FM演算法python實現
我們需要注意以下四點:
1. 初始化引數,包括對偏置項權值w0、一次項權值w以及交叉項輔助向量的初始化;
2. 定義FM演算法;
3. 損失函式梯度的定義;
4. 利用梯度下降更新引數。
下面的程式碼片段是以上四點的描述,其中的loss並不是二分類的損失loss,而是分類loss的梯度中的一部分:
loss = self.sigmoid(classLabels[x] * p[0, 0]) -1
實際上,二分類的損失loss的梯度可以表示為:
gradient = (self.sigmoid(classLabels[x] * p[0, 0]) -1)*classLabels[x]*p_derivative
其中 p_derivative 代表常數項、一次項、交叉項的導數
# -*- coding: utf-8 -*-
from __future__ import division
from math import exp
from numpy import *
from random import normalvariate # 正態分佈
from sklearn import preprocessing
import numpy as np
'''
data : 資料的路徑
feature_potenital : 潛在分解維度數
alpha : 學習速率
iter : 迭代次數
_w,_w_0,_v : 拆分子矩陣的weight
with_col : 是否帶有columns_name
first_col : 首列有價值的feature的index
'''
class fm(object):
def __init__(self):
self.data = None
self.feature_potential = None
self.alpha = None
self.iter = None
self._w = None
self._w_0 = None
self.v = None
self.with_col = None
self.first_col = None
def min_max(self, data):
self.data = data
min_max_scaler = preprocessing.MinMaxScaler()
return min_max_scaler.fit_transform(self.data)
def loadDataSet(self, data, with_col=True, first_col=2):
# 我就是閒的蛋疼,明明pd.read_table()可以直接度,非要搞這樣的,顯得程式碼很長,小資料下完全可以直接讀嘛,唉~
self.first_col = first_col
dataMat = []
labelMat = []
fr = open(data)
self.with_col = with_col
if self.with_col:
N = 0
for line in fr.readlines():
# N=1時幹掉列表名
if N > 0:
currLine = line.strip().split()
lineArr = []
featureNum = len(currLine)
for i in range(self.first_col, featureNum):
lineArr.append(float(currLine[i]))
dataMat.append(lineArr)
labelMat.append(float(currLine[1]) * 2 - 1)
N = N + 1
else:
for line in fr.readlines():
currLine = line.strip().split()
lineArr = []
featureNum = len(currLine)
for i in range(2, featureNum):
lineArr.append(float(currLine[i]))
dataMat.append(lineArr)
labelMat.append(float(currLine[1]) * 2 - 1)
return mat(self.min_max(dataMat)), labelMat
def sigmoid(self, inx):
# return 1.0/(1+exp(min(max(-inx,-10),10)))
return 1.0 / (1 + exp(-inx))
# 得到對應的特徵weight的矩陣
def fit(self, data, feature_potential=8, alpha=0.01, iter=100):
# alpha是學習速率
self.alpha = alpha
self.feature_potential = feature_potential
self.iter = iter
# dataMatrix用的是mat, classLabels是列表
dataMatrix, classLabels = self.loadDataSet(data)
print('dataMatrix:',dataMatrix.shape)
print('classLabels:',classLabels)
k = self.feature_potential
m, n = shape(dataMatrix)
# 初始化引數
w = zeros((n, 1)) # 其中n是特徵的個數
w_0 = 0.
v = normalvariate(0, 0.2) * ones((n, k))
for it in range(self.iter): # 迭代次數
# 對每一個樣本,優化
for x in range(m):
# 這邊注意一個數學知識:對應點積的地方通常會有sum,對應位置積的地方通常都沒有,詳細參見矩陣運算規則,本處計算邏輯在:http://blog.csdn.net/google19890102/article/details/45532745
# xi·vi,xi與vi的矩陣點積
inter_1 = dataMatrix[x] * v
# xi與xi的對應位置乘積 與 xi^2與vi^2對應位置的乘積 的點積
inter_2 = multiply(dataMatrix[x], dataMatrix[x]) * multiply(v, v) # multiply對應元素相乘
# 完成交叉項,xi*vi*xi*vi - xi^2*vi^2
interaction = sum(multiply(inter_1, inter_1) - inter_2) / 2.
# 計算預測的輸出
p = w_0 + dataMatrix[x] * w + interaction
print('classLabels[x]:',classLabels[x])
print('預測的輸出p:', p)
# 計算sigmoid(y*pred_y)-1
loss = self.sigmoid(classLabels[x] * p[0, 0]) - 1
if loss >= -1:
loss_res = '正方向 '
else:
loss_res = '反方向'
# 更新引數
w_0 = w_0 - self.alpha * loss * classLabels[x]
for i in range(n):
if dataMatrix[x, i] != 0:
w[i, 0] = w[i, 0] - self.alpha * loss * classLabels[x] * dataMatrix[x, i]
for j in range(k):
v[i, j] = v[i, j] - self.alpha * loss * classLabels[x] * (
dataMatrix[x, i] * inter_1[0, j] - v[i, j] * dataMatrix[x, i] * dataMatrix[x, i])
print('the no %s times, the loss arrach %s' % (it, loss_res))
self._w_0, self._w, self._v = w_0, w, v
def predict(self, X):
if (self._w_0 == None) or (self._w == None).any() or (self._v == None).any():
raise NotFittedError("Estimator not fitted, call `fit` first")
# 型別檢查
if isinstance(X, np.ndarray):
pass
else:
try:
X = np.array(X)
except:
raise TypeError("numpy.ndarray required for X")
w_0 = self._w_0
w = self._w
v = self._v
m, n = shape(X)
result = []
for x in range(m):
inter_1 = mat(X[x]) * v
inter_2 = mat(multiply(X[x], X[x])) * multiply(v, v) # multiply對應元素相乘
# 完成交叉項
interaction = sum(multiply(inter_1, inter_1) - inter_2) / 2.
p = w_0 + X[x] * w + interaction # 計算預測的輸出
pre = self.sigmoid(p[0, 0])
result.append(pre)
return result
def getAccuracy(self, data):
dataMatrix, classLabels = self.loadDataSet(data)
w_0 = self._w_0
w = self._w
v = self._v
m, n = shape(dataMatrix)
allItem = 0
error = 0
result = []
for x in range(m):
allItem += 1
inter_1 = dataMatrix[x] * v
inter_2 = multiply(dataMatrix[x], dataMatrix[x]) * multiply(v, v) # multiply對應元素相乘
# 完成交叉項
interaction = sum(multiply(inter_1, inter_1) - inter_2) / 2.
p = w_0 + dataMatrix[x] * w + interaction # 計算預測的輸出
pre = self.sigmoid(p[0, 0])
result.append(pre)
if pre < 0.5 and classLabels[x] == 1.0:
error += 1
elif pre >= 0.5 and classLabels[x] == -1.0:
error += 1
else:
continue
# print(result)
value = 1 - float(error) / allItem
return value
class NotFittedError(Exception):
"""
Exception class to raise if estimator is used before fitting
"""
pass
if __name__ == '__main__':
fm()
相關文章
- python實現FM演算法Python演算法
- python實現douban.fm簡易客戶端Python客戶端
- 一文讀懂FM演算法優勢,並用python實現!(附程式碼)演算法Python
- 4.【Python】分類演算法—Factorization Machine(FM,因子分解機)Python演算法Mac
- python實現冒泡演算法Python演算法
- PYTHON實現DFS演算法Python演算法
- python實現Floyd演算法Python演算法
- Python實現KNN演算法PythonKNN演算法
- python實現希爾排序演算法Python排序演算法
- RSA演算法與Python實現演算法Python
- python演算法 - python實現氣泡排序Python演算法排序
- 常見排序演算法-Python實現排序演算法Python
- 基本排序演算法的Python實現排序演算法Python
- “猴子選大王” 演算法 python實現演算法Python
- python排序演算法的實現-冒泡Python排序演算法
- python排序演算法的實現-插入Python排序演算法
- FP-Growth演算法python實現演算法Python
- PageRank演算法概述與Python實現演算法Python
- k近鄰演算法python實現 -- 《機器學習實戰》演算法Python機器學習
- 用Python實現約瑟夫環演算法Python演算法
- 模擬退火演算法(1)Python 實現演算法Python
- python實現常用五種排序演算法Python排序演算法
- 機器學習之kNN演算法(純python實現)機器學習KNN演算法Python
- 蟻群演算法原理及其實現(python)演算法Python
- Python實現常見機器學習演算法(上)Python機器學習演算法
- 用 python 實現各種排序演算法Python排序演算法
- python排序演算法的實現-選擇Python排序演算法
- python排序演算法的實現-快速排序Python排序演算法
- python實現:目標優化演算法——遺傳演算法Python優化演算法
- [譯]使用 Python 實現接縫裁剪演算法Python演算法
- 排序演算法原理總結和Python實現排序演算法Python
- CART演算法解密:從原理到Python實現演算法解密Python
- 目標匹配:匈牙利演算法的python實現演算法Python
- 曲線點抽稀演算法- Python 實現演算法Python
- 八大排序演算法python實現排序演算法Python
- 用Python實現K-近鄰演算法Python演算法
- 機器學習10種經典演算法的Python實現機器學習演算法Python
- python實現常見的五種排序演算法Python排序演算法