天天看點

Factorization MachineFactorization Machine---因子分解機

Factorization Machine---因子分解機

①target function的推導

logistics regression algorithm model中使用的是特征的線性組合,最終得到的分割平面屬于線性模型,但是線性模型就隻能處理線性問題,是以對于非線性的問題就有點難處理了,對于這些複雜問題一般是兩種解決方法①對資料本身進行處理,比如進行特征轉換,和函數高維擴充等等。②對算法模型本身進行擴充,比如對linear regression加上正則化懲罰項進行改進得到lasso regression或者是ridge regression。

Factorization Machine就是一種對logistics regression的一種改進,線性的部分權值組合是不變的,在後面增加了非線性的交叉項。

target function:

Factorization MachineFactorization Machine---因子分解機
Factorization MachineFactorization Machine---因子分解機
Factorization MachineFactorization Machine---因子分解機

表示的是系數矩陣V的第i維向量,

Factorization MachineFactorization Machine---因子分解機

,k的大小稱為是度,度越大代表分解出來的特征就越多。對于每一個特征都會對應有一個

Factorization MachineFactorization Machine---因子分解機

維的向量。前兩部分是傳統的線性模型,後一個部分就是将臉剛剛互不相同的特征分量之間的互相關系考慮進來了。也就是不同特征之間的吸引程度。

如果使用男女戀愛來解釋這個模型,得分score是男生對女生的一個喜歡程度,

Factorization MachineFactorization Machine---因子分解機

代表的就是底分,可以看成是男生對于女生的第一感覺。對于第二部分可以看成是女生的優秀程度,第三部分就相當于是男女之間的事互動關系了,也就是男女之間的感覺,如果兩個男生對于同一個女生的感覺是一緻的,那麼他們的

Factorization MachineFactorization Machine---因子分解機

就是一緻的,從本質上說,因子分解機也是探索一種相似性,其與協同過濾算法是類似的,但是這兩者的差別在于,因子分解機同時考慮了男生和男生間的相似性以及女生和女生間的相似性,但是協同過濾要麼隻考慮男生之間的相似性,要麼隻考慮女生之間的相似性。

優化求解target function

Factorization MachineFactorization Machine---因子分解機
Factorization MachineFactorization Machine---因子分解機

對于原始的target function計算複雜度是

Factorization MachineFactorization Machine---因子分解機

,采用公式

Factorization MachineFactorization Machine---因子分解機

的公式。于是化簡一波:

Factorization MachineFactorization Machine---因子分解機

這樣就成功的把複雜度降到了

Factorization MachineFactorization Machine---因子分解機

FM可以解決的問題主要是四種:

1.回歸問題:這時候的error function:

Factorization MachineFactorization Machine---因子分解機

2.二分類問題:

Factorization MachineFactorization Machine---因子分解機

3.排序問題。

4,推薦系統。

接下來就是模型的求解,自然就是求導了,我們做的是二分類問題,是以采用的就是第二種loss function求導,按照求導正常求取即可:

Factorization MachineFactorization Machine---因子分解機
Factorization MachineFactorization Machine---因子分解機
Factorization MachineFactorization Machine---因子分解機

Factorization Machine的優點

①對于一些很稀疏的資料集也可以進行參數的預測,而SVM是不行的。

②FM有線性的複雜性,可以直接在原始資料進行預測,而不需要再做核函數或者特征轉換,對于SVM,是要基于對支援向量的優化的。

③FMs是一種通用的預測器,可用于任何實值特征向量。相比之下。其他最先進的因數分解模型隻在非常有限的輸入資料上工作。通過定義輸入資料的特征向量,FMs可以模拟最先進的模型,如偏置MF、SVD++、PITF或FPMC。

K的選擇

如果資料是一個稀疏矩陣,那麼可以選擇一個比較小的k,因為稀疏矩陣其實就已經表明這個矩陣的資訊是十分有限的了,再取比較大的k可能會導緻過拟合。如果資料并不是一個稀疏矩陣,可以選擇大一點的k來代表資料。

代碼實作

主要部分的代碼:

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)

           

準備資料部分:

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)
           
Factorization MachineFactorization Machine---因子分解機
最後附上GitHub代碼: https://github.com/GreenArrow2017/MachineLearning/tree/master/MachineLearning/Factorization%20Machine