1. 程式人生 > >推薦系統實踐 0x05 推薦資料集MovieLens及評測

推薦系統實踐 0x05 推薦資料集MovieLens及評測

# 推薦資料集MovieLens及評測 ## 資料集簡介 MoiveLens是GroupLens Research收集併發布的關於電影評分的資料集,規模也比較大,為了讓我們的實驗快速有效的進行,我們選取了釋出於2003年2月的 MovieLens 1M,這個資料集包含6000個使用者對4000個電影的一百萬個評分。這個資料集經常用來做推薦系統,機器學習演算法的測試資料集。尤其在推薦系統領域,很多著名論文都是基於這個資料集的。資料集[下載地址](https://grouplens.org/datasets/movielens/1m/)。 ## 資料集格式 ### 評分資料 在rating.dat檔案當中,裡面主要儲存了每個使用者與對每一部電影的評分,資料的格式為:使用者標識::MovieID::評級::時間戳。 -使用者id範圍在1到6040之間 -電影id在1到3952之間 -評分以五星為標準(只有全星) -時間戳以秒為單位表示,從epoch返回到time(2) -每個使用者至少有20個評分 我們簡單看一下是不是這樣 ```python import pandas as pd ratings = pd.read_csv('./MovieLens/ml-1m/ratings.dat', delimiter="::",header=None) ratings.head(5) ``` 輸出結果 ``` 0 1 2 3 0 1 1193 5 978300760 1 1 661 3 978302109 2 1 914 3 978301968 3 1 3408 4 978300275 4 1 2355 5 978824291 ``` ### 電影資料 我們再看一下電影資料movies.dat,看一下里面的內容, 資料格式為MovieID::電影名稱::電影分類 ```python movies = pd.read_csv('./MovieLens/ml-1m/movies.dat', delimiter="::", header=None) movies.head(5) ``` 輸出結果: ``` 0 1 2 0 1 Toy Story (1995) Animation|Children's|Comedy 1 2 Jumanji (1995) Adventure|Children's|Fantasy 2 3 Grumpier Old Men (1995) Comedy|Romance 3 4 Waiting to Exhale (1995) Comedy|Drama 4 5 Father of the Bride Part II (1995) Comedy ``` ### 使用者資料 我們再看一下使用者資料users.dat,看一下里面的內容, 資料格式為使用者標識::性別::年齡::職業::郵編 ```python users = pd.read_csv('./MovieLens/ml-1m/users.dat', delimiter="::", header=None) users.head(5) ``` 輸出結果: ``` 0 1 2 3 4 0 1 F 1 10 48067 1 2 M 56 16 70072 2 3 M 25 15 55117 3 4 M 45 7 02460 4 5 M 25 20 55455 ``` ## 實驗設定 以上就是這個資料集所有包含的內容以及相應的含義了,相信通過上面的資料呈現也會對這個資料集大概有個印象。由於後面的演算法主要介紹的是隱反饋資料集MoiveLens的TopN的推薦問題,因此忽略了評分記錄。 ### 訓練設定 我們採用了N折交叉驗證的方式進行訓練,也就是將資料劃分成M份,選取其中M-1份作為訓練集,選取其中的1份作為測試集。將M次實驗的評測指標的平均值作為演算法測試結果。主要是為了防止演算法發生過擬合。 ```python import random def SplitData(data, M, k, seed): test = [] train = [] random.seed(seed) for user, item in data: if random.randint(0,M) == k: test.append([user,item]) else: train.append([user,item]) return train, test ``` ### 評測設定 我們採用了召回率,精準率、覆蓋率以及新穎度作為主要的評測指標。之前評測指標的文章已經詳細介紹了這四種指標的含義以及推導,這裡就給出詳細的實現的程式碼。 #### 召回率 ```python def Recall(train, test, N): hit = 0 all = 0 for user in train.keys(): tu = test[user] rank = GetRecommendation(user, N) for item, pui in rank: if item in tu: hit += 1 all += len(tu) return hit / (all * 1.0) ``` #### 精準率 ```python def Precision(train, test, N): hit = 0 all = 0 for user in train.keys(): tu = test[user] rank = GetRecommendation(user, N) for item, pui in rank: if item in tu: hit += 1 all += N return hit / (all * 1.0) ``` #### 覆蓋率 ```python def Coverage(train, test, N): recommend_items = set() all_items = set() for user in train.keys(): for item in train[user].keys(): all_items.add(item) rank = GetRecommendation(user, N) for item, pui in rank: recommend_items.add(item) return len(recommend_items) / (len(all_items) * 1.0) ``` #### 新穎度 計算平均流行度時對每個物品的流行度取對數,這是因為物品的流行度分佈滿足長尾分佈,在取對數後,流行度的平均值更加穩定。 ```python def Popularity(train, test, N): item_popularity = dict() for user, items in train.items(): for item in items.keys(): if item not in item_popularity: item_popularity[item] = 0 item_popularity[item] += 1 ret = 0 n = 0 for user in train.keys(): rank = GetRecommendation(user, N) for item, pui in rank: ret += math.log(1 + item_popularity[item]) n += 1 ret /= n * 1.0 return ret ``` 下一篇,我們將介紹基於鄰域的演算法。 ## 參考 [推薦系統實戰(一)--movieslens資料集簡介](https://www.jianshu.com/p/58b108