Factorization Machine---因子分解機(jī)
①target function的推導(dǎo)
logistics regression algorithm model中使用的是特征的線性組合捞魁,最終得到的分割平面屬于線性模型局骤,但是線性模型就只能處理線性問(wèn)題惋鸥,所以對(duì)于非線性的問(wèn)題就有點(diǎn)難處理了银受,對(duì)于這些復(fù)雜問(wèn)題一般是兩種解決方法①對(duì)數(shù)據(jù)本身進(jìn)行處理妆绞,比如進(jìn)行特征轉(zhuǎn)換收捣,和函數(shù)高維擴(kuò)展等等陨收。②對(duì)算法模型本身進(jìn)行擴(kuò)展势告,比如對(duì)linear regression加上正則化懲罰項(xiàng)進(jìn)行改進(jìn)得到lasso regression或者是ridge regression岸啡。
Factorization Machine就是一種對(duì)logistics regression的一種改進(jìn)原叮,線性的部分權(quán)值組合是不變的,在后面增加了非線性的交叉項(xiàng)巡蘸。
target function:
表示的是系數(shù)矩陣V的第i維向量奋隶,
,k的大小稱為是度悦荒,度越大代表分解出來(lái)的特征就越多唯欣。對(duì)于每一個(gè)特征都會(huì)對(duì)應(yīng)有一個(gè)
維的向量。前兩部分是傳統(tǒng)的線性模型搬味,后一個(gè)部分就是將臉剛剛互不相同的特征分量之間的相互關(guān)系考慮進(jìn)來(lái)了境氢。也就是不同特征之間的吸引程度。
如果使用男女戀愛(ài)來(lái)解釋這個(gè)模型碰纬,得分score是男生對(duì)女生的一個(gè)喜歡程度萍聊,代表的就是底分,可以看成是男生對(duì)于女生的第一感覺(jué)悦析。對(duì)于第二部分可以看成是女生的優(yōu)秀程度寿桨,第三部分就相當(dāng)于是男女之間的事交互關(guān)系了,也就是男女之間的感覺(jué)她按,如果兩個(gè)男生對(duì)于同一個(gè)女生的感覺(jué)是一致的牛隅,那么他們的
就是一致的,從本質(zhì)上說(shuō)酌泰,因子分解機(jī)也是探索一種相似性媒佣,其與協(xié)同過(guò)濾算法是類似的,但是這兩者的區(qū)別在于陵刹,因子分解機(jī)同時(shí)考慮了男生和男生間的相似性以及女生和女生間的相似性默伍,但是協(xié)同過(guò)濾要么只考慮男生之間的相似性,要么只考慮女生之間的相似性衰琐。
優(yōu)化求解target function
對(duì)于原始的target function計(jì)算復(fù)雜度是
也糊,采用公式
的公式。于是化簡(jiǎn)一波:
這樣就成功的把復(fù)雜度降到了
FM可以解決的問(wèn)題主要是四種:
1.回歸問(wèn)題:這時(shí)候的error function:
2.二分類問(wèn)題:
3.排序問(wèn)題羡宙。
4,推薦系統(tǒng)狸剃。
接下來(lái)就是模型的求解,自然就是求導(dǎo)了狗热,我們做的是二分類問(wèn)題钞馁,所以采用的就是第二種loss function求導(dǎo),按照求導(dǎo)常規(guī)求取即可:
Factorization Machine的優(yōu)點(diǎn)
①對(duì)于一些很稀疏的數(shù)據(jù)集也可以進(jìn)行參數(shù)的預(yù)測(cè)匿刮,而SVM是不行的僧凰。
②FM有線性的復(fù)雜性,可以直接在原始數(shù)據(jù)進(jìn)行預(yù)測(cè)熟丸,而不需要再做核函數(shù)或者特征轉(zhuǎn)換训措,對(duì)于SVM,是要基于對(duì)支持向量的優(yōu)化的光羞。
③FMs是一種通用的預(yù)測(cè)器绩鸣,可用于任何實(shí)值特征向量。相比之下狞山。其他最先進(jìn)的因數(shù)分解模型只在非常有限的輸入數(shù)據(jù)上工作全闷。通過(guò)定義輸入數(shù)據(jù)的特征向量,F(xiàn)Ms可以模擬最先進(jìn)的模型萍启,如偏置MF总珠、SVD++、PITF或FPMC勘纯。
K的選擇
如果數(shù)據(jù)是一個(gè)稀疏矩陣局服,那么可以選擇一個(gè)比較小的k,因?yàn)橄∈杈仃嚻鋵?shí)就已經(jīng)表明這個(gè)矩陣的信息是十分有限的了驳遵,再取比較大的k可能會(huì)導(dǎo)致過(guò)擬合淫奔。如果數(shù)據(jù)并不是一個(gè)稀疏矩陣,可以選擇大一點(diǎn)的k來(lái)代表數(shù)據(jù)堤结。
代碼實(shí)現(xiàn)
主要部分的代碼:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from loadDataSet import loadData
def Accuracy(preiction, classlabel):
score = 0
for i in range(len(preiction)):
if preiction[i] > 0.5:
preiction[i] = 1
else:
preiction[i] = -1
if preiction[i] == classlabel[i]:
score += 1
print('Accuracy: ', score/len(preiction))
def initialize(n, k):
v = np.mat(np.zeros((n, k)))
for i in range(n):
for j in range(k):
v[i, j] = np.random.normal(0, 0.2)
return v
def sigmoid(inx):
return 1.0/(1+np.exp(-inx))
def getCost(predict, classLabels):
m = len(predict)
error = 0.0
for i in range(m):
error -= np.log(sigmoid(predict[i]*classLabels[i]))
return error
def getPrediction(dataMatrix, w0, w, v):
m = np.shape(dataMatrix)[0]
result = []
for x in range(m):
inter_1 = dataMatrix[x] * v
inter_2 = np.multiply(dataMatrix[x], dataMatrix[x]) * np.multiply(v, v)
interaction = np.sum(np.multiply(inter_1, inter_1) - inter_2) / 2
p = w0 + dataMatrix[x] * w + interaction
pre = sigmoid(p[0, 0])
result.append(pre)
return result
def stocGradAscent(dataMatrix, classLabels, k, max_iter, alpha):
#initialize parameters
m, n = np.shape(dataMatrix)
w = np.zeros((n, 1))
w0 = 0
v = initialize(n, k)
#training
for it in range(max_iter):
for x in range(m):
inter_1 = dataMatrix[x] * v
inter_2 = np.multiply(dataMatrix[x], dataMatrix[x])*np.multiply(v, v)
interaction = np.sum(np.multiply(inter_1, inter_1) - inter_2)/2
p = w0 + dataMatrix[x]*w + interaction
loss = sigmoid(classLabels[x] * p[0, 0]) - 1
w0 = w0 - alpha*loss*classLabels[x]
for i in range(n):
if dataMatrix[x, i] != 0:
w[i, 0] = w[i, 0] - alpha*loss*classLabels[x]*dataMatrix[x, i]
for j in range(k):
v[i, j] = v[i, j] - alpha*loss*classLabels[x]*(dataMatrix[x, i]*inter_1[0, j]-v[i, j]*dataMatrix[x, i]*dataMatrix[x, i])
if it % 1000 == 0:
print('-----iter: ', it, ', cost: ', getCost(getPrediction(np.mat(dataMatrix), w0, w, v), classLabels))
Accuracy(getPrediction(np.mat(dataMatrix), w0, w, v), classLabels)
if __name__ == '__main__':
dataMatrix, target = loadData('../Data/testSetRBF2.txt')
stocGradAscent(dataMatrix, target, 5, 5000, 0.01)
準(zhǔn)備數(shù)據(jù)部分:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def loadData(filename):
df = pd.read_csv(filename, sep=' ', names=['1', '2', 'target'])
data = []
target = []
for i in range(len(df)):
d = df.iloc[i]
ds = [d['1'], d['2']]
t = int(d['target'])
if t == 0:
t = -1
data.append(ds)
target.append(t)
return np.mat(data), np.mat(target).tolist()[0]
if __name__ == '__main__':
dataMatrix, target = loadData('../Data/testSetRBF2.txt')
print(dataMatrix)
print(target)
最后附上GitHub代碼:
https://github.com/GreenArrow2017/MachineLearning/tree/master/MachineLearning/Factorization%20Machine