svd推薦

#準備工作,調(diào)入相關(guān)的庫

import numpyas np

from numpyimport linalgas la

import pandasas pd

#第1部分:加載測試數(shù)據(jù)集,形成loadExData()函數(shù)。

#用戶-物品矩陣行代表用戶user,列代表物品item,其中的值代表用戶對物品的打分。該矩陣存放在評分.csv文件中,使用前需要加載。由movie數(shù)據(jù)集生成該評分.csv的具體實現(xiàn)見6.9節(jié)。

#行:代表用戶

#列:代表電影

#值:代表用戶對電影的評分,0表示未評分

#記載數(shù)據(jù)集

def loadExData():

return np.array(pd.read_csv("評分.csv",sep=",",header=None))

#第2部分:計算相似度,形成ecludSim()函數(shù)、pearsSim()函數(shù)、cosSim()函數(shù)。

'''

以下是三種計算相似度的算法,分別是歐式距離、皮爾遜相關(guān)系數(shù)和余弦相似度

注意三種計算方式的參數(shù)X和Y都是采用一維數(shù)組。

'''

# 利用歐式距離計算相似度 0~1之間

def ecludSim(X, Y):

return 1.0 / (1.0 + la.norm(X - Y))# linalg.norm()是向量A的模(2階范數(shù))計算方法,

#1/(1+ norm)表示將相似度歸一到0與1之間。

# 利用皮爾遜相關(guān)系數(shù)計算相似度 0~1之間

def pearsSim(X, Y):

if len(X) <3:return 1.0

? ? return 0.5 +0.5 * np.corrcoef(X, Y,rowvar=1)[0][1]

# corrcoef()表示皮爾遜相關(guān)系數(shù)的計算方法

#corrcoef() 在 -1 ~ 1之間,0.5 + 0.5*corrcoef()把其取值范圍歸一化到0到1之間。

#利用余弦相似度計算相似度0~1之間

def cosSim(X, Y):

XY =float(X.dot(Y))# 向量 X*Y

? ? XYnorm= la.norm(X) * la.norm(Y)#向量A的模(2階范數(shù)) * 向量B的模(2階范數(shù))

? ? return 0.5 +0.5 * (XY / XYnorm)#向量A 與 向量B 的夾角余弦 A*B / (||A||*||B||)

#范圍在-1~1 ,將相似度歸一到0與1之間。

#第3部分:對矩陣降維處理,形成svd_item()函數(shù)。

#本部分首先確定要選取的奇異值個數(shù),然后進行降維計算矩陣的近似值。

#1.計算選取的奇異值數(shù)目k值,形成SigmaPct函數(shù)。

'''

按照前k個奇異值的平方和占總奇異值的平方和的百分比percentage確定k的值。

后續(xù)計算SVD時需要將item原始矩陣降維

'''

def SigmaPct(sigma, percentage):

sum_sigma =sum(sigma **2)

sum_sigma1 = sum_sigma * percentage# 求所有奇異值sigma的平方和的百分比

? ? sum_sigma2 =0? # sum_sigma2是前k個奇異值的平方和

? ? k =0? # 計數(shù)

? ? for iin sigma:

sum_sigma2 += i **2? # 計算每個奇異值的平方

? ? ? ? k +=1? # 計數(shù)增加1

? ? ? ? if sum_sigma2 >= sum_sigma1:# 判斷是否已達到percentage

? ? ? ? ? ? return k

#2.降維處理,形成svd_item()函數(shù)。

#(1)調(diào)用SigmaPct()函數(shù),確定k值。

#(2)利用 ,求出降維后的 。

# 返回降維的物品數(shù)據(jù)

def svd_item(data, percentage):

n = np.shape(data)[1]# 物品種類數(shù)據(jù)

? ? U, s, VT = la.svd(data)# 數(shù)據(jù)集進行奇異值分解,返回的s為對角線上的值

? ? k = SigmaPct(s, percentage)# 確定了k的值,前k個已經(jīng)包含了percentage的能力

? ? Sigma = np.eye(k) * s[:k]# 構(gòu)建對角矩陣

# 將數(shù)據(jù)轉(zhuǎn)換到k維空間(低維),構(gòu)建轉(zhuǎn)換后的物品

? ? FormedItems = data.T.dot(U[:, :k].dot(la.inv(Sigma)))

return FormedItems# 返回降維的物品數(shù)據(jù)

#第4部分:在已經(jīng)降維的數(shù)據(jù)中,對用戶未打分的一個物品進行評分預(yù)測,形成svd_predict()函數(shù)。

