golang基于协同过滤的离线推荐系统后端插件gorse的使用

Golang基于协同过滤的离线推荐系统后端插件Gorse的使用

Gorse推荐系统引擎介绍

Gorse是一个用Go语言编写的开源推荐系统,旨在成为一个通用的开源推荐系统,可以快速引入各种在线服务。通过将物品、用户和交互数据导入Gorse,系统会自动训练模型为每个用户生成推荐。

Gorse Logo

主要特性

  • 多源推荐:从热门、最新、基于用户、基于物品和协同过滤中推荐物品
  • AutoML:在后台自动搜索最佳推荐模型
  • 分布式预测:支持在单节点训练后的推荐阶段水平扩展
  • RESTful API:暴露RESTful API用于数据CRUD和推荐请求
  • 在线评估:从最近插入的反馈中分析在线推荐性能
  • 仪表盘:提供GUI用于数据管理、系统监控和集群状态检查

快速开始

以下是使用Gorse构建基于协同过滤的离线推荐系统的完整示例:

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

func main() {
	// 1. 启动Gorse服务(这里使用Docker方式)
	// docker run -p 8088:8088 zhenghaoz/gorse-in-one --playground

	// 2. 插入用户反馈数据
	feedbackData := `[
		{ "FeedbackType": "star", "UserId": "bob", "ItemId": "vuejs:vue", "Timestamp": "2022-02-24" },
		{ "FeedbackType": "star", "UserId": "bob", "ItemId": "d3:d3", "Timestamp": "2022-02-25" },
		{ "FeedbackType": "star", "UserId": "bob", "ItemId": "dogfalo:materialize", "Timestamp": "2022-02-26" },
		{ "FeedbackType": "star", "UserId": "bob", "ItemId": "mozilla:pdf.js", "Timestamp": "2022-02-27" },
		{ "FeedbackType": "star", "UserId": "bob", "ItemId": "moment:moment", "Timestamp": "2022-02-28" }
	]`

	resp, err := http.Post("http://127.0.0.1:8088/api/feedback", 
		"application/json", 
		strings.NewReader(feedbackData))
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	fmt.Println("Feedback inserted:", resp.Status)

	// 3. 获取推荐结果
	resp, err = http.Get("http://127.0.0.1:8088/api/recommend/bob?n=10")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	var recommendations []string
	err = json.Unmarshal(body, &recommendations)
	if err != nil {
		panic(err)
	}

	fmt.Println("Recommendations for Bob:")
	for i, item := range recommendations {
		fmt.Printf("%d. %s\n", i+1, item)
	}
}

系统架构

Gorse是一个单节点训练和分布式预测的推荐系统。Gorse将数据存储在MySQL、MongoDB、Postgres或ClickHouse中,中间结果缓存在Redis、MySQL、MongoDB和Postgres中。

Gorse架构图

  1. 集群由一个主节点、多个工作节点和服务器节点组成
  2. 主节点负责模型训练、非个性化物品推荐、配置管理和成员管理
  3. 服务器节点负责暴露RESTful API和在线实时推荐
  4. 工作节点负责为每个用户进行离线推荐

此外,管理员可以通过主节点上的仪表盘进行系统监控、数据导入导出和系统状态检查。

使用示例

1. 通过API插入用户反馈

feedback := []map[string]interface{}{
	{
		"FeedbackType": "click",
		"UserId":       "user1",
		"ItemId":       "item100",
		"Timestamp":    "2023-01-01",
	},
	{
		"FeedbackType": "star",
		"UserId":       "user1",
		"ItemId":       "item101",
		"Timestamp":    "2023-01-02",
	},
}

jsonData, _ := json.Marshal(feedback)
resp, err := http.Post("http://localhost:8088/api/feedback", 
	"application/json", 
	bytes.NewBuffer(jsonData))

2. 获取个性化推荐

