推薦系統實踐 0x05 推薦數據集MovieLens及評測

推薦數據集MovieLens及評測

數據集簡介

MoiveLens是GroupLens Research收集併發布的關於電影評分的數據集,規模也比較大,爲了讓我們的實驗快速有效的進行,我們選取了發佈於2003年2月的 MovieLens 1M,這個數據集包含6000個用戶對4000個電影的一百萬個評分。這個數據集經常用來做推薦系統,機器學習算法的測試數據集。尤其在推薦系統領域,很多著名論文都是基於這個數據集的。數據集下載地址

數據集格式

評分數據

在rating.dat文件當中,裏面主要保存了每個用戶與對每一部電影的評分,數據的格式爲:用戶標識::MovieID::評級::時間戳。

  • 用戶id範圍在1到6040之間
  • 電影id在1到3952之間
  • 評分以五星爲標準(只有全星)
  • 時間戳以秒爲單位表示,從epoch返回到time(2)
  • 每個用戶至少有20個評分

我們簡單看一下是不是這樣

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::電影名稱::電影分類

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,看一下里面的內容, 數據格式爲用戶標識::性別::年齡::職業::郵編

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次實驗的評測指標的平均值作爲算法測試結果。主要是爲了防止算法發生過擬合。

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

評測設置

我們採用了召回率,精準率、覆蓋率以及新穎度作爲主要的評測指標。之前評測指標的文章已經詳細介紹了這四種指標的含義以及推導,這裏就給出詳細的實現的代碼。

召回率

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)

精準率

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)

覆蓋率

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)

新穎度

計算平均流行度時對每個物品的流行度取對數,這是因爲物品的流行度分佈滿足長尾分佈,在取對數後,流行度的平均值更加穩定。

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數據集簡介

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章