推薦算法矩陣分解實戰(zhàn)——keras算法練習(xí)(3)

當(dāng)今這個信息爆炸的社會腥椒,每個人都會面對無數(shù)的商品沿猜,無數(shù)的選擇。而推薦算法的目的幫助大家解決選擇困難癥的問題溪烤,在大千世界中推薦專屬于你的商品味咳。

推薦系統(tǒng)算法簡介

這里簡單介紹下推薦系統(tǒng)中最為主要的協(xié)同過濾算法,大致分為如下幾類:

  • 基于用戶的協(xié)同過濾(給用戶推薦與他相似的人購買的物品)
  • 基于商品的協(xié)同過濾(給用戶推薦和他之前喜歡的物品相似的物品)
  • 基于模型的協(xié)同過濾:關(guān)聯(lián)算法檬嘀,聚類算法槽驶,分類算法,回歸算法鸳兽,矩陣分解掂铐,神經(jīng)網(wǎng)絡(luò),圖模型以及隱語義模型都屬于這個范疇。

而本次實戰(zhàn)使用的是矩陣分解算法揍异。
矩陣分解其實是數(shù)學(xué)上的一個經(jīng)典問題全陨。大家從線性代數(shù)中可以知道,矩陣可以做SVD分解衷掷、Cholesky分解等辱姨,就好比任何大于1的正整數(shù)都可以分解成若干質(zhì)數(shù)的乘積,矩陣分解可以認(rèn)為是一種信息壓縮戚嗅。下圖是一個用戶電影評分矩陣雨涛。矩陣的每行表示一個用戶,每列表示一部電影懦胞,矩陣中每個位置的值替久,代表某個用戶對某個電影的評分值。

矩陣分解

  • R矩陣:用戶對電影的評分組合矩陣躏尉,
  • 用戶矩陣蚯根,每一個被壓縮的行向量代表一個用戶的信息向量
  • 電影矩陣胀糜,每一個被壓縮列向量代表一個電影的信息向量颅拦。

而這樣的矩陣分解壓縮過程,使得用戶矩陣電影矩陣都具有了一定的語義信息教藻,必須強(qiáng)調(diào)的是用戶矩陣行向量的維數(shù)和電影矩陣列向量維數(shù)是相等的距帅。所以本質(zhì)上就是將每個用戶和每個電影通過已有的打分信息Embedding到同一維度的信息向量空間
接下來我們就學(xué)習(xí)一下如何使用keras對R矩陣進(jìn)行矩陣分解怖竭,獲得每個電影和每個用戶的信息向量锥债。

推薦系統(tǒng)實戰(zhàn)

數(shù)據(jù)載入

import pandas as pd
import numpy as np
rating = pd.read_csv("./ml-latest-small/ratings.csv",sep=",")
num_user = np.max(rating["userId"])
num_movie = np.max(rating["movieId"])
print(num_user,num_movie,len(rating))

數(shù)據(jù)格式如下,第一列是index痊臭,第二列是用戶ID哮肚,第三列是電影ID,第四列示評分。

      userId movieId rating 
0       1     1     4.0 
1       1     3     4.0 
2       1     6     4.0 
3       1    47     5.0 
......
100831  610 166534  4.0 
100832  610 168248  5.0 
100833  610 168250  5.0 
100834  610 168252  5.0 
100835  610 170875  3.0 

其中num_user = 610, num_movie = 193609 len(rating)=100836广匙。意味著我的數(shù)據(jù)中有610為觀眾允趟,193609 部電影,得到了100836個評分?jǐn)?shù)據(jù)鸦致。從這些我們可以計算出上圖用戶電影組合的R矩陣的填充率潮剪。
100836/(610*193609) = 0.008
這說明只有0.8%的用戶電影組合有評分涣楷,當(dāng)然這和實際情況是相符的,畢竟一個人只會給很少部分的電影評分抗碰,所以我們發(fā)現(xiàn)用戶對電影的評分組合矩陣R極其稀疏狮斗。所以接下來我們要做的就是預(yù)測那些沒有評分的用戶電影組合可能的得分,填充R矩陣弧蝇,這樣就可以為用戶推薦模型預(yù)測得分較高的電影碳褒。

模型搭建

from keras import Model
import keras.backend as K
from keras.layers import Embedding,Reshape,Input,Dot
K.clear_session()
def Recmand_model(num_user,num_movie,k):
    input_uer = Input(shape=[None,],dtype="int32")
    model_uer = Embedding(num_user+1,k,input_length = 1)(input_uer)
    model_uer = Reshape((k,))(model_uer)
    
    input_movie = Input(shape=[None,],dtype="int32")
    model_movie  = Embedding(num_movie+1,k,input_length = 1)(input_movie)
    model_movie = Reshape((k,))(model_movie)
    
    out = Dot(1)([model_uer,model_movie])
    model = Model(inputs=[input_uer,input_movie], outputs=out)
    model.compile(loss='mse', optimizer='Adam')
    model.summary()
    return model

