【机器学习】因子分解机(FM) 原理及在召回中的应用(python实现)
FM 原理及在召回中的應(yīng)用(python實(shí)現(xiàn))
1. 綜述
為了學(xué)習(xí)推薦系統(tǒng)的召回模型,首先梳理了一下FM模型,權(quán)當(dāng)是學(xué)習(xí)筆記,記錄一下。
FM(factor Machine,因子分解機(jī))算法是一種基于矩陣分解的機(jī)器學(xué)習(xí)算法,是為了解決大規(guī)模稀疏矩陣中特征組合問題。它是一種通用的預(yù)測方法,在即使數(shù)據(jù)非常稀疏的情況下,依然能估計(jì)出可靠的參數(shù)進(jìn)行預(yù)測。與傳統(tǒng)的簡單線性模型不同的是,因子分解機(jī)考慮了特征間的交叉,對(duì)所有嵌套變量交互進(jìn)行建模(類似于SVM中的核函數(shù)),因此在推薦系統(tǒng)和計(jì)算廣告領(lǐng)域關(guān)注的點(diǎn)擊率CTR(click-through rate)和轉(zhuǎn)化率CVR(conversion rate)兩項(xiàng)指標(biāo)上有著良好的表現(xiàn)。此外,FM的模型還具有可以用線性時(shí)間來計(jì)算,以及能夠與許多先進(jìn)的協(xié)同過濾方法(如Bias MF、svd++等)相融合等優(yōu)點(diǎn),也被廣泛的應(yīng)用于召回模型中。
本文的主要組織思路如下:
為什么提出FM(演進(jìn))
FM具體是什么(原理)
FM模型在召回中的應(yīng)用
具體怎樣應(yīng)用
2. FM演進(jìn)
為什么會(huì)提出FM模型,下面我從兩個(gè)角度來簡單介紹下FM模型,一個(gè)角度是從特征組合模型的進(jìn)化角度來講;另外一個(gè)角度從協(xié)同過濾模型的進(jìn)化角度來講。FM模型剛好處于這兩類模型進(jìn)化的交匯口。
特征組合角度
這條路徑主要的演進(jìn)路線是從LR到SVM再到FM模型。LR模型是CTR預(yù)估領(lǐng)域早期成功的模型,在深度學(xué)習(xí)大規(guī)模應(yīng)用之前,大多工業(yè)推薦排序系統(tǒng)采取LR這種“線性模型+人工特征組合引入非線性”的模式,具體公式表達(dá)如圖1所示。因?yàn)長R模型具有簡單方便易解釋容易上規(guī)模等諸多好處,所以目前仍然有不少實(shí)際系統(tǒng)仍然采取這種模式。但是,LR模型最大的缺陷就是人工特征工程,耗時(shí)費(fèi)力費(fèi)人力資源,那么能否將特征組合的能力體現(xiàn)在模型層面呢?
image-20211028234308878 圖1 LR公式表達(dá)為了解決上述的問題,可以直接在圖1中的線性公式中直接加入二階特征組合即可,具體得到圖2 所示公式。任意兩個(gè)特征進(jìn)行組合,可以將這個(gè)組合出的特征看作一個(gè)新特征,融入線性模型中。而組合后的特征權(quán)重和一階特征類似可以直接在訓(xùn)練階段學(xué)習(xí)得到。其實(shí)這種二階特征組合的使用方式,和多項(xiàng)式核SVM是等價(jià)的。雖然這個(gè)模型看上去貌似解決了二階特征組合問題了,但是它有個(gè)潛在的問題:它對(duì)組合特征建模,泛化能力比較弱。這里舉一個(gè)例子加深理解,如果設(shè)計(jì)一個(gè)電影評(píng)分系統(tǒng),現(xiàn)在組合特征是用戶U對(duì)電影M的評(píng)分,在數(shù)據(jù)集合中如果用戶張三張三沒有評(píng)論電影大話西游的記錄,如果想要估計(jì)張三和大話西游之間,或者說特征分量張三和大話西游之間的相互關(guān)系,顯然會(huì)得到稀疏張三大話西游。即對(duì)于觀察樣本中未出現(xiàn)過交叉的特征分量,不能對(duì)相應(yīng)的參數(shù)進(jìn)行估計(jì)。尤其是在大規(guī)模稀疏特征存在的場景下,這個(gè)毛病尤其突出。比如CTR預(yù)估和推薦排序,這些場景的最大特點(diǎn)就是特征的大規(guī)模稀疏。所以上述模型并未在工業(yè)界廣泛采用。那么,有什么辦法能夠解決這個(gè)問題嗎?
于是,FM模型此刻可以閃亮登場了。如圖3所示,FM模型也直接引入任意兩個(gè)特征的二階特征組合,和SVM模型最大的不同,在于特征組合權(quán)重的計(jì)算方法。FM對(duì)于每個(gè)特征,學(xué)習(xí)一個(gè)大小為k的一維向量,于是,兩個(gè)特征 和的特征組合的權(quán)重值,通過特征對(duì)應(yīng)的向量 和的內(nèi)積$$ 來表示。這本質(zhì)上是在對(duì)特征進(jìn)行embedding化表征,和目前非常常見的各種實(shí)體embedding本質(zhì)思想是一脈相承的,但是很明顯在FM這么做的年代(2010年),還沒有現(xiàn)在能看到的各種眼花繚亂的embedding的形式與概念。所以FM作為特征embedding,可以看作當(dāng)前深度學(xué)習(xí)里各種embedding方法的老前輩。當(dāng)然,FM這種模式有它的前輩模型嗎?有,等會(huì)會(huì)談。其實(shí),和目前的各種深度DNN排序模型比,它僅僅是少了2層或者3層MLP隱層,用來直接對(duì)多階特征非線性組合建模而已,其它方面基本相同。
image-20211029003500966圖3 fm模型為什么fm這種通過embedding模式能夠解決上述稀疏特征下泛化能力弱的問題?如圖3所示,如果和的特征組合在數(shù)據(jù)集合中沒有出現(xiàn)過,在上述SVM模型的特征組合下,是無法學(xué)到這個(gè)特征組合的權(quán)重的。但是FM模型是學(xué)習(xí)單個(gè)特征的embedding,不依賴某個(gè)特定的特征組合是否存在,只要該特征在特征組合中出現(xiàn)過,就可以學(xué)習(xí)他對(duì)應(yīng)的特征組合的embedding向量,于是,盡管這個(gè)特征組合沒有看到過,但是在預(yù)測的時(shí)候,如果看到這個(gè)新的特征組合,因?yàn)楹投寄軐W(xué)會(huì)自己對(duì)應(yīng)的embedding,所以可以通過內(nèi)積算出這個(gè)新特征組合的權(quán)重。故而FM泛化能力更強(qiáng)。
協(xié)同過濾
協(xié)同過濾(Collaborative Filtering,CF)是推薦算法的鼻祖,至今各個(gè)互聯(lián)網(wǎng)公司中,CF都扮演著不可或缺的角色。協(xié)同過濾是根據(jù)大家的反饋、評(píng)論和意見一起對(duì)海量的信息進(jìn)行過濾,從中篩選出目標(biāo)用戶可能感興趣的信息的推薦過程。大致過程是,將用戶與商品放入一個(gè)共現(xiàn)矩陣中,矩陣中的值為某用戶對(duì)某件商品的點(diǎn)擊、評(píng)價(jià)或者購買行為的度量。我們可以將用戶感興趣的所有商品向量化,記為代表該用戶的向量,進(jìn)而可以計(jì)算用戶間的相似度。于是,可以將與某待推薦用戶相似的用戶所感興趣的商品推薦給該用戶。類似的,可以將對(duì)商品感興趣的所有用戶向量化,記為代表該商品的向量,進(jìn)而計(jì)算物品之間的相似度。在實(shí)際的計(jì)算過程中,還應(yīng)該對(duì)爆品、高銷品與其他商品的相似度進(jìn)行一定程度上的衰減。相似度的計(jì)算也應(yīng)該進(jìn)行歸一化,排除數(shù)量級(jí)的影響。
協(xié)同過濾的優(yōu)點(diǎn)是沒有顯式的學(xué)習(xí)過程、可解釋性強(qiáng)、簡單、速度快。其缺點(diǎn)也很明顯:協(xié)同過濾只考慮了用戶和物品的id信息,而無法將用戶的屬性、物品的屬性、上下文考慮在內(nèi),無法挖掘用戶和物品之間的隱含關(guān)系。對(duì)于沒有購買或者消費(fèi)的新用戶,協(xié)同過濾不知如何推薦,泛化性能差,推薦頭部效應(yīng)比較明顯。針對(duì)這些問題,MF(Matrix Factorization,矩陣分解)模型被提出來。它的核心思想是通過兩個(gè)低維小矩陣(一個(gè)代表用戶embedding矩陣,一個(gè)代表物品embedding矩陣)的乘積計(jì)算,來模擬真實(shí)用戶點(diǎn)擊或評(píng)分產(chǎn)生的大的協(xié)同信息稀疏矩陣,本質(zhì)上是編碼了用戶和物品協(xié)同信息的降維模型。當(dāng)訓(xùn)練完成,每個(gè)用戶和物品得到對(duì)應(yīng)的低維embedding表達(dá)后,如果要預(yù)測某個(gè) 對(duì) ?的評(píng)分的時(shí)候,只要它們做個(gè)內(nèi)積計(jì)算$$,這個(gè)得分就是預(yù)測得分。
本質(zhì)上,MF模型是FM模型的特例,MF可以被認(rèn)為是只有User ID 和Item ID這兩個(gè)特征Fields的FM模型,MF將這兩類特征通過矩陣分解,來達(dá)到將這兩類特征embedding化表達(dá)的目的。而FM則可以看作是MF模型的進(jìn)一步拓展,除了User ID和Item ID這兩類特征外,很多其它類型的特征,都可以進(jìn)一步融入FM模型里,它將所有這些特征轉(zhuǎn)化為embedding低維向量表達(dá),并計(jì)算任意兩個(gè)特征embedding的內(nèi)積,就是特征組合的權(quán)重,如果FM只使用User ID 和Item ID,你套到FM公式里,看看它的預(yù)測過程和MF的預(yù)測過程一樣嗎?
在具體的實(shí)踐過程中,FM模型和MF模型相比,前者繼承了后者特征embedding化的特點(diǎn),同時(shí)引入了更多的Side information作為特征,將更多的特征及Side information embedding化融入FM模型中。所以表現(xiàn)的也更加的靈活,能夠適應(yīng)更多的場景。在推薦排序階段,絕大多數(shù)只使用ID信息的模型是不實(shí)用的,沒有引入Side Information(也就是除了User ID/Item ID外的很多其它可用特征的模型)是不具備實(shí)戰(zhàn)價(jià)值的。原因很簡單,大多數(shù)真實(shí)應(yīng)用場景中,User/Item有很多信息可用,而協(xié)同數(shù)據(jù)只是其中的一種,引入更多特征明顯對(duì)于更精準(zhǔn)地進(jìn)行個(gè)性化推薦是非常有幫助的。而如果模型不支持更多特征的便捷引入,明顯受限嚴(yán)重,很難真正實(shí)用,這也是為何矩陣分解類的方法很少看到在排序階段使用,通常是作為一路召回形式存在的原因。
3. FM原理
FM模型的關(guān)鍵是:特征兩兩相關(guān)。具體的方程式如下:
其中,是第i維特征的隱向量,<-,->代表向量點(diǎn)積,具體表達(dá)關(guān)系式:
image-20211113121414814其中隱向量的長度為k(k<<n), 包含k個(gè)描述特征的因子。上述fm公式時(shí)間復(fù)雜度是 實(shí)際使用還是比較耗時(shí),這里需要對(duì)原始公式做一個(gè)化簡。針對(duì)FM模型二次項(xiàng)的等價(jià)化簡過程如圖4所示。
image-20211109005506337圖4 fm二次項(xiàng)等價(jià)化簡過程第一行到第二行的公式理解可以借助圖5所示的直觀推理,所要計(jì)算的部分就是矩陣的上半角。
image-20211109010008253圖5 矩陣直觀推理至于第二行到第三行提取公共部分理解相對(duì)較難,可以借助下圖展開公式加以理解,先把k維特征內(nèi)容抽取到最外層,第一項(xiàng)就剩下 ,然后再按照?qǐng)D6逐層展開合并,可以得到最終結(jié)果。
image-20211113003736335圖6 第三步展開公式最終的計(jì)算等價(jià)轉(zhuǎn)化為:
將時(shí)間復(fù)雜度降低為,即降到線性復(fù)雜度,提高了模型的實(shí)用性
4. 召回的應(yīng)用
在網(wǎng)上介紹最多的就是如果利用fm模型的交叉特征的特性提升網(wǎng)絡(luò)的性能,更好的做分類或者回歸任務(wù)。對(duì)于推薦系統(tǒng)的召回部分,如何通過fm模型計(jì)算user和item的相似度,在線上快速獲取topK的item?基于上面的基礎(chǔ),下面來探討一下如何用FM模型在線上做召回。
構(gòu)建一個(gè)線上的召回模塊,主要包含四大部分,訓(xùn)練數(shù)據(jù)的篩選、特征的選擇、模型訓(xùn)練,線上服務(wù)搭建。數(shù)據(jù)樣本的確認(rèn)因場景不同而有很大的差異,細(xì)節(jié)和注意點(diǎn)較多,這里不做討論,線上服務(wù)也不是討論重點(diǎn),這個(gè)章節(jié)主要集中的特征和模型部分。針對(duì)一個(gè)線上召回系統(tǒng),可以將特征簡化抽樣為user特征,item特征,以及context上下文特征(比如用戶點(diǎn)外賣所處地址、時(shí)間點(diǎn)等)。
為了簡化理解,我們可以先考慮只包含user特征和item特征。對(duì)于某個(gè)用戶,我們可以把屬于這個(gè)用戶子集合的特征,查詢離線訓(xùn)練好的FM模型對(duì)應(yīng)的特征embedding向量,然后將n個(gè)用戶子集合的特征embedding向量累加,形成用戶興趣向量U,這個(gè)向量維度和每個(gè)特征的維度是相同的。類似的,我們也可以把每個(gè)物品,其對(duì)應(yīng)的物品子集合的特征,查詢離線訓(xùn)練好的FM模型對(duì)應(yīng)的特征embedding向量,然后將m個(gè)物品子集合的特征embedding向量累加,形成物品向量I,這個(gè)向量維度和每個(gè)特征的維度也是是相同的。對(duì)于極簡版FM召回模型來說,用戶興趣向量U可以離線算好,物品興趣向量I可以類似離線計(jì)算或者近在線計(jì)算,問題都不大。
然后將上述計(jì)算得到的user embedding 存入線上redis中,線上通過id索引對(duì)應(yīng)的embedding。離線計(jì)算的item embedding可以存入Faiss(Facebook開源的embedding高效匹配庫)數(shù)據(jù)庫中。通過用戶的embedding和Faiss中存儲(chǔ)的物料embedding做內(nèi)積計(jì)算,按照得分由高到低返回得分Top K的物料作為召回結(jié)果。這樣就完成了一個(gè)極簡版本FM召回模型。但是這個(gè)版本的FM召回模型存在兩個(gè)問題。
問題一:首先我們需要問自己,這種累加用戶embedding特征向量以及累加物品embedding特征向量,之后做向量內(nèi)積。這種算法符合FM模型的原則嗎?和常規(guī)的FM模型是否等價(jià)?
我們來分析一下。這種做法其實(shí)是在做用戶特征集合U和物品特征集合I之間兩兩特征組合,是符合FM的特征組合原則的,考慮下列公式是否等價(jià)就可以明白了:
?公式(1)
?公式(2)
其實(shí)兩者是等價(jià)的,具體推導(dǎo)過程和上節(jié)中第三步的推導(dǎo)類似,但是和完全版本的FM比,我們沒有考慮U和I特征集合內(nèi)部任意兩個(gè)特征的組合。也可以這么思考問題:在上文我們說過,FM為了提升計(jì)算效率,對(duì)公式進(jìn)行了改寫,改寫后的高效計(jì)算公式的第一個(gè)平方項(xiàng)其實(shí)等價(jià)于:把所有特征embedding向量逐位累加成一個(gè)求和向量V,然后自己和自己做個(gè)內(nèi)積操作<V,V>。這樣等價(jià)于根據(jù)FM的原則計(jì)算了任意兩個(gè)特征的二階特征組合了。而上面描述的方法,和標(biāo)準(zhǔn)的FM的做法其實(shí)是一樣的,區(qū)別無非是將特征集合劃分為兩個(gè)子集合U和I,分別代表用戶相關(guān)特征及物品相關(guān)特征。而上述做法其實(shí)等價(jià)于在用戶特征和物品特征之間做兩兩特征組合,只是少了U內(nèi)部之間特征,及I內(nèi)部特征之間的特征組合而已。一般而言,其實(shí)我們不需要做U內(nèi)部特征之間以及I內(nèi)部特征之間的特征組合,對(duì)最終效果影響很小。于是,沿著這個(gè)思考路徑,我們也可以推導(dǎo)出上述做法基本和FM標(biāo)準(zhǔn)計(jì)算過程是等價(jià)的。
第二個(gè)問題是:這個(gè)版本FM是個(gè)簡化版本模型,因?yàn)樗鼪]考慮場景上下文特征,那么如果再將上下文特征引入,此時(shí)應(yīng)該怎么做呢?
上下文特征也是很重要的一個(gè)特征,它是用戶發(fā)生行為的場景特征(比如什么時(shí)間在什么地方用的什么設(shè)備在刷新),這類特征幾乎是實(shí)時(shí)變化的,比如用戶上一時(shí)刻看了什么電影,下一刻會(huì)有歷史有很大的相關(guān)性,這些動(dòng)態(tài)的特征不太可能離線算好緩存起來。考慮進(jìn)來上下文特征,如果我們希望構(gòu)造和標(biāo)準(zhǔn)的FM等價(jià)的召回模型,就需要多考慮兩個(gè)問題:既然部分上下文特征可能是實(shí)時(shí)變化的,無法離線算好,那么怎么融入上文所述的召回計(jì)算框架里?我們需要考慮上下文特征C和用戶特征U之間的特征組合,也需要考慮C和物品特征I之間的特征組合。上下文特征有時(shí)是非常強(qiáng)的特征。那么,如何做能夠?qū)⑦@兩對(duì)特征組合考慮進(jìn)來呢?
首先由于上下文特征的動(dòng)態(tài)性,所以給定用戶uid后,可以在線查詢或者計(jì)算某個(gè)上下文特征對(duì)應(yīng)的embedding向量,然后所有上下文向量求和得到綜合的上下文向量C。這個(gè)過程其實(shí)和U及I的累加過程是一樣的,區(qū)別無非是上下文特征需要在線實(shí)時(shí)計(jì)算。而一般而言,場景上下文特征數(shù)都不多,所以在線計(jì)算,速度方面應(yīng)可接受。然后,將U和C向量累加求和,利用(U+C)去Faiss通過內(nèi)積方式取出Top K物品,這個(gè)過程和極簡版是一樣的,無非查詢向量由U換成了(U+C)。通過這種方式取出的物品同時(shí)考慮到了用戶和物品的特征組合<U,I>,以及上下文和物品的特征組合<C,I>。道理和之前講的內(nèi)容是類似的。
5. 代碼實(shí)現(xiàn)
使用python做二分類任務(wù)。數(shù)據(jù)和代碼下載在AI成長社 中回復(fù)FM即可
import?numpy?as?np import?random import?pandas?as?pd from?numpy?import?* from?random?import?normalvariate??#?正態(tài)分布 from?datetime?import?datetime from?sklearn.preprocessing?import?LabelEncoder from?sklearn.preprocessing?import?OneHotEncoderdef?loadData(base_dir):'''load?ori_dataReturns:?csv_data'''movie_columns?=?['movie_id',?'title',?'genres']movies?=?pd.read_csv(base_dir?+?"movies.dat",?sep='::',?header=None,?names=movie_columns,?engine='python')rating_columns?=?['user_id','movie_id','rating','timestamp']ratings?=?pd.read_csv(base_dir?+?"ratings.dat",?sep='::',?header=None,?names=rating_columns,?engine='python')user_columns?=?['user_id','gender','age','occupation','zip']users?=?pd.read_csv(base_dir?+?"users.dat",?sep='::',?header=None,?names=user_columns,?engine='python')data?=?pd.merge(ratings,?movies)data?=?pd.merge(data,?users)return?data#?處理數(shù)據(jù) def?preprocessData(data,?ratio):label?=?data['rating'].map(lambda?x:?1?if?x?>?3?else?-1)features?=?['genres',?'gender',?'age']data?=?data[features]#?onehotdata?=?pd.get_dummies(data)num?=?int(data.shape[0]?*?ratio)train?=?data[:num]train_label?=?label[:num]test?=?data[num:]test_label?=?label[num:]return?train,?train_label,?test,?test_labeldef?sigmoid(inx):return?1.0?/?(1?+?np.exp(-inx))#?訓(xùn)練FM模型 def?FM(dataMatrix,?classLabels,?k,?iter,?alpha):''':param?dataMatrix:??特征矩陣:param?classLabels:?標(biāo)簽矩陣:param?k:???????????v的維數(shù):param?iter:????????迭代次數(shù):return:????????????常數(shù)項(xiàng)w_0,?一階特征系數(shù)w,?二階交叉特征系數(shù)v'''#?dataMatrix用的是matrix,?classLabels是列表m,?n?=?shape(dataMatrix)??#?矩陣的行列數(shù),即樣本數(shù)m和特征數(shù)n#?初始化參數(shù)w?=?zeros((n,?1))??#?一階特征的系數(shù)w_0?=?0??#?常數(shù)項(xiàng)v?=?normalvariate(0,?0.2)?*?ones((n,?k))??#?即生成輔助向量(n*k),用來訓(xùn)練二階交叉特征的系數(shù)for?it?in?range(iter):for?x?in?range(m):??#?隨機(jī)優(yōu)化,每次只使用一個(gè)樣本#?二階項(xiàng)的計(jì)算inter_1?=?dataMatrix[x]?*?v??#?每個(gè)樣本(1*n)x(n*k),得到k維向量(FM化簡公式大括號(hào)內(nèi)的第一項(xiàng))inter_2?=?multiply(dataMatrix[x],?dataMatrix[x])?*?multiply(v,?v)??#?二階交叉項(xiàng)計(jì)算,得到k維向量(FM化簡公式大括號(hào)內(nèi)的第二項(xiàng))interaction?=?sum(multiply(inter_1,?inter_1)?-?inter_2)?/?2.??#?二階交叉項(xiàng)計(jì)算完成(FM化簡公式的大括號(hào)外累加)p?=?w_0?+?dataMatrix[x]?*?w?+?interaction??#?計(jì)算預(yù)測的輸出,即FM的全部項(xiàng)之和tmp?=?1?-?sigmoid(classLabels[x]?*?p[0,?0])??#?tmp迭代公式的中間變量,便于計(jì)算w_0?=?w_0?+?alpha?*?tmp?*?classLabels[x]for?i?in?range(n):if?dataMatrix[x,?i]?!=?0:w[i,?0]?=?w[i,?0]?+?alpha?*?tmp?*?classLabels[x]?*?dataMatrix[x,?i]for?j?in?range(k):v[i,?j]?=?v[i,?j]?+?alpha?*?tmp?*?classLabels[x]?*?(dataMatrix[x,?i]?*?inter_1[0,?j]?-?v[i,?j]?*?dataMatrix[x,?i]?*?dataMatrix[x,?i])#?計(jì)算損失函數(shù)的值if?it?%?10?==?0:loss?=?getLoss(getPrediction(mat(dataMatrix),?w_0,?w,?v),?classLabels)print("第{}次迭代后的損失為{}".format(it,?loss))return?w_0,?w,?v#?損失函數(shù) def?getLoss(predict,?classLabels):m?=?len(predict)loss?=?0.0for?i?in?range(m):loss?-=?log(sigmoid(predict[i]?*?classLabels[i]))return?loss#?預(yù)測 def?getPrediction(dataMatrix,?w_0,?w,?v):m?=?np.shape(dataMatrix)[0]result?=?[]for?x?in?range(m):inter_1?=?dataMatrix[x]?*?vinter_2?=?multiply(dataMatrix[x],?dataMatrix[x])?*?multiply(v,?v)??#?multiply對(duì)應(yīng)元素相乘#?完成交叉項(xiàng)interaction?=?np.sum(multiply(inter_1,?inter_1)?-?inter_2)?/?2.p?=?w_0?+?dataMatrix[x]?*?w?+?interaction??#?計(jì)算預(yù)測的輸出pre?=?sigmoid(p[0,?0])result.append(pre)return?result#?評(píng)估預(yù)測的準(zhǔn)確性 def?getAccuracy(predict,?classLabels):m?=?len(predict)allItem?=?0error?=?0for?i?in?range(m):??#?計(jì)算每一個(gè)樣本的誤差allItem?+=?1if?float(predict[i])?<?0.5?and?classLabels[i]?==?1.0:error?+=?1elif?float(predict[i])?>=?0.5?and?classLabels[i]?==?-1.0:error?+=?1else:continuereturn?float(error)?/?allItemif?__name__?==?'__main__':data_file?=?"../data/ml-1m/"Data?=?loadData(data_file)dataTrain,?labelTrain,?dataTest,?labelTest?=?preprocessData(Data,?0.8)date_startTrain?=?datetime.now()print("開始訓(xùn)練")w_0,?w,?v?=?FM(mat(dataTrain),?labelTrain,?4,?100,?0.001)print("w_0:",?w_0)print("w:",?w)print("v:",?v)predict_train_result?=?getPrediction(mat(dataTrain),?w_0,?w,?v)??#?得到訓(xùn)練的準(zhǔn)確性print("訓(xùn)練準(zhǔn)確性為:%f"?%?(1?-?getAccuracy(predict_train_result,?labelTrain)))date_endTrain?=?datetime.now()print("訓(xùn)練用時(shí)為:%s"?%?(date_endTrain?-?date_startTrain))print("開始測試")predict_test_result?=?getPrediction(mat(dataTest),?w_0,?w,?v)??#?得到訓(xùn)練的準(zhǔn)確性print("測試準(zhǔn)確性為:%f"?%?(1?-?getAccuracy(predict_test_result,?labelTest)))最終的訓(xùn)練結(jié)果如下圖
使用tensorflow做召回的代碼:鏈接
6. 參考
1.Factorization Machines
2. Factorization Machines 學(xué)習(xí)筆記
3. 推薦系統(tǒng)召回四模型之:全能的FM模型
4. FM因子分解機(jī)的原理、公式推導(dǎo)、python實(shí)現(xiàn)和應(yīng)用
5.深入FFM原理與實(shí)戰(zhàn)
6.Factorization Machines
7.FM推薦算法中的瑞士軍刀
8.從矩陣分解到FM的演進(jìn)
9.推薦算法中的倚天劍: FM (tensorflow2實(shí)現(xiàn))
往期精彩回顧適合初學(xué)者入門人工智能的路線及資料下載機(jī)器學(xué)習(xí)及深度學(xué)習(xí)筆記等資料打印機(jī)器學(xué)習(xí)在線手冊(cè)深度學(xué)習(xí)筆記專輯《統(tǒng)計(jì)學(xué)習(xí)方法》的代碼復(fù)現(xiàn)專輯 AI基礎(chǔ)下載黃海廣老師《機(jī)器學(xué)習(xí)課程》視頻課黃海廣老師《機(jī)器學(xué)習(xí)課程》711頁完整版課件
本站qq群955171419,加入微信群請(qǐng)掃碼:
總結(jié)
以上是生活随笔為你收集整理的【机器学习】因子分解机(FM) 原理及在召回中的应用(python实现)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 获取java 私有属性或 方法
- 下一篇: 【Python合集】全面掌握Python