接觸fm方法時間也算是很久了,雖然沒有持續在上面做非常深入的研究,但是做的幾個專案中,多次使用後也算是也算是業餘玩家中的高階玩家了。在前期的乙個專案中深入的參與了spark中的als推薦模型(其實本質是fm,als是指其中最優化的演算法),其中主要參與解決的問題就是增量推薦(場景中是解決新使用者的推薦問題),其中具體的思路就是固定住物品矩陣單獨訓練每個使用者的評分內容,具體就不贅述。但是該方法效率非常慢~(測試中一秒只能處理10個人左右,億級別的使用者還是太慢了)。而在近期又遇到了類似問題,偶然得到乙個解決的辦法,做個分享。
之所以增量演算法部分很慢,其本質原因是對於每乙個新使用者的推薦過程仍然是乙個小的train過程。只要避開這個過程該演算法就會很快了。
俗語約定:
1. 使用者評分矩陣 : s 原始的使用者資訊
2. 使用者因子矩陣 : u 壓縮的使用者資訊
3. 解碼矩陣 : p 即原本的product矩陣 ,滿足 u*p=s
4. 編碼矩陣 : e 新引入的矩陣,滿足 s * e = u
原有的推薦過程是 u*p 的結果進行排序過濾等操作後直接推薦(u矩陣式和使用者有關),而現在是 s* e*p 的結果進行排序過濾等操作後直接推薦。訓練完成後e矩陣和p矩陣都是和使用者無關的矩陣,因此直接避免了後續的新使用者不在u矩陣時需要train的問題,而e 矩陣和 p 矩陣也不需要重新訓練。
該方法並不是憑空而來的,一方面是基於之前我對fm一些基礎知識的理解,另一方面也是近期又看到深度學習中的自編碼器,兩者結合起來就想到了該方法(其實在fm的增量算方法之前我就是知道自編碼器的,但是在做fm增量演算法時卻是沒有想到這一層,上面之所以重新定義矩陣的名稱也是為了和自編碼器模擬)。
至於怎麼去得到這個矩陣e和矩陣p,這裡也給個簡單易行的思路:
1. 先根據s = u*p 進行訓練得到 u 和 p ;
2. 再根據 u = s*e 進行train得到 e;
理論上是最好根據 s = s*e*p來同時求解e,p矩陣(複雜會較之前大大增加),但是考慮到第二個等式中兩個未知量不是乘法關係而第乙個等式是乘法關係,因此感覺這種粗糙的方法也會有乙個很好的近似解。
仔細想過之後發現e矩陣其實就是p矩陣的偽逆。
主線1 2FM演算法的Python實現
演算法原理部分可以檢視部落格主線1.1fm演算法原理詳解 coding utf 8 from future import division from math import exp from numpy import from random import normalvariate 正態分佈 fro...
最小覆蓋圓的增量演算法
題意 給出平面上的一些點,要求用乙個最小的圓,把所有的點包圍起來。最小覆蓋圓,增量法 假設圓o是前i 1個點得最小覆蓋圓,加入第i個點,如果在圓內或邊上則什麼也不做。否,新得到的最小覆蓋圓肯定經過第i個點。然後以第i個點為基礎 半徑為0 重複以上過程依次加入第j個點,若第j個點在圓外,則最小覆蓋圓必...
Pid控制演算法 增量型pid演算法的C 實現
上一節中介紹了最簡單的位置型pid的實現手段,這一節主要講解增量式pid的實現方法.實現過程仍然是分為定義變數 初始化變數 實現控制演算法函式 演算法測試四個部分,這裡直接給出 了。pid.h ifndef pid h define pid h typedef struct pidpid class...