'''

參數(shù)包含:數(shù)據(jù)矩陣、用戶編號、物品編號和奇異值占比的閾值,

數(shù)據(jù)矩陣的行對應(yīng)用戶,列對應(yīng)物品

函數(shù)的作用:基于item的相似性對用戶未評過分的物品進行預(yù)測評分

'''

def svd_predict(data, user, simMeas, FormedItems, item,percentage):

n = np.shape(data)[1]# 得到數(shù)據(jù)集中的物品種類數(shù)據(jù)

? ? Totalsim =0.0? # 初始化兩個評分值

? ? TotalratSim =0.0? # 相似性總和變量初始化

# 遍歷給定的用戶行中的每個物品

# 即(對用戶評過分的物品進行遍歷,并將它與其他物品進行比較),計算相似度

? ? for jin range(n):

# 得到給定的用戶user對商品的評分

? ? ? ? Rating_user = data[user, j]

# 只對評價過的商品和不是自己的商品求相似度

? ? ? ? if Rating_user !=0 and j != item:

# 計算 svd轉(zhuǎn)換過后矩陣的相似度,物品item與物品j之間的相似度

# 相似度的計算方法也會作為一個參數(shù)傳遞給該函數(shù)

? ? ? ? ? ? Similarity = simMeas(FormedItems[item, :], FormedItems[j, :])

Totalsim += Similarity# 對相似度不斷累加求和

? ? ? ? ? ? TotalratSim += Similarity * Rating_user# 對相似度及對應(yīng)評分值乘積求和

? ? if Totalsim ==0:

return 0

? ? else:

return TotalratSim / Totalsim# 得到對物品的預(yù)測評分,返回后用于分數(shù)的排序

#第5部分:產(chǎn)生前N個評分值高的物品,返回物品編號以及預(yù)測評分值,形成recommend()函數(shù)。

'''

函數(shù)recommend()產(chǎn)生預(yù)測評分最高的N個推薦結(jié)果,默認返回5個;

參數(shù)包括:數(shù)據(jù)矩陣、用戶編號、相似度衡量的方法、預(yù)測評分的方法、以及奇異值占比的閾值。

'''

def recommend(data, user, FormedItems, N, simMeas, percentage):

# 為未評價的物品建立一個用戶未評分item的列表

? ? unratedItems = np.array(np.nonzero(data[user, :] ==0))[0]

if len(unratedItems) ==0:

return "你已評價完所有物品"? # 若都已經(jīng)評過分,則退出

? ? Scoresitem = []

for itemin unratedItems:# 對未評分的物品item,都計算其預(yù)測評分

# 計算評價值

? ? ? ? estimatedScore = svd_predict(data, user, simMeas, FormedItems, item, percentage)

Scoresitem.append((item, estimatedScore))# 記錄商品及評價值

? ? Scoresitem =sorted(Scoresitem,key=lambda x: x[1],reverse=True)# 按照得分逆序排序

? ? return Scoresitem[:N]# 返回前N個評分的物品名

#第6部分:對指定用戶進行商品推薦,形成recommend_predict函數(shù)。

def recommend_predict():

user_item = loadExData()

percentage=0.9 #奇異值平方和的百分比

? ? n=4? #推薦個數(shù)

? ? FormedItems = svd_item(user_item, percentage)# 獲得SVD降維后的物品

? ? print('利用余弦相似度計算距離,進行的奇異值分解推薦:')

simMeas=cosSim#相似度

? ? for iin range(0,np.shape(user_item)[0]):

print("對第",i,"個用戶進行推薦:")

print("按相似度推薦的物品編號為:", recommend(user_item, i, FormedItems, n, simMeas, percentage))

print('利用歐式距離相似度計算距離,進行的奇異值分解推薦:')

simMeas = ecludSim

for iin range(0,np.shape(mymat1)[0]):

print("對第",i,"個用戶進行推薦:")

print("按相似度推薦的物品編號為:", recommend(user_item, i, FormedItems, n, simMeas, percentage))

print('利用皮爾遜相似度計算距離,進行的奇異值分解推薦:')

simMeas= pearsSim

for iin range(0,np.shape(mymat1)[0]):

print("對第",i,"個用戶進行推薦:")

print("按相似度推薦的物品編號為:", recommend(user_item, user, FormedItems, n, simMeas, percentage))

#第7部分:調(diào)用recommend_predict()函數(shù),獲得結(jié)果。

#主程序

recommend_predict()

其他文章:協(xié)同過濾

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內(nèi)容