Skip to content

ankane/disco-go

Repository files navigation

Disco Go

🔥 Recommendations for Go using collaborative filtering

  • Supports user-based and item-based recommendations
  • Works with explicit and implicit feedback
  • Uses high-performance matrix factorization

Build Status

Installation

Run:

go get github.com/ankane/disco-go

Getting Started

Import the package

import "github.com/ankane/disco-go"

Prep your data in the format userId, itemId, value

data := disco.NewDataset[string, string]()
data.Push("user_a", "item_a", 5.0)
data.Push("user_a", "item_b", 3.5)
data.Push("user_b", "item_a", 4.0)

IDs can be integers or strings

data.Push(1, "item_a", 5.0)

If users rate items directly, this is known as explicit feedback. Fit the recommender with:

recommender, err := disco.FitExplicit(data)

If users don’t rate items directly (for instance, they’re purchasing items or reading posts), this is known as implicit feedback. Use 1.0 or a value like number of purchases or page views for the dataset, and fit the recommender with:

recommender, err := disco.FitImplicit(data)

Get user-based recommendations - “users like you also liked”

recommender.UserRecs(userId, 5)

Get item-based recommendations - “users who liked this item also liked”

recommender.ItemRecs(itemId, 5)

Get predicted ratings for a specific user and item

recommender.Predict(userId, itemId)

Get similar users

recommender.SimilarUsers(userId, 5)

Examples

MovieLens

Load the data

data, err := disco.LoadMovieLens()

Create a recommender

recommender, err := disco.FitExplicit(data, disco.Factors(20))

Get similar movies

recommender.ItemRecs("Star Wars (1977)")

Storing Recommendations

Save recommendations to your database.

Alternatively, you can store only the factors and use a library like pgvector-go. See an example.

Algorithms

Disco uses high-performance matrix factorization.

Specify the number of factors and iterations

recommender, err := disco.FitExplicit(data, disco.Factors(8), disco.Iterations(20))

Progress

Pass a callback to show progress

callback := func(info disco.FitInfo) { fmt.Printf("%+v\n", info) }
recommender, err := disco.FitExplicit(data, disco.Callback(callback))

Note: TrainLoss and ValidLoss are not available for implicit feedback

Validation

Pass a validation set with explicit feedback

recommender, err := disco.FitEvalExplicit(trainSet, validSet)

The loss function is RMSE

Cold Start

Collaborative filtering suffers from the cold start problem. It’s unable to make good recommendations without data on a user or item, which is problematic for new users and items.

recommender.UserRecs(newUserId, 5) // returns empty array

There are a number of ways to deal with this, but here are some common ones:

  • For user-based recommendations, show new users the most popular items
  • For item-based recommendations, make content-based recommendations

Reference

Get ids

recommender.UserIds()
recommender.ItemIds()

Get the global mean

recommender.GlobalMean()

Get factors

recommender.UserFactors(userId)
recommender.ItemFactors(itemId)

References

History

View the changelog

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help:

To get started with development:

git clone https://github.com/ankane/disco-go.git
cd disco-go
go mod tidy
go test -v

About

Recommendations for Go using collaborative filtering

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages