推薦系統 | 矩陣分解(SVD)原理和實戰

2021-01-14 機器學習與數據挖掘實踐

本文收錄在推薦系統專欄,專欄系統化的整理推薦系統相關的算法和框架,並記錄了相關實踐經驗,所有代碼都已整理至推薦算法實戰集合(hub-recsys)。

目錄

一. 特徵分解

1.1 特徵求解:

1.2 標準化:

1.3 特徵分解條件

二. SVD

2.1 定義

2.2 求解方法

2.3 相關特性 

2.4 SVD的python實現

2.5 SVD在PCA中的應用

三. 推薦系統中的SVD

3.1 問題定義

3.2 SVD應用

3.2.1 traditional-SVD

3.2.2 FunkSVD

3.2.3 BiasSVD

3.2.4 SVD++

3.3 矩陣分解推薦小結

3.4 SVD實現用戶評分預測(MovieLens數據集)

特徵分解——>奇異值分解(SVD)——>隱語義模型(LFM),三個算法在前者的基礎上推導而成,按順序先後出現。三者均用於矩陣降維。其中:特徵分解可用於主成分分析。奇異值分解(SVD)和隱語義模型(LFM)可用於推薦系統中,將評分矩陣補全、降維。
一. 特徵分解

1.1 特徵求解:

特徵分解是指將矩陣分解為由其特徵值和特徵向量表示的矩陣之積的方法,我們首先回顧下特徵值和特徵向量的定義:

上式中,λ是矩陣A的一個特徵值,x是矩陣A的特徵值λ對應的一個n維特徵向量。站在特徵向量的角度,特徵向量的幾何含義是:特徵向量x通過方陣A變換,只縮放,方向不變。

求得A的n個特徵值後,組成對角矩陣∑,A的特徵分解就可以表示為:

其中U是n個特徵向量組成的n×n維方陣,∑是這n個特徵值為主對角線的n×n維方陣。


1.2 標準化:

一般我們會把U的這n個特徵向量標準化(可使用施密特正交化方法),即滿足||𝑤𝑖||2=1, 或者說𝑤𝑖𝑇𝑤𝑖=1。標準化後∑的𝑛個特徵向量為標準正交基,滿足∑𝑇∑=𝐼,即∑𝑇=∑−1, 也就是說∑為酉矩陣。這樣我們的特徵分解表達式可以寫成


1.3 特徵分解條件

根據上述條件,實對稱矩陣一定可以進行特徵分解。但是針對更一般的情況,由於特徵分解矩陣A必須為方陣,對於行和列不相同的矩陣,應該如何分解,可以引出我們下文討論的SVD。


二. SVD
2.1 定義

SVD也是對矩陣進行分解,但是和特徵分解不同,SVD並不要求要分解的矩陣為方陣。假設我們的矩陣A是一個𝑚×𝑛的矩陣,那麼我們定義矩陣A的SVD為:


其中U是一個𝑚×𝑚矩陣,Σ是一個𝑚×𝑛矩陣,除了主對角線上的元素以外全為0,主對角線上的每個元素都稱為奇異值,V是一個𝑛×𝑛的矩陣。U和V都是酉矩陣,即滿足𝑈𝑇𝑈=𝐼,𝑉𝑇𝑉=𝐼。

2.2 求解方法

那麼我們如何求出SVD分解後的𝑈,Σ,𝑉,簡單的方式是和轉置矩陣相乘,獲得方陣,然後再對方陣進行特徵分解。


利用式(2-2)特徵值分解,得到的特徵矩陣即為𝑈;利用式(2-3)特徵值分解,得到的特徵矩陣即為𝑉;對Σ𝑇Σ或的特徵值開方,可以得到所有的奇異值。


2.3 相關特性 

奇異值可以被看作成一個矩陣的代表值,或者說,奇異值能夠代表這個矩陣的信息。當奇異值越大時,它代表的信息越多。也就是說,我們也可以用最大的k個的奇異值和對應的左右奇異向量來近似描述矩陣,並且SVD的求解可實現並行化,SVD的缺點是分解出的矩陣解釋性往往不強,有點黑盒子的味道,不過這不影響它的使用。



