简单易学的机器学习算法——因子分解机(Factorization Machine)
时间:2022-05-04
本文章向大家介绍简单易学的机器学习算法——因子分解机(Factorization Machine),主要内容包括一、因子分解机FM的模型、2、因子分解机FM的模型、二、因子分解机FM算法、三、因子分解机FM算法的求解过程、2、模型的求解、3、基于随机梯度的方式求解、四、实验(求解二分类问题)、2、实验结果:、五、几点疑问、参考文章、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
一、因子分解机FM的模型
因子分解机(Factorization Machine, FM)是由Steffen Rendle提出的一种基于矩阵分解的机器学习算法。
1、因子分解机FM的优势
对于因子分解机FM来说,最大的特点是对于稀疏的数据具有很好的学习能力。现实中稀疏的数据很多,例如作者所举的推荐系统的例子便是一个很直观的具有稀疏特点的例子。
2、因子分解机FM的模型
二、因子分解机FM算法
因子分解机FM算法可以处理如下三类问题:
- 回归问题(Regression)
- 二分类问题(Binary Classification)
- 排序(Ranking)
在这里主要介绍回归问题和二分类问题。
三、因子分解机FM算法的求解过程
1、交叉项系数
2、模型的求解
这里要求出
主要采用了如公式
求出交叉项。具体过程如下:
3、基于随机梯度的方式求解
对于回归问题:
对于二分类问题:
而
四、实验(求解二分类问题)
1、实验的代码:
#coding:UTF-8
from __future__ import division
from math import exp
from numpy import *
from random import normalvariate#正态分布
from datetime import datetime
trainData = 'E://data//diabetes_train.txt'
testData = 'E://data//diabetes_test.txt'
featureNum = 8
def loadDataSet(data):
dataMat = []
labelMat = []
fr = open(data)#打开文件
for line in fr.readlines():
currLine = line.strip().split()
#lineArr = [1.0]
lineArr = []
for i in xrange(featureNum):
lineArr.append(float(currLine[i + 1]))
dataMat.append(lineArr)
labelMat.append(float(currLine[0]) * 2 - 1)
return dataMat, labelMat
def sigmoid(inx):
return 1.0 / (1 + exp(-inx))
def stocGradAscent(dataMatrix, classLabels, k, iter):
#dataMatrix用的是mat, classLabels是列表
m, n = shape(dataMatrix)
alpha = 0.01
#初始化参数
w = zeros((n, 1))#其中n是特征的个数
w_0 = 0.
v = normalvariate(0, 0.2) * ones((n, k))
for it in xrange(iter):
print it
for x in xrange(m):#随机优化,对每一个样本而言的
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#计算预测的输出
loss = sigmoid(classLabels[x] * p[0, 0]) - 1
print loss
w_0 = w_0 - alpha * loss * classLabels[x]
for i in xrange(n):
if dataMatrix[x, i] != 0:
w[i, 0] = w[i, 0] - alpha * loss * classLabels[x] * dataMatrix[x, i]
for j in xrange(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])
return w_0, w, v
def getAccuracy(dataMatrix, classLabels, w_0, w, v):
m, n = shape(dataMatrix)
allItem = 0
error = 0
result = []
for x in xrange(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 = 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
return float(error) / allItem
if __name__ == '__main__':
dataTrain, labelTrain = loadDataSet(trainData)
dataTest, labelTest = loadDataSet(testData)
date_startTrain = datetime.now()
print "开始训练"
w_0, w, v = stocGradAscent(mat(dataTrain), labelTrain, 20, 200)
print "训练准确性为:%f" % (1 - getAccuracy(mat(dataTrain), labelTrain, w_0, w, v))
date_endTrain = datetime.now()
print "训练时间为:%s" % (date_endTrain - date_startTrain)
print "开始测试"
print "测试准确性为:%f" % (1 - getAccuracy(mat(dataTest), labelTest, w_0, w, v))
2、实验结果:
五、几点疑问
在传统的非稀疏数据集上,有时效果并不是很好。在实验中,我有一点处理,即在求解Sigmoid函数的过程中,在有的数据集上使用了带阈值的求法:
def sigmoid(inx):
#return 1.0 / (1 + exp(-inx))
return 1. / (1. + exp(-max(min(inx, 15.), -15.)))
欢迎更多的朋友一起讨论这个算法。
参考文章
1、Rendle, Factorization Machines.
2、Factorization Machines with libFM
- Python-面向对像及其他
- 基于MongoDB GridFS的图片存储
- css3 过渡和2d变换——回顾
- Microsoft 防跨站点脚本库AntiXSS Library v4.2.1
- Compilify——让你在浏览器中编译.NET代码
- Python进阶-面向对象
- WCF RESTful服务的Google Protocol Buffers超媒体类型
- 使用CoreOs,Docker和Nirmata部署微服务类型的应用
- .NET 4 上的REST 框架
- 结合游戏开发与人工智能研究,游戏大厂 Ubisoft 成立AI研发部门
- Quartz.NET的管理工具
- Python-执行系统命令
- css3 UI 修饰——回顾
- Windows Phone 7实战 第一天 设计启动页面和应用程序图标
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 服务器性能监控神器nmon使用介绍
- makefile从入门到入门
- 服务器如何同步网络时间
- 用Bi-GRU语义解析,实现中文人物关系分析
- 控制梦境
- 引号吃掉了我的数据~~~
- 每日一题 | 召唤兽问题
- WMI ——重写版
- LeetCode009|只出现一次的数字
- 丢弃掉那些 BeanUtils 工具类吧,MapStruct 是真香!!!
- 还在「黑盒炼丹」? 教你如何实现一行代码透视炼丹过程
- SpringCloud Alibaba微服务实战十九 - 集成RBAC授权
- 混合算法(GA+TS)求解作业车间调度问题(JSP)-禁忌搜索部分
- 打卡群刷题总结0810——从前序与中序遍历序列构造二叉树
- JavaScript性能优化