此外我們還需要注意的兩個問題:
我們在可見的使用者書單中歸結出3個類別,不等於該使用者就只喜歡這3類,對其他類別的書就一點興趣也沒有。也就是說,我們需要了解使用者對於所有類別的興趣度。
對於乙個給定的類來說,我們需要確定這個類中每本書屬於該類別的權重。權重有助於我們確定該推薦哪些書給使用者。
下面我們就來看看lfm是如何解決上面的問題的?對於乙個給定的使用者行為資料集(資料集包含的是所有的user, 所有的item,以及每個user有過行為的item列表),使用lfm對其建模後,我們可以得到如下圖所示的模型:(假設資料集中有3個user, 4個item, lfm建模的分類數為4)
r矩陣是user-item矩陣,矩陣值rij表示的是user i 對item j的興趣度,這正是我們要求的值。對於乙個user來說,當計算出他對所有item的興趣度後,就可以進行排序並作出推薦。lfm演算法從資料集中抽取出若干主題,作為user和item之間連線的橋梁,將r矩陣表示為p矩陣和q矩陣相乘。其中p矩陣是user-class矩陣,矩陣值pij表示的是user i對class j的興趣度;q矩陣式class-item矩陣,矩陣值qij表示的是item j在class i中的權重,權重越高越能作為該類的代表。所以lfm根據如下公式來計算使用者u對物品i的興趣度
我們發現使用lfm後,
我們不需要關心分類的角度,結果都是基於使用者行為統計自動聚類的,全憑資料自己說了算。
不需要關心分類粒度的問題,通過設定lfm的最終分類數就可控制粒度,分類數越大,粒度約細。
對於乙個item,並不是明確的劃分到某一類,而是計算其屬於每一類的概率,是一種標準的軟分類。
對於乙個user,我們可以得到他對於每一類的興趣度,而不是只關心可見列表中的那幾個類。
對於每乙個class,我們可以得到類中每個item的權重,越能代表這個類的item,權重越高。
那麼,接下去的問題就是如何計算矩陣p和矩陣q中引數值。一般做法就是最優化損失函式來求引數。在定義損失函式之前,我們需要準備一下資料集並對興趣度的取值做一說明。
資料集應該包含所有的user和他們有過行為的(也就是喜歡)的item。所有的這些item構成了乙個item全集。對於每個user來說,我們把他有過行為的item稱為正樣本,規定興趣度rui=1,此外我們還需要從item全集中隨機抽樣,選取與正樣本數量相當的樣本作為負樣本,規定興趣度為rui=0。因此,興趣的取值範圍為[0,1]。
取樣之後原有的資料集得到擴充,得到乙個新的user-item集k=,其中如果(u,i)是正樣本,則rui=1,否則rui=0。損失函式如下所示:
上式中的
通過求引數puk和qki的偏導確定最快的下降方向;
迭代計算不斷優化引數(迭代次數事先人為設定),直到引數收斂。
其中,α是學習速率,α越大,迭代下降的越快。α和λ一樣,也需要根據實際的應用場景反覆實驗得到。本書中,作者在movielens資料集上進行實驗,他取分類數f=100,α=0.02,λ=0.01。
【注意】:書中在上面四個式子中都缺少了
綜上所述,執行lfm需要:
根據資料集初始化p和q矩陣(這是我暫時沒有弄懂的地方,這個初始化過程到底是怎麼樣進行的,還懇請各位童鞋予以賜教。)
確定4個引數:分類數f,迭代次數n,學習速率α,正則化引數λ。
lfm的偽**可以表示如下:
[python]view plain
copy
print?
def lfm(user_items, f, n, alpha, lambda):
#初始化p,q矩陣
[p, q] = initmodel(user_items, f)
#開始迭代
for step in range(0, n):
#從資料集中依次取出user以及該user喜歡的iterms集
for user, items in user_item.iterms():
#隨機抽樣,為user抽取與items數量相當的負樣本,並將正負樣本合併,用於優化計算
samples = randselectnegativesamples(items)
#依次獲取item和user對該item的興趣度
for item, rui in samples.items():
#根據當前引數計算誤差
eui = eui - predict(user, item)
#優化引數
for f in range(0, f):
p[user][f] += alpha * (eui * q[f][item] - lambda * p[user][f])
q[f][item] += alpha * (eui * p[user][f] - lambda * q[f][item])
#每次迭代完後,都要降低學習速率。一開始的時候由於離最優值相差甚遠,因此快速下降;
#當優化到一定程度後,就需要放慢學習速率,慢慢的接近最優值。
alpha *= 0.9
def lfm(user_items, f, n, alpha, lambda):
#初始化p,q矩陣
[p, q] = initmodel(user_items, f)
#開始迭代
for step in range(0, n):
#從資料集中依次取出user以及該user喜歡的iterms集
for user, items in user_item.iterms():
#隨機抽樣,為user抽取與items數量相當的負樣本,並將正負樣本合併,用於優化計算
samples = randselectnegativesamples(items)
#依次獲取item和user對該item的興趣度
for item, rui in samples.items():
#根據當前引數計算誤差
eui = eui - predict(user, item)
#優化引數
for f in range(0, f):
p[user][f] += alpha * (eui * q[f][item] - lambda * p[user][f])
q[f][item] += alpha * (eui * p[user][f] - lambda * q[f][item])
#每次迭代完後,都要降低學習速率。一開始的時候由於離最優值相差甚遠,因此快速下降;
#當優化到一定程度後,就需要放慢學習速率,慢慢的接近最優值。
alpha *= 0.9
本人對書中的偽**追加了注釋,有不對的地方還請指正。
當估算出p和q矩陣後,我們就可以使用(*)式計算使用者u對各個item的興趣度值,並將興趣度值最高的n個iterm(即top n)推薦給使用者。
總結來說,lfm具有成熟的理論基礎,它是乙個純種的學習演算法,通過最優化理論來優化指定的引數,建立最優的模型。
推薦系統 02 隱語義模型LFM
隱語義模型 lfm 圖形解釋 lfm的前生今世 隱語義模型的適用性 關於訓練集 基本概念 那麼如何產生負樣本呢?負樣本的選擇 小結 如何計算權重 負樣本取樣過程 如何求解c的極小值 演算法原理 原函式 deffun x,y return x y 2 x x 2 x y y y 偏x導 defpxfu...
推薦系統 5 隱語義模型 LFM
2019 03 02 14 27 17 對於usercf,我們可以先計算和目標使用者興趣相似的使用者,之後再根據計算出來的使用者喜歡的物品給目標使用者推薦物品。而itemcf,我們可以根據目標使用者喜歡的物品,尋找和這些物品相似的物品,再推薦給使用者。我們還有一種方法,先對所有的物品進行分類,再根據...
隱語義分析,以LFM為例
隱語義分析,以lfm為例 乙個比較好的圖 對於乙個給定的使用者行為資料集 資料集包含的是所有的user,所有的item,以及每個user有過行為的item列表 使用lfm對其建模後,我們可以得到如下圖所示的模型 假設資料集中有3個user,4個item,lfm建模的分類數為4 r矩陣是user it...