2.4 SVD的python實現


矩陣數據讀取

import numpy as np
import pandas as pd
from scipy.io import loadmat

# 讀取數據,使用自己數據集的路徑。
train_data_mat = loadmat("../data/train_data2.mat")
train_data = train_data_mat["Data"]
print(train_data.shape)



特徵值分解

# 數據必需先轉為浮點型,否則在計算的過程中會溢出,導致結果不準確
train_dataFloat = train_data / 255.0
# 計算特徵值和特徵向量
eval_sigma1,evec_u = np.linalg.eigh(train_dataFloat.dot(train_dataFloat.T))



計算奇異矩陣

#降序排列後,逆序輸出
eval1_sort_idx = np.argsort(eval_sigma1)[::-1]
# 將特徵值對應的特徵向量也對應排好序
eval_sigma1 = np.sort(eval_sigma1)[::-1]
evec_u = evec_u[:,eval1_sort_idx]
# 計算奇異值矩陣的逆
eval_sigma1 = np.sqrt(eval_sigma1)
eval_sigma1_inv = np.linalg.inv(np.diag(eval_sigma1))
# 計算右奇異矩陣
evec_part_v = eval_sigma1_inv.dot((evec_u.T).dot(train_dataFloat))


上面的計算出的evec_u, eval_sigma1, evec_part_v分別為左奇異矩陣,所有奇異值,右奇異矩陣。



2.5 SVD在PCA中的應用

對於PCA降維而言,需要找到樣本協方差矩陣𝑋𝑇𝑋的最大的d個特徵向量,然後用這最大的d個特徵向量張成的矩陣來做低維投影降維。可以看出,在這個過程中需要先求出協方差矩陣𝑋𝑇𝑋,當樣本數多樣本特徵數也多的時候,這個計算量是很大的。

SVD也可以得到協方差矩陣𝑋𝑇𝑋最大的d個特徵向量張成的矩陣,但是SVD有個好處,有一些SVD的實現算法可以不求先求出協方差矩陣𝑋𝑇𝑋,也能求出我們的右奇異矩陣𝑉V。也就是說,我們的PCA算法可以不用做特徵分解,而是做SVD來完成。這個方法在樣本量很大的時候很有效。

PCA僅僅使用了我們SVD的右奇異矩陣,沒有使用左奇異矩陣。左奇異矩陣可以用於行數的壓縮。相對的,右奇異矩陣可以用於列數即特徵維度的壓縮,也就是我們的PCA降維。    


三. 推薦系統中的SVD


在推薦系統 - 概述和技術演進中,我們提到利用矩陣分解是Model-Based協同過濾是廣泛使用的方法。


3.1 問題定義

在推薦系統中,我們常常遇到的問題是這樣的,我們有很多用戶和物品,也有少部分用戶對少部分物品的評分,我們希望預測目標用戶對其他未評分物品的評分,進而將評分高的物品推薦給目標用戶。比如下面的用戶物品評分表:

用戶\物品物品1物品2物品3物品4物品5物品6物品7用戶13
5

1
用戶2
2



4用戶3


4


用戶4

2


1用戶51


4

即對於一個M行(M個user),N列(N個item)的矩陣,我們的任務是要通過分析已有的數據(觀測數據)來對未知數據進行預測,即這是一個矩陣補全(填充)任務。


3.2 SVD應用3.2.1 traditional-SVD

此時可以將這個用戶物品對應的𝑚×𝑛矩陣𝑀進行SVD分解,並通過選擇部分較大的一些奇異值來同時進行降維,也就是說矩陣𝑀此時分解為:


從而可以使用矩陣的乘積對稀疏空缺物品的評分做預測,然後再對評分排序,將高評分的物品推薦給用戶。

缺點:

評分矩陣不稠密:用全局平均值或者用用戶物品平均值補全。

耗時巨大:userItem維度通常很大,SVD分解耗時巨大的。

分解方式比較單一,獲取的特徵的方式不夠靈活,是否可以完全表徵用戶和item特徵。


