使用Mahout搭建推薦系統之入門篇2-玩轉你的數據1


用意: 搞推薦系統或者數據挖掘的, 對數據要絕對的敏感和熟悉, 而且熱愛你的數據. 分析數據既要用統計分析那一套,又要熟悉業務發掘有趣的特徵(feature). 後者有意思的多,可是由於我業務作的很少,還不太熟悉, 跪求大牛們分析業務經歷. 聽豆瓣上的大神"懶惰啊我"說過,有一個Nokia的比賽,有一個團隊直接用陀螺儀參數就發現了性別分佈,由於男生手機都放在口袋裏, 而女生每每放在包裏面. 不知道記錯沒有. html

下面主要講些統計分析或者簡單的內容分析, 說說我本身的總結, 這個話題之後能夠常說. python

這部分不涉及Mahout的內容,主要是使用Python和Linux命令簡單處理數據. 不感興趣的朋友能夠直接跳到最後面看看一些不錯的數據集推薦.  算法

一. 前期數據分析的三個階段

1. 打開你的數據,讀懂每一行的含義 數據庫

2. 統計你的數據, 用python\excel pivot table\R\SPSS等均可以, 考慮到複用性建議寫代碼

    數據的行數 數據結構

    item和user的數量 機器學習

    rate的評分方式,是boolean仍是1-5分或者其它. 性能

    數據稀疏仍是稠密 sparse or dense 學習

3. 找到合適的存儲方式存儲,DenseVector仍是SparseVector spa

二. 數據分析實例

   如今國內的數據還比較少, 感謝下百度,提供了一些不錯的數據. excel

    首先來看一份國內的數據

    百度舉辦的電影推薦系統算法創新大賽提供的用戶數據. http://pan.baidu.com/s/1y15w4

1. 讀懂你的數據, 知道每一行的含義.

一共有五個文件:

movie_tag.txt 每行表示一個有效數據項, 下面相似. 每行由電影id以及tag的id, 用"\t"隔開; tag用","隔開.

training_set.txt  每行表示用戶id, 電影id, 評分, 用"\t"隔開.

user_social.txt  每行表示用戶id和用戶關注的好友id集合; 好友id集合用","隔開.

predict.txt 每行表示用戶id和電影id

user_history.txt 每行表示用戶id和用戶看過的電影id. 

數據以下圖所示: head -n 2 *.txt


2. 數據統計
主要參數:
    用戶個數\電影個數
    每一個用戶平均電影個數,平均值,標準差\每一個電影平均用戶個數,平均值,標準差
    評分的範圍

行數分析: wc -l *.txt


traning_set.txt數量爲1262741行,predict.txt數量爲314679行, 電影和用戶數量未知,大概在萬的級別,因此寫些
python代碼簡單分析一下. 100萬用戶級別的數據項使用python dict數據結構消耗內存在MByte級別且因爲Python使用共享池共享int類,對象的冗餘開銷也不會暴漲, 普通PC既能夠計算.

Python數據分析

Python代碼輸出以下:

     用戶(總數,平均值,標準差)=( 9722 129.884900226 223.778624272 )
     電影(總數,平均值,標準差)=( 7889 160.063506148 360.171047305 )
     評分範圍=( 1.0 5.0 )

簡要分析:

    由數據可見,用戶數量和電影數量在10000左右級別, 因爲電影更少一些,使用item-based較合適;固然,因爲用戶和電影數量差距不大,最終仍是要用實驗來證實一下二者的性能優異.

    另外:二者標準差分別爲223與336可見, 基本能夠斷定數據爲稀疏矩陣.

[比較: 我使用了movieLens上的1M數據集進行對比, 運行結果以下]

http://www.grouplens.org/datasets/movielens/

用戶(總數,平均值,標準差)=( 6040 165.597516556 192.731072529 )
電影(總數,平均值,標準差)=( 3706 269.889098759 383.996019743 )
評分範圍=( 1.0 5.0 )

    評價: 平均值更大, 數據更加緻密一些. 每一個用戶和電影的數據推薦效果應該也會更好一些.

[吐槽點: 你給了id不給電影和標籤的真實名稱,看着一堆id, 推薦一大堆數字有個毛興趣啊.  可是movieLens給出了電影名稱,之後仍是使用movieLens來做爲預測數據更加有興趣一些.]

Python代碼以下:

# -*- coding: utf-8 -*- ''' Created on 2 Nov, 2013 @author: cool ''' import math #return user_num, movie_num, movie_mean, movie_variant def countData(filename): user_count = {} #the number of movie about every user movie_count = {} #the number of user about every movie max = -100 min = 100 #Assuming no duplicate data for line in open(filename): (user, movie, rating) = line.split("\t") #(user, movie, rating, xx) = line.split("::") rating = float(rating.replace(r"\r\r\n", "")) #print rating user_count.setdefault(user, 0) user_count[user] += 1 movie_count.setdefault(movie, 0) movie_count[movie] += 1 if (max < rating): max = rating if (min > rating): min = rating uSum = sum([user_count[user] for user in user_count]) uSqSum = sum([user_count[user]**2 for user in user_count]) user_mean = float(uSum) / len(user_count) user_variant = math.sqrt(float(uSqSum) / len(user_count) - user_mean**2) mSum = sum([movie_count[movie] for movie in movie_count]) mSqSum = sum([movie_count[movie]**2 for movie in movie_count]) movie_mean = float(mSum) / len(movie_count) movie_variant = math.sqrt(float(mSqSum) / len(movie_count) - movie_mean**2) return len(user_count), len(movie_count), user_mean, user_variant, movie_mean, movie_variant, min, max if __name__ == '__main__': (user_count, movie_count, user_mean, user_variant, movie_mean, movie_variant, min, max) \ = countData("../data/baidu/training_set.txt") #(user_count, movie_count, user_mean, user_variant, movie_mean, movie_variant, min, max) \ # = countData("../data/baidu/ratings.dat") print "用戶(總數,平均值,標準差)=(", user_count, user_mean, user_variant, ")" print "電影(總數,平均值,標準差)=(", movie_count, movie_mean, movie_variant, ")" print "評分範圍=(", min, max, ")" 

三. 不錯的數據來源

[1] GroupLens數據集(推薦相關:電影數據\書\笑話等): http://grouplens.org/datasets/
[2] UCI數據集(數據豐富,無所不包) http://archive.ics.uci.edu/ml/index.html
[3] Kaggle數據(數據豐富,規範,KDD2012是騰訊提供的微博數據) http://www.kddcup2012.org/c/kddcup2012-track1
[4] Scikit-learn 提供的一些Python數據庫,能夠教你怎麼玩轉數據,我本身只玩過一點,之後得深挖一下. 此外這個Python機器學習庫的文檔堪稱天人所寫  http://scikit-learn.org/stable/datasets/
相關文章
相關標籤/搜索