Skip to content

Commit

Permalink
fix: use hash map when excluding read items
Browse files Browse the repository at this point in the history
  • Loading branch information
zhenghaoz committed Feb 25, 2020
1 parent 50ad870 commit 8161c99
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 34 deletions.
2 changes: 1 addition & 1 deletion base/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ func TestRuntimeOptions(t *testing.T) {
var opt1 *RuntimeOptions
assert.Equal(t, true, opt1.GetVerbose())
assert.Equal(t, 1, opt1.GetFitJobs())
assert.Equal(t, 1, opt1.GetCVJobs())
assert.Equal(t, 1, opt1.GetCVJobs())
// Check options
opt2 := &RuntimeOptions{false, 10, 5}
assert.Equal(t, false, opt2.GetVerbose())
Expand Down
17 changes: 10 additions & 7 deletions cmd/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,16 +277,19 @@ func getRecommends(request *restful.Request, response *restful.Response) {
}
if engineConfig.Recommend.Once {
// Get read recommended items
reads, err := db.GetIdentList(engine.BucketReads, userId, 0)
readItems, err := db.GetIdentList(engine.BucketReads, userId, 0)
readSet := make(map[string]bool)
for _, item := range readItems {
readSet[item.ItemId] = true
}
var subItems []engine.RecommendedItem
change := false
notRecommended := false
if err != nil {
change = false
} else {
for i := range items {
exist := engine.ExistRecommendedItem(items[i].ItemId, reads)
if !exist {
if _, exist := readSet[items[i].ItemId]; !exist {
subItems = append(subItems, items[i])
change = true
}
Expand All @@ -301,9 +304,9 @@ func getRecommends(request *restful.Request, response *restful.Response) {
} else if change {
subItems = engine.Ranking(subItems, number, p, t, c)
for i := range subItems {
reads = append(reads, subItems[i])
readItems = append(readItems, subItems[i])
}
if err := db.PutIdentList(engine.BucketReads, userId, reads); err != nil {
if err := db.PutIdentList(engine.BucketReads, userId, readItems); err != nil {
badRequest(response, err)
}
// Send result
Expand All @@ -312,9 +315,9 @@ func getRecommends(request *restful.Request, response *restful.Response) {
// Send result
items = engine.Ranking(items, number, p, t, c)
for i := range items {
reads = append(reads, items[i])
readItems = append(readItems, items[i])
}
if err := db.PutIdentList(engine.BucketReads, userId, reads); err != nil {
if err := db.PutIdentList(engine.BucketReads, userId, readItems); err != nil {
badRequest(response, err)
}
json(response, items)
Expand Down
2 changes: 1 addition & 1 deletion core/ranking.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,4 @@ func Popularity(dataSet DataSetInterface) (itemId []string, popularity []float64
itemId[itemIndex] = dataSet.ItemIndexer().ToID(itemIndex)
}
return
}
}
2 changes: 1 addition & 1 deletion core/ranking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ func TestNeighbors(t *testing.T) {
// Find N nearest neighbors
neighbors, _ := Neighbors(dataSet, "1", 5, base.MSDSimilarity)
assert.Equal(t, []string{"2", "3", "4", "5", "6"}, neighbors)
}
}
3 changes: 2 additions & 1 deletion engine/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func TestLoadConfig(t *testing.T) {
assert.Equal(t, 10, config.Recommend.UpdateThreshold)
assert.Equal(t, 1, config.Recommend.CheckPeriod)
assert.Equal(t, 10, config.Recommend.FitJobs)
assert.Equal(t, true, config.Recommend.Once)
// params configuration
assert.Equal(t, 0.05, config.Params.Lr)
assert.Equal(t, 0.01, config.Params.Reg)
Expand All @@ -43,7 +44,6 @@ func TestLoadConfig(t *testing.T) {
assert.Equal(t, "pearson", config.Params.Similarity)
assert.Equal(t, 100, config.Params.K)
assert.Equal(t, 5, config.Params.MinK)
//assert.Equal(t, "bpr", config.Params.Optimizer)
assert.Equal(t, 1.0, config.Params.Alpha)
}

Expand Down Expand Up @@ -93,6 +93,7 @@ func TestTomlConfig_FillDefault(t *testing.T) {
assert.Equal(t, 10, config.Recommend.UpdateThreshold)
assert.Equal(t, 1, config.Recommend.CheckPeriod)
assert.Equal(t, 1, config.Recommend.FitJobs)
assert.Equal(t, false, config.Recommend.Once)
}

func TestLoadSimilarity(t *testing.T) {
Expand Down
36 changes: 15 additions & 21 deletions engine/offline.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,6 @@ func UpdateNeighbors(name string, cacheSize int, dataSet core.DataSetInterface,
}
return nil
}
func ExistRecommendedItem(item string, reads []RecommendedItem) bool {
for i := range reads {
if reads[i].Item.ItemId == item {
return true
}
}
return false
}

// UpdateRecommends updates personalized recommendations for the database.
func UpdateRecommends(name string, params base.Params, cacheSize int, fitJobs int, once bool, dataSet core.DataSetInterface, db *DB) error {
Expand All @@ -106,25 +98,27 @@ func UpdateRecommends(name string, params base.Params, cacheSize int, fitJobs in
for userIndex := 0; userIndex < dataSet.UserCount(); userIndex++ {
userId := dataSet.UserIndexer().ToID(userIndex)
exclude := dataSet.UserByIndex(userIndex)
// get read items
subItems := make(map[string]bool)
// exclude read items
candidateItems := items
if once {
reads, err := db.GetIdentList(BucketReads, userId, 0)
if err != nil {
// reads is empty
subItems = items
candidateItems = make(map[string]bool)
var err error
var readItems []RecommendedItem
if readItems, err = db.GetIdentList(BucketReads, userId, 0); err != nil {
candidateItems = items
} else {
for itemID := range items {
exist := ExistRecommendedItem(itemID, reads)
if !exist {
subItems[itemID] = true
readSet := make(map[string]bool)
for _, item := range readItems {
readSet[item.ItemId] = true
}
for itemId := range items {
if _, exist := readSet[itemId]; !exist {
candidateItems[itemId] = true
}
}
}
} else {
subItems = items
}
recommendItems, ratings := core.Top(subItems, userId, cacheSize, exclude, model)
recommendItems, ratings := core.Top(candidateItems, userId, cacheSize, exclude, model)
recommends := make([]RecommendedItem, len(recommendItems))
items, err := db.GetItemsByID(recommendItems)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions engine/offline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func TestUpdateRecommends(t *testing.T) {
base.InitMean: 0,
base.InitStdDev: 0.001,
}
if err = UpdateRecommends("bpr", params, 10, runtime.NumCPU(),false, trainSet, db); err != nil {
if err = UpdateRecommends("bpr", params, 10, runtime.NumCPU(), false, trainSet, db); err != nil {
t.Fatal(err)
}
// Check result
Expand Down Expand Up @@ -230,7 +230,7 @@ func TestUpdateRecommendsInvalidModel(t *testing.T) {
if err = db.InsertItems(itemId, nil); err != nil {
t.Fatal(err)
}
if err = UpdateRecommends("invalid-model", nil, 10, runtime.NumCPU(), false,dataSet, db); err == nil {
if err = UpdateRecommends("invalid-model", nil, 10, runtime.NumCPU(), false, dataSet, db); err == nil {
t.Fatal("function should return an error")
}
// Close database
Expand Down
1 change: 1 addition & 0 deletions example/file_config/config_test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ cache_size = 100 # the number of cached recommendations
update_threshold = 10 # update model when more than 10 ratings are added
check_period = 1 # check for update every one minute
fit_jobs = 10 # concurrent jobs for fitting
once = true # recommend once

# This section declares hyperparameters for the recommendation model.
[params]
Expand Down

0 comments on commit 8161c99

Please sign in to comment.