3.2.2 FunkSVD

FunkSVD用於解決 traditional-SVD 計算耗時大的問題,同時避免解決稀疏的問題,將期望矩陣𝑀分解成兩個矩陣Q和P的乘積。


FunkSVD如何將矩陣𝑀分解為𝑃和𝑄呢?這裡採用了線性回歸的思想。我們的目標是讓用戶的評分和用矩陣乘積得到的評分殘差儘可能的小,也就是說,可以用均方差作為損失函數,來尋找最終的𝑃和𝑄。借鑑線性回歸的思想,通過最小化觀察數據的平方來尋求最優的用戶和項目的隱含向量表示。同時為了避免過度擬合(Overfitting)觀測數據,加入正則項。


最終可通過梯度下降或者隨機梯度下降法來尋求最優解。

    

3.2.3 BiasSVD

BiasSVD假設評分系統包括三部分的偏置因素:1. 用戶有一些和物品無關的評分因素,稱為用戶偏置項(用戶就喜歡打高分),2.物品也有一些和用戶無關的評分因素,稱為物品偏置項(山寨商品)

假設評分系統平均分為𝜇,第i個用戶的用戶偏置項為𝑏𝑖,而第j個物品的物品偏置項為𝑏𝑗,則加入了偏置項以後的優化目標函數如下所示:


通過迭代我們最終可以得到𝑃和𝑄,進而用於推薦。BiasSVD增加了一些額外因素的考慮,因此在某些場景會比FunkSVD表現好。


3.2.4 SVD++

SVD++算法在BiasSVD算法上進一步做了增強,這裡它增加考慮用戶的隱式反饋。


它是基於這樣的假設:用戶對於項目的歷史評分記錄或者瀏覽記錄可以從側面反映用戶的偏好,比如用戶對某個項目進行了評分,可以從側面反映他對於這個項目感興趣,同時這樣的行為事實也蘊含一定的信息。其中N(i)為用戶i所產生行為的物品集合;ys為隱藏的對於項目j的個人喜好偏置,是一個我們所要學習的參數;至於|N(i)|的負二分之一次方是一個經驗公式。


3.3 矩陣分解推薦小結

矩陣分解用於推薦方法本身來說,它容易編程實現,實現複雜度低,預測效果也好,同時還能保持擴展性,小的推薦系統用矩陣分解應該是一個不錯的選擇。

但是當數據的特徵和維度逐漸增多時,不再具備優勢,無法引入更多的side-information,同時也並沒有解決數據稀疏和冷啟動問題。