func getRecommendations(userId string, n int) ([]string, error) {
	resp, err := http.Get(fmt.Sprintf("http://localhost:8088/api/recommend/%s?n=%d", userId, n))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var items []string
	err = json.NewDecoder(resp.Body).Decode(&items)
	return items, err
}

3. 获取物品相似度

func getSimilarItems(itemId string, n int) ([]string, error) {
	resp, err := http.Get(fmt.Sprintf("http://localhost:8088/api/item/%s/neighbors?n=%d", itemId, n))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var items []string
	err = json.NewDecoder(resp.Body).Decode(&items)
	return items, err
}

总结

Gorse是一个功能强大的开源推荐系统,特别适合Golang开发者构建基于协同过滤的离线推荐系统。通过简单的RESTful API,开发者可以快速集成推荐功能到现有系统中。Gorse的自动模型训练和分布式预测能力使其非常适合生产环境使用。


更多关于golang基于协同过滤的离线推荐系统后端插件gorse的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang基于协同过滤的离线推荐系统后端插件gorse的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用Gorse构建基于协同过滤的离线推荐系统后端

Gorse是一个用Go编写的开源推荐系统引擎,它实现了多种推荐算法,包括协同过滤、基于内容的推荐和热门推荐等。下面我将介绍如何在Go项目中使用Gorse构建离线推荐系统。

Gorse核心概念

Gorse主要包含以下几个核心组件:

  • 协同过滤:基于用户-物品交互矩阵计算相似度
  • 矩阵分解:使用ALS算法进行隐因子模型训练
  • 多臂老虎机:用于探索-利用平衡
  • 离线训练:定期训练模型
  • 在线推荐:实时生成推荐结果

安装Gorse

首先安装Gorse库:

go get github.com/zhenghaoz/gorse@master

基本使用示例

1. 创建推荐引擎

package main

import (
	"fmt"
	"github.com/zhenghaoz/gorse/base"
	"github.com/zhenghaoz/gorse/core"
	"github.com/zhenghaoz/gorse/model"
)

func main() {
	// 1. 创建数据集
	data := core.NewDataSet([]core.Feedback{
		{UserId: "1", ItemId: "101", Feedback: 5.0},
		{UserId: "1", ItemId: "102", Feedback: 3.0},
		{UserId: "2", ItemId: "101", Feedback: 4.0},
		{UserId: "2", ItemId: "103", Feedback: 2.0},
		{UserId: "3", ItemId: "102", Feedback: 1.0},
		{UserId: "3", ItemId: "103", Feedback: 5.0},
	})

	// 2. 划分训练集和测试集
	trainSet, testSet := core.Split(data, 0.8)

	// 3. 创建推荐模型 (使用协同过滤)
	cf := model.NewKNNImplicit(model.Params{
		model.K:       10,    // 邻居数量
		model.Similarity: "pearson", // 相似度计算方法
	})

	// 4. 训练模型
	cf.Fit(trainSet, testSet, nil)

	// 5. 为用户生成推荐
	userId := "1"
	n := 5 // 推荐数量
	items := cf.Recommend(userId, n, nil)
	fmt.Printf("为用户 %s 推荐: %v\n", userId, items)
}

2. 使用矩阵分解

// 创建矩阵分解模型
mf := model.NewMF(model.Params{
	model.NEpochs:   100,   // 迭代次数
	model.NFactors:  50,    // 隐因子数量
	model.Lr:        0.01,  // 学习率
	model.Reg:       0.1,   // 正则化系数
})

// 训练模型
mf.Fit(trainSet, testSet, nil)

// 为用户生成推荐
items := mf.Recommend(userId, n, nil)

离线推荐系统实现

下面是一个更完整的离线推荐系统实现示例:

package main

import (
	"encoding/csv"
	"fmt"
	"log"
	"os"
	"strconv"
	"time"

	"github.com/zhenghaoz/gorse/base"
	"github.com/zhenghaoz/gorse/core"
	"github.com/zhenghaoz/gorse/model"
)

