3.2、Factorization Machine实践
1、在上一篇博客中我们构建度为二的因子分解机模型,这篇博客对这个模型进行实践
下图为准备的数据集:
完整代码为:
# -*- coding: UTF-8 -*-
# date:2018/6/6
# User:WangHong
import numpy as np
from random import normalvariate # 正态分布 def loadDataSet(data):
'''导入训练数据
input: data(string)训练数据
output: dataMat(list)特征
labelMat(list)标签
'''
dataMat = []
labelMat = []
fr = open(data) # 打开文件
for line in fr.readlines():
lines = line.strip().split("\t")
lineArr = [] for i in range(len(lines) - 1):
lineArr.append(float(lines[i]))
dataMat.append(lineArr) labelMat.append(float(lines[-1]) * 2 - 1) # 转换成{-1,1}
fr.close()
return dataMat, labelMat def sigmoid(inx):
return 1.0 / (1 + np.exp(-inx)) def initialize_v(n, k):
'''初始化交叉项
input: n(int)特征的个数
k(int)FM模型的超参数
output: v(mat):交叉项的系数权重
'''
v = np.mat(np.zeros((n, k))) for i in range(n):
for j in range(k):
# 利用正态分布生成每一个权重
v[i, j] = normalvariate(0, 0.2)
return v def stocGradAscent(dataMatrix, classLabels, k, max_iter, alpha):
'''利用随机梯度下降法训练FM模型
input: dataMatrix(mat)特征
classLabels(mat)标签
k(int)v的维数
max_iter(int)最大迭代次数
alpha(float)学习率
output: w0(float),w(mat),v(mat):权重
'''
m, n = np.shape(dataMatrix)
# 1、初始化参数
w = np.zeros((n, 1)) # 其中n是特征的个数
w0 = 0 # 偏置项
v = initialize_v(n, k) # 初始化V # 2、训练
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) # multiply对应元素相乘
# 完成交叉项
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 ("\t------- iter: ", it, " , cost: ", \
getCost(getPrediction(np.mat(dataMatrix), w0, w, v), classLabels)) # 3、返回最终的FM模型的参数
return w0, w, v def getCost(predict, classLabels):
'''计算预测准确性
input: predict(list)预测值
classLabels(list)标签
output: error(float)计算损失函数的值
'''
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):
'''得到预测值
input: dataMatrix(mat)特征
w(int)常数项权重
w0(int)一次项权重
v(float)交叉项权重
output: result(list)预测的结果
'''
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) # multiply对应元素相乘
# 完成交叉项
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 getAccuracy(predict, classLabels):
'''计算预测准确性
input: predict(list)预测值
classLabels(list)标签
output: float(error) / allItem(float)错误率
'''
m = len(predict)
allItem = 0
error = 0
for i in range(m):
allItem += 1
if float(predict[i]) < 0.5 and classLabels[i] == 1.0:
error += 1
elif float(predict[i]) >= 0.5 and classLabels[i] == -1.0:
error += 1
else:
continue
return float(error) / allItem def save_model(file_name, w0, w, v):
'''保存训练好的FM模型
input: file_name(string):保存的文件名
w0(float):偏置项
w(mat):一次项的权重
v(mat):交叉项的权重
'''
f = open(file_name, "w")
# 1、保存w0
f.write(str(w0) + "\n")
# 2、保存一次项的权重
w_array = []
m = np.shape(w)[0]
for i in range(m):
w_array.append(str(w[i, 0]))
f.write("\t".join(w_array) + "\n")
# 3、保存交叉项的权重
m1 , n1 = np.shape(v)
for i in range(m1):
v_tmp = []
for j in range(n1):
v_tmp.append(str(v[i, j]))
f.write("\t".join(v_tmp) + "\n")
f.close() if __name__ == "__main__":
# 1、导入训练数据
print ("---------- 1.load data ---------")
dataTrain, labelTrain = loadDataSet("data_1.txt")
print( "---------- 2.learning ---------")
# 2、利用随机梯度训练FM模型
w0, w, v = stocGradAscent(np.mat(dataTrain), labelTrain, 3, 10000, 0.01)
predict_result = getPrediction(np.mat(dataTrain), w0, w, v) # 得到训练的准确性
print( "----------training accuracy: %f" % (1 - getAccuracy(predict_result, labelTrain)))
print ("---------- 3.save result ---------")
# 3、保存训练好的FM模型
save_model("weights", w0, w, v)
最终训练过程为:
训练的过程比较慢,我用来将近有一分半
得到的权值文件为:
最终分隔得到的超平面为:
2、对新的数据进行预测:
预测的全部代码为:
# -*- coding: UTF-8 -*-
# date:2018/6/6
# User:WangHong import numpy as np from FM_train import getPrediction def loadDataSet(data):
'''导入测试数据集
input: data(string)测试数据
output: dataMat(list)特征
'''
dataMat = []
fr = open(data) # 打开文件
for line in fr.readlines():
lines = line.strip().split("\t")
lineArr = [] for i in range(len(lines)):
lineArr.append(float(lines[i]))
dataMat.append(lineArr) fr.close()
return dataMat def loadModel(model_file):
'''导入FM模型
input: model_file(string)FM模型
output: w0, np.mat(w).T, np.mat(v)FM模型的参数
'''
f = open(model_file)
line_index = 0
w0 = 0.0
w = []
v = []
for line in f.readlines():
lines = line.strip().split("\t")
if line_index == 0: # w0
w0 = float(lines[0].strip())
elif line_index == 1: # w
for x in lines:
w.append(float(x.strip()))
else:
v_tmp = []
for x in lines:
v_tmp.append(float(x.strip()))
v.append(v_tmp)
line_index += 1
f.close()
return w0, np.mat(w).T, np.mat(v) def save_result(file_name, result):
'''保存最终的预测结果
input: file_name(string)需要保存的文件名
result(mat):对测试数据的预测结果
'''
f = open(file_name, "w")
f.write("\n".join(str(x) for x in result))
f.close() if __name__ == "__main__":
# 1、导入测试数据
dataTest = loadDataSet("test_data.txt")
# 2、导入FM模型
w0, w , v = loadModel("weights")
# 3、预测
result = getPrediction(dataTest, w0, w, v)
# 4、保存最终的预测结果
save_result("predict_result", result)
最终测试结果得到一个predict_result.txt文件
3.2、Factorization Machine实践的更多相关文章
- Factorization Machine因子分解机
隐因子分解机Factorization Machine[http://www. w2bc. com/article/113916] https://my.oschina.net/keyven/blog ...
- Factorization Machine
Factorization Machine Model 如果仅考虑两个样本间的交互, 则factorization machine的公式为: $\hat{y}(\mathbf{x}):=w_0 + \ ...
- 3.1、Factorization Machine模型
Factorization Machine模型 在Logistics Regression算法的模型中使用的是特征的线性组合,最终得到的分隔超平面属于线性模型,其只能处理线性可分的二分类问题,现实生活 ...
- Factorization Machine算法
参考: http://stackbox.cn/2018-12-factorization-machine/ https://baijiahao.baidu.com/s?id=1641085157432 ...
- AI Factorization Machine(FM)算法
FM算法 参考链接: https://www.csie.ntu.edu.tw/~b97053/paper/Rendle2010FM.pdf
- CTR预估算法之FM, FFM, DeepFM及实践
https://blog.csdn.net/john_xyz/article/details/78933253 目录目录CTR预估综述Factorization Machines(FM)算法原理代码实 ...
- 深入理解FFM原理与实践
原文:http://tech.meituan.com/deep-understanding-of-ffm-principles-and-practices.html 深入理解FFM原理与实践 del2 ...
- zz深度学习在美团配送 ETA 预估中的探索与实践
深度学习在美团配送 ETA 预估中的探索与实践 比前一版本有改进: 基泽 周越 显杰 阅读数:32952019 年 4 月 20 日 1. 背景 ETA(Estimated Time of A ...
- 个性化排序算法实践(二)——FFM算法
场感知分解机(Field-aware Factorization Machine ,简称FFM)在FM的基础上进一步改进,在模型中引入类别的概念,即field.将同一个field的特征单独进行one- ...
随机推荐
- crontab学习笔记
一.crond与crontab简介 在Linux系统中,循环运行的例行性计划任务,是由 cron (crond) 这个系统服务来控制的,而crontab命令则被用来提交和管理用户的需要周期性执行的任务 ...
- IntelliJ IDEA 安装
1.在终端输入sudo vim /private/etc/hosts 2.在打开的hosts文件中,在尾行添加 0.0.0.0 account.jetbrains.com 3.去网站http://id ...
- python 全栈基础作业题
1.执行 Python 脚本的两种方式 1..直接使用PyCharm执行 2.python run.py 调用python 解释器来调用python脚本 2.简述位.字节的关系 数据存储是以“字节”( ...
- code1006 等差数列
我绞尽脑汁想一个更好的算法,然而不能如愿,只好写一个n^3的了 很简单,就是暴力搜索(还好n<100) 先排序,然后循环i=1ton,j=i+1ton 把a[i]a[j]确定为等差数列开始的两个 ...
- Oracle 用户
1.关于创建用户; 2.用户配置文件; 3.创建用户; 4.更改用户; 5.删除用户; 1.关于创建用户: 1.1 用户名:创建数据库用户必须具有 Create user 系统权限,必须指定用户名和密 ...
- Spring Boot☞ 统一异常处理
效果区: 代码区: package com.wls.integrateplugs.exception.dto; public class ErrorInfo<T> { public st ...
- C# Winform 跨线程更新UI控件常用方法总结(转)
出处:http://www.tuicool.com/articles/FNzURb 概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件 ...
- 编写高质量代码改善C#程序的157个建议——建议62:避免嵌套异常
建议62:避免嵌套异常 应该允许异常在调用堆栈上往上传,不要过多的使用catch,然后再throw.过多的使用catch会带来两个问题: 1)代码更多了.这看上去好像你根本不知道怎么处理异常,所以你总 ...
- CodeForces 588E A Simple Task(线段树)
This task is very simple. Given a string S of length n and q queries each query is on the format i j ...
- CentOS下安装PHP的AMQP扩展方法和步骤
AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计.基于此协议的客户端 ...