3.4 SVD實現用戶評分預測(MovieLens數據集)
'''Version:1.0Created on 2014-02-25@Author:Dior'''
import randomimport mathimport cPickle as pickle
class SVD(): def __init__(self,allfile,trainfile,testfile,factorNum=10): self.allfile=allfile self.trainfile=trainfile self.testfile=testfile self.factorNum=factorNum self.userNum=self.getUserNum() self.itemNum=self.getItemNum() self.learningRate=0.01 self.regularization=0.05 self.initModel() def getUserNum(self): file=self.allfile cnt=0 userSet=set() for line in open(file): user=line.split('\t')[0].strip() if user not in userSet: userSet.add(user) cnt+=1 return cnt def getItemNum(self): file=self.allfile cnt=0 itemSet=set() for line in open(file): item=line.split('\t')[1].strip() if item not in itemSet: itemSet.add(item) cnt+=1 return cnt def initModel(self): self.av=self.average(self.trainfile) self.bu=[0.0 for i in range(self.userNum)] self.bi=[0.0 for i in range(self.itemNum)] temp=math.sqrt(self.factorNum) self.pu=[[(0.1*random.random()/temp) for i in range(self.factorNum)] for j in range(self.userNum)] self.qi=[[0.1*random.random()/temp for i in range(self.factorNum)] for j in range(self.itemNum)] print "Initialize end.The user number is:%d,item number is:%d,the average score is:%f" % (self.userNum,self.itemNum,self.av) def train(self,iterTimes=100): print "Beginning to train the model......" trainfile=self.trainfile preRmse=10000.0 for iter in range(iterTimes): fi=open(trainfile,'r') for line in fi: content=line.split('\t') user=int(content[0].strip())-1 item=int(content[1].strip())-1 rating=float(content[2].strip()) pscore=self.predictScore(self.av,self.bu[user],self.bi[item],self.pu[user],self.qi[item]) eui=rating-pscore
self.bu[user]+=self.learningRate*(eui-self.regularization*self.bu[user]) self.bi[item]+=self.learningRate*(eui-self.regularization*self.bi[item]) for k in range(self.factorNum): temp=self.pu[user][k] self.pu[user][k]+=self.learningRate*(eui*self.qi[user][k]-self.regularization*self.pu[user][k]) self.qi[item][k]+=self.learningRate*(temp*eui-self.regularization*self.qi[item][k]) fi.close() curRmse=self.test(self.av,self.bu,self.bi,self.pu,self.qi) print "Iteration %d times,RMSE is : %f" % (iter+1,curRmse) if curRmse>preRmse: break else: preRmse=curRmse print "Iteration finished!" def test(self,av,bu,bi,pu,qi): testfile=self.testfile rmse=0.0 cnt=0 fi=open(testfile) for line in fi: cnt+=1 content=line.split('\t') user=int(content[0].strip())-1 item=int(content[1].strip())-1 score=float(content[2].strip()) pscore=self.predictScore(av,bu[user],bi[item],pu[user],qi[item]) rmse+=math.pow(score-pscore,2) fi.close() return math.sqrt(rmse/cnt) def average(self,filename): result=0.0 cnt=0 for line in open(filename): cnt+=1 score=float(line.split('\t')[2].strip()) result+=score return result/cnt def innerProduct(self,v1,v2): result=0.0 for i in range(len(v1)): result+=v1[i]*v2[i] return result def predictScore(self,av,bu,bi,pu,qi): pscore=av+bu+bi+self.innerProduct(pu,qi) if pscore<1: pscore=1 if pscore>5: pscore=5 return pscore
if __name__=='__main__': s=SVD("data\\u.data","data\\ua.base","data\\ua.test") s.train()

排序學習(Learning to rank)綜述

今日頭條 | 推薦算法原理詳解

Tensorflow架構

喜歡的話點個在看吧👇