這里就是矩陣分解的部分,模型的架構(gòu)圖如下圖所示:將用戶和電影通過Eembdding層壓縮到k維度向量看疗,然后簡單粗暴直接向量點乘沙峻,得到用戶對電影的預(yù)測評分。這里誤差采用平方誤差MSE两芳,優(yōu)化器采用的是Adam摔寨。

模型架構(gòu)
model = Recmand_model(num_user,num_movie,100)

運行上方代碼就可以構(gòu)建好模型,這里筆者將用戶和電影都embedding的100維的向量空間中怖辆。


model

數(shù)據(jù)準(zhǔn)備

將數(shù)據(jù)準(zhǔn)備成( [用戶ID, 電影ID] , 用戶ID對電影ID的評分 )這種格式是复。接下來就可以把數(shù)據(jù)喂給模型了。

train_user = rating["userId"].values
train_movie = rating["movieId"].values
train_x = [train_user,train_movie]
train_y = rating["rating"].values

拿到輸入數(shù)據(jù)之后疗隶,設(shè)置好batch_size,epoch佑笋,就可以進(jìn)行訓(xùn)練了翼闹。運行下面代碼讓模型跑起來斑鼻。

模型訓(xùn)練

model.fit(train_x,train_y,batch_size = 100,epochs =10)
train

十個epoch之后loss只有0.09,這樣我們就可以不嚴(yán)謹(jǐn)?shù)南陆Y(jié)論:模型的預(yù)測誤差不超出0.1猎荠,接下來是預(yù)測部分坚弱。

模型預(yù)測

從之前讀入數(shù)據(jù)中可以得知,userId為1的用戶关摇,沒有對movieId為2的電影評分荒叶。我們就用模型試試userId為1的用戶會為movieId為2的電影打多少數(shù)分呢?運行下方代碼输虱,便能知曉些楣。

model.predict([[1],[2]])

輸出結(jié)果:array([[3.9732044]], dtype=float32)

模型預(yù)測為3.9,而評分的總分為5分宪睹,意味著userId為1的用戶很有可能會喜歡movieId為2的電影愁茁。可以考慮將movieId為2的電影推薦給userId為1的用戶亭病。

結(jié)語

這里只是采用了最簡單的方式做了一個簡單的推薦系統(tǒng)鹅很,而且此方式很難解決新的電影和新的用戶的推薦問題。推薦系統(tǒng)是門很深的學(xué)問罪帖,算法不僅需要考慮到推薦的準(zhǔn)確率促煮,覆蓋率邮屁,還要考慮到推薦內(nèi)容的豐富性和新穎性。人是很容易改變和厭倦的動物菠齿,所以佑吝,筆者有時候在想真會出現(xiàn)一個一直都懂你的推薦算法嗎?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绳匀,一起剝皮案震驚了整個濱河市迹蛤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌襟士,老刑警劉巖盗飒,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異陋桂,居然都是意外死亡逆趣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門嗜历,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宣渗,“玉大人,你說我怎么就攤上這事梨州『鄞眩” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵暴匠,是天一觀的道長鞍恢。 經(jīng)常有香客問我,道長每窖,這世上最難降的妖魔是什么帮掉? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮窒典,結(jié)果婚禮上蟆炊,老公的妹妹穿的比我還像新娘。我一直安慰自己瀑志,他們只是感情好涩搓,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著劈猪,像睡著了一般昧甘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上岸霹,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天疾层,我揣著相機(jī)與錄音,去河邊找鬼贡避。 笑死痛黎,一個胖子當(dāng)著我的面吹牛予弧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播湖饱,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼掖蛤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了井厌?” 一聲冷哼從身側(cè)響起蚓庭,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仅仆,沒想到半個月后器赞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡墓拜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年港柜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咳榜。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡夏醉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涌韩,到底是詐尸還是另有隱情畔柔,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布臣樱,位于F島的核電站靶擦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏擎淤。R本人自食惡果不足惜奢啥,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一秸仙、第九天 我趴在偏房一處隱蔽的房頂上張望嘴拢。 院中可真熱鬧,春花似錦寂纪、人聲如沸席吴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽孝冒。三九已至,卻和暖如春拟杉,著一層夾襖步出監(jiān)牢的瞬間庄涡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工搬设, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留穴店,地道東北人撕捍。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像泣洞,于是被迫代替她去往敵國和親忧风。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

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