// 从CSV加载数据
func loadData(path string) ([]core.Feedback, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	reader := csv.NewReader(file)
	records, err := reader.ReadAll()
	if err != nil {
		return nil, err
	}

	var feedbacks []core.Feedback
	for _, record := range records {
		if len(record) < 3 {
			continue
		}
		rating, err := strconv.ParseFloat(record[2], 64)
		if err != nil {
			continue
		}
		feedbacks = append(feedbacks, core.Feedback{
			UserId:   record[0],
			ItemId:   record[1],
			Feedback: rating,
		})
	}

	return feedbacks, nil
}

// 保存推荐结果到文件
func saveRecommendations(userId string, items []string, path string) error {
	file, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return err
	}
	defer file.Close()

	writer := csv.NewWriter(file)
	for _, item := range items {
		if err := writer.Write([]string{userId, item}); err != nil {
			return err
		}
	}
	writer.Flush()

	return nil
}

func main() {
	// 1. 加载数据
	feedbacks, err := loadData("ratings.csv")
	if err != nil {
		log.Fatal(err)
	}

	// 2. 创建数据集
	data := core.NewDataSet(feedbacks)

	// 3. 划分训练集和测试集
	trainSet, testSet := core.Split(data, 0.8)

	// 4. 创建并训练模型
	start := time.Now()
	cf := model.NewKNNImplicit(model.Params{
		model.K:         20,
		model.Similarity: "cosine",
	})
	cf.Fit(trainSet, testSet, nil)
	log.Printf("模型训练完成, 耗时: %v", time.Since(start))

	// 5. 评估模型
	rmse := core.RMSE(testSet, cf)
	log.Printf("模型RMSE: %.4f", rmse)

	// 6. 为所有用户生成推荐
	userIds := trainSet.Users()
	for _, userId := range userIds {
		items := cf.Recommend(userId, 10, nil)
		if err := saveRecommendations(userId, items, "recommendations.csv"); err != nil {
			log.Printf("为用户 %s 保存推荐结果失败: %v", userId, err)
		}
	}

	log.Println("离线推荐完成")
}

高级功能

1. 混合推荐

// 创建混合推荐模型
ensemble := model.NewHybrid([]core.Model{
	model.NewKNNImplicit(model.Params{model.K: 20}),
	model.NewMF(model.Params{model.NFactors: 50}),
}, []float64{0.5, 0.5})

// 训练模型
ensemble.Fit(trainSet, testSet, nil)

2. 定期离线训练

func scheduleOfflineTraining() {
	ticker := time.NewTicker(24 * time.Hour) // 每天训练一次
	defer ticker.Stop()

	for range ticker.C {
		// 加载最新数据
		feedbacks, err := loadData("ratings.csv")
		if err != nil {
			log.Printf("加载数据失败: %v", err)
			continue
		}

		// 训练模型
		data := core.NewDataSet(feedbacks)
		trainSet, _ := core.Split(data, 1.0) // 使用全部数据训练
		cf := model.NewKNNImplicit(model.Params{model.K: 20})
		cf.Fit(trainSet, nil, nil)

		// 保存模型
		if err := core.SaveModel(cf, "model.gob"); err != nil {
			log.Printf("保存模型失败: %v", err)
		}
	}
}

性能优化建议

  1. 数据预处理:对用户ID和物品ID进行哈希处理,减少内存占用
  2. 并行计算:Gorse支持并行训练,可以设置base.SetParallelism(4)来使用多核
  3. 增量更新:对于新数据,可以使用增量更新而非全量训练
  4. 缓存推荐结果:离线推荐结果可以缓存到Redis等高速存储中

总结

Gorse为Go开发者提供了一个简单高效的推荐系统实现方案。通过上述示例,你可以快速构建一个基于协同过滤的离线推荐系统。根据实际业务需求,你可以调整模型参数、尝试不同的算法组合,或者集成更多数据源来提升推荐效果。

要了解更多高级用法,可以参考Gorse的官方文档和示例代码。

回到顶部