多源
从热门、最新、基于用户、基于项目和协作过滤中推荐物品。
自动机器学习
在后台自动搜索最佳的推荐模型。
分布式预测
在单节点训练后的推荐阶段支持水平伸缩。
RESTful APIs
为数据CRUD和推荐请求暴露RESTful API。
多数据源支持
支持使用Redis、MySQL、Postgres、MongoDB和ClickHouse作为后端存储。
在线评估
根据最近插入的反馈分析在线推荐的效果。
仪表盘
提供数据管理、系统监控、集群状态检查的GUI界面。
开源
代码库是在Apache 2许可下发布的、由社区驱动的。
Gorse是一个用Go语言编写的开源推荐系统。Gorse的目标是成为一个通用的开源推荐系统,可以很容易地被引入到各种各样的在线服务中。通过将物品、用户和交互数据导入到Gorse中,系统将自动训练模型,为每个用户生成推荐。
快速开始
Playground模式是为初学者准备的。只需通过以下命令为GitHub仓库设置一个推荐系统。
curl -fsSL https://gorse.io/playground | bash
docker run -p 8088:8088 zhenghaoz/gorse-in-one --playground
Playground模式将从GitRec下载数据并导入到Gorse中。仪表板可以通过http://localhost:8088访问。
在“任务”页面上完成“查找临近的物品”任务后,尝试向Gorse插入一些反馈。假设Bob是GitHub中几个前端仓库的前端开发人员。我们把他的star行为的反馈写入Gorse。
read -d '' JSON << EOF
[
{ \"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\" }
]
EOF
curl -X POST http://127.0.0.1:8088/api/feedback \
-H 'Content-Type: application/json' \
-d "$JSON"
import "github.com/zhenghaoz/gorse/client"
gorse := client.NewGorseClient("http://127.0.0.1:8088", "")
gorse.InsertFeedback([]client.Feedback{
{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"},
})
from gorse import Gorse
client = Gorse('http://127.0.0.1:8088', '')
client.insert_feedbacks([
{ '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' }
])
import { Gorse } from "gorsejs";
const client = new Gorse({ endpoint: "http://127.0.0.1:8088", secret: "" });
await client.insertFeedbacks([
{ 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' }
]);
import io.gorse.gorse4j.*;
Gorse client = new Gorse(GORSE_ENDPOINT, GORSE_API_KEY);
List<Feedback> feedbacks = List.of(
new Feedback("star", "bob", "vuejs:vue", "2022-02-24"),
new Feedback("star", "bob", "d3:d3", "2022-02-25"),
new Feedback("star", "bob", "dogfalo:materialize", "2022-02-26"),
new Feedback("star", "bob", "mozilla:pdf.js", "2022-02-27"),
new Feedback("star", "bob", "moment:moment", "2022-02-28")
);
client.insertFeedback(feedbacks);
use gorse_rs::{Feedback, Gorse};
let client = Gorse::new("http://127.0.0.1:8088", "");
let feedback = vec![
Feedback::new("star", "bob", "vuejs:vue", "2022-02-24"),
Feedback::new("star", "bob", "d3:d3", "2022-02-25"),
Feedback::new("star", "bob", "dogfalo:materialize", "2022-02-26"),
Feedback::new("star", "bob", "mozilla:pdf.js", "2022-02-27"),
Feedback::new("star", "bob", "moment:moment", "2022-02-28")
];
client.insert_feedback(&feedback).await;
require 'gorse'
client = Gorse.new('http://127.0.0.1:8088', 'api_key')
client.insert_feedback([
Feedback.new("star", "bob", "vuejs:vue", "2022-02-24"),
Feedback.new("star", "bob", "d3:d3", "2022-02-25"),
Feedback.new("star", "bob", "dogfalo:materialize", "2022-02-26"),
Feedback.new("star", "bob", "mozilla:pdf.js", "2022-02-27"),
Feedback.new("star", "bob", "moment:moment", "2022-02-28")
])
$client = new Gorse("http://127.0.0.1:8088/", "api_key");
$rowsAffected = $client->insertFeedback([
new Feedback("star", "bob", "vuejs:vue", "2022-02-24"),
new Feedback("star", "bob", "d3:d3", "2022-02-25"),
new Feedback("star", "bob", "dogfalo:materialize", "2022-02-26"),
new Feedback("star", "bob", "mozilla:pdf.js", "2022-02-27"),
new Feedback("star", "bob", "moment:moment", "2022-02-28")
]);
using Gorse.NET;
var client = new Gorse("http://127.0.0.1:8087", "api_key");
client.InsertFeedback(new Feedback[]
{
new Feedback{FeedbackType="star", UserId="bob", ItemId="vuejs:vue", Timestamp="2022-02-24"},
new Feedback{FeedbackType="star", UserId="bob", ItemId="d3:d3", Timestamp="2022-02-25"},
new Feedback{FeedbackType="star", UserId="bob", ItemId="dogfalo:materialize", Timestamp="2022-02-26"},
new Feedback{FeedbackType="star", UserId="bob", ItemId="mozilla:pdf.js", Timestamp="2022-02-27"},
new Feedback{FeedbackType="star", UserId="bob", ItemId="moment:moment", Timestamp="2022-02-28"},
});
然后从Gorse中获取10个推荐的物品。我们可以发现,前端相关的仓库被推荐给了Bob。
curl http://127.0.0.1:8088/api/recommend/bob?n=10
gorse.GetRecommend("bob", "", 10)
client.get_recommend('bob', n=10)
await client.getRecommend({ userId: 'bob', cursorOptions: { n: 10 } });
client.getRecommend("bob");
client.get_recommend("bob").await;
client.get_recommend('10')
$client->getRecommend('10');
client.GetRecommend("10");
[
"mbostock:d3",
"nt1m:material-framework",
"mdbootstrap:vue-bootstrap-with-material-design",
"justice47:f2-vue",
"10clouds:cyclejs-cookie",
"academicpages:academicpages.github.io",
"accenture:alexia",
"addyosmani:tmi",
"1wheel:d3-starterkit",
"acdlite:redux-promise"
]
最终的输出可能与示例不同,因为playground数据集会随时间而变化。