相關焦點

  • 奇異值、奇異矩陣、SVD分解、正交矩陣
    然後,再看此方陣的行列式|A|是否等於0,若等於0,稱矩陣A為奇異矩陣;若不等於0,稱矩陣A為非奇異矩陣。 同時,由|A|≠0可知矩陣A可逆,這樣可以得出另外一個重要結論:可逆矩陣就是非奇異矩陣,非奇異矩陣也是可逆矩陣。如果A為奇異矩陣,則AX=0有非零解或無解。如果A為非奇異矩陣,則AX=0有且只有唯一零解。
  • 數據科學中需要知道的5個關於奇異值分解(SVD)的應用
    線性代數的一種這樣的用途是奇異值分解(SVD)用於降維。你在數據科學中一定很多次遇到SVD。它無處不在,特別是當我們處理降維時。但它是什麼?它是如何工作的?SVD應用有什麼?事實上,SVD是推薦系統的基礎,而推薦系統是谷歌,YouTube,亞馬遜,Facebook等大公司的核心。
  • SVD奇異值分解的數學涵義及其應用實例
    [online]Ams.org.Availableat: http://www.ams.org/publicoutreach/feature-column/fcarc-svd [Accessed 27 Feb. 2019].[2] Wikipedia contributors. "酉矩陣."維基百科, 自由的百科全書.
  • 從理論到實踐,一文詳解 AI 推薦系統的三大算法
    由於信息的爆炸式增長,對信息獲取的有效性,針對性的需求也就自然出現了。推薦系統應運而生。● 對於登錄用戶,亞馬遜中國則給出了完全不同的推薦方式,網站會根據用戶的歷史瀏覽記錄在登入界面首屏展現出一個今日推薦的欄目,緊接著是最近一次瀏覽商品的記錄和根據該物品所給的產品推薦(「根據瀏覽推薦給我的商品」、「瀏覽XX產品的用戶會買XX的概率」),值得注意的是,每個頁面最下方網站都會根據用戶的瀏覽行為做響應推薦,如果沒有瀏覽記錄則會推薦「系統暢銷品」(13頁,50款商品)。
  • 強大的矩陣奇異值分解(SVD)及其應用
    在上篇文章中便是基於特徵值分解的一種解釋。特徵值和奇異值在大部分人的印象中,往往是停留在純粹的數學計算中。而且線性代數或者矩陣論裡面,也很少講任何跟特徵值與奇異值有關的應用背景。奇異值分解是一個有著很明顯的物理意義的一種方法,它可以將一個比較複雜的矩陣用更小更簡單的幾個子矩陣的相乘來表示,這些小矩陣描述的是矩陣的重要的特性。
  • 幾何角度理解奇異值分解SVD
    二、SVD的幾何意義奇異值分解SVD ( The singular value decomposition )從幾何意義上來說:對於任意矩陣M,通過SVD。可以將一個相互垂直的坐標變換到另外一個相互垂直的坐標。問題描述:用v1和v2分別表示原來坐標系中的單位向量, 經過左乘矩陣M後,向量Mv1和 Mv2正交。
  • 奇異值分解和矩陣分解傻傻分不清楚?一文幫你理清兩者差異!
    在推薦系統的相關研究中,我們常常用到兩個相關概念:矩陣分解和奇異值分解。這兩個概念是同一種算法嗎?兩者到底有什麼差別?在本文中,作者梳理了兩種算法的概念、來源和內容,並進行了比較。通過對相關內容的梳理,作者提出,矩陣分解是推薦系統中最初使用的概念,奇異值分解是對該方法的進一步發展。在現在的討論中,一般將兩種方法統一成為奇異值分解。
  • 奇異值分解簡介:從原理到基礎機器學習應用
    奇異值分解(SVD)可能是最著名和使用最廣泛的矩陣分解方法。所有矩陣都有一種 SVD 方法,這使得其比特徵分解(eigendecomposition)等其它方法更加穩定。因此,這種方法在很多應用中都有應用,包括壓縮、去噪、數據壓縮。在這份教程中,你將了解用於將矩陣分解成其組成元素的奇異值分解方法。
  • 奇異值分解(SVD) 的 幾何意義
    換句話說,定義在單位圓上的函數|Mx|分別在v1和v2方向上取得最大和最小值。這樣我們就把尋找矩陣的奇異值分解過程縮小到了優化函數|Mx|上了。結果發現(具體的推到過程這裡就不詳細介紹了)這個函數取得最優值的向量分別是矩陣 MT M 的特徵向量。由於MTM是對稱矩陣,因此不同特徵值對應的特徵向量都是互相正交的,我們用vi 表示MTM的所有特徵向量。
  • 奇異值分解及其應用
    特徵值和奇異值在大部分人的印象中,往往是停留在純粹的數學計算中。而且線性代數或者矩陣論裡面,也很少講任何跟特徵值與奇異值有關的應用背景。奇異值分解是一個有著很明顯的物理意義的一種方法,它可以將一個比較複雜的矩陣用更小更簡單的幾個子矩陣的相乘來表示,這些小矩陣描述的是矩陣的重要的特性。
  • 通俗易懂的講解奇異值分解(SVD)和主成分分析(PCA)
    與之前在特徵分解部分的步驟相似,我們也可以將上面的方程用矩陣形式表示出來,從而可以得到矩陣A奇異值分解的表達式。但是,矩陣v,矩陣u和奇異值σ應該如何求取呢?我們可以通過矩陣乘積(AA和AA)的方式從方程的兩邊來分別消除V和U來獲得,具體方法如下:這些步驟看起來是不是很熟悉…的確,通過對對稱矩陣AA和AA進行奇異值分解,這個結果看起來幾乎與對對稱矩陣進行特徵分解是相同的
  • 推薦算法系統/人臉識別/深度學習對話機器人高級實戰課
    包含了推薦算法系統實戰、深度學習人臉識別實戰、深度學習對話機器人實戰等高級前沿的精品課程,下面分別介紹下各個實戰項目:1、推薦算法系統實戰首先推薦系統不等於推薦算法,更不等於協同過濾。推薦系統是偏算法的策略系統,但要達到一個非常好的推薦效果,只有算法是不夠的。比如做算法依賴於訓練數據,數據質量不好,或者數據處理沒做好,再好的算法也發揮不出價值。算法上線了,如果不知道效果怎麼樣,後面的優化工作就無法進行。所以AB測試是評價推薦效果的關鍵,它指導著系統該何去何從。為了能夠快速切換和優化策略,推薦位管理平臺起著舉足輕重的作用。
  • 矩陣分解 (乘法篇)
    對角和三角矩陣首先, 我們總結下, 在矩陣加法分解中出現了三種矩陣: 上三角矩陣, 下三角矩陣 和 對角陣。  這三種矩陣在乘法的分解中也會遇到。 那麼是不是乘法矩陣中有這三種矩陣就夠了呢? 不是的!正交矩陣還有一種經典的矩陣, 叫正交矩陣, 什麼叫正交矩陣呢?
  • 專題七:矩陣分解
    專題七:矩陣分解矩陣分解分為兩類:和分解與積分解.和分解是將一個矩陣分解為一些矩陣的和.積分解是將一個矩陣分解為一些矩陣的乘積.矩陣分解通常是利用標準形理論.個秩為1的矩陣的和0的矩陣的和.可以唯一分解為一個對稱陣與一個反對稱陣的和
  • 矩陣的奇異值與特徵值有什麼相似之處與區別之處?
    A=,和是兩組正交單位向量,是對角陣,表示奇異值,它表示我們找到了和這樣兩組基,A矩陣的作用是將一個向量從這組正交基向量的空間旋轉到這組正交基向量空間,並對每個方向進行了一定的縮放,縮放因子就是各個奇異值。如果維度比大,則表示還進行了投影。可以說奇異值分解將一個矩陣原本混合在一起的三種作用效果,分解出來了。而特徵值分解其實是對旋轉縮放兩種效應的歸併。
  • 深入了解SVD與糾纏
    你可能已經對它非常熟悉了,但這裡還是要快速地回顧一下。每個矩陣MM都可以分解為M=UDV† ,如下圖所示,稱為M的奇異值分解。對角矩陣D的元素為非負數,稱為奇異值,它們的數量等於M的秩,比如說k。更重要的是,U和V正好有k列,分別稱為左、右奇異值向量。
  • 矩陣的特徵值分解的物理意義
    矩陣的特徵值分解目的就是提取出一個矩陣最重要的特徵。這其實是在平面上對一個軸進行的拉伸變換(如藍色的箭頭所示),在圖中,藍色的箭頭是一個最主要的變化方向(變化方向可能有不止一個),如果我們想要描述好一個變換,那我們就描述好這個變換主要的變化方向就好了。
  • IJCAI 2020|推薦系統中的隱私威脅與對策
    推薦系統的「數據孤島」困境推薦系統技術在商業社會中為國內和國際眾多科技巨頭騰訊,Google等公司帶來海量的營收。在電商購物與短視頻推送等眾多業務場景中,推薦系統根據收集到的用戶數據為不同用戶推送個性化的內容,已然成為智能時代的關鍵技術。
  • 教程| 從特徵分解到協方差矩陣:詳細剖析和實現PCA算法
    一個線性變換通常可以由其特徵值和特徵向量完全描述。如果我們將矩陣看作物理運動,那麼最重要的就是運動方向(特徵向量)和速度(特徵值)。因為物理運動只需要方向和速度就可以描述,同理矩陣也可以僅使用特徵向量和特徵值描述。其實在線性代數中,矩陣就是一個由各種標量或變量構成的表格,它和 Excel 表格並沒有什麼本質上的區別。