简单易学的机器学习算法——因子分解机(Factorization Machine)

一、因子分解机FM的模型

       因子分解机(Factorization Machine, FM)是由Steffen Rendle提出的一种基于矩阵分解的机器学习算法。

1、因子分解机FM的优势

       对于因子分解机FM来说,最大的特点是对于稀疏的数据具有很好的学习能力。现实中稀疏的数据很多,例如作者所举的推荐系统的例子便是一个很直观的具有稀疏特点的例子。

2、因子分解机FM的模型       

二、因子分解机FM算法

    因子分解机FM算法可以处理如下三类问题:

  1. 回归问题(Regression)
  2. 二分类问题(Binary Classification)
  3. 排序(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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据挖掘DT机器学习

R语言与点估计学习笔记(EM算法与Bootstrap法)

众所周知,R语言是个不错的统计软件。今天分享一下利用R语言做点估计的内容。主要有:矩估计、极大似然估计、EM算法、最小二乘估计、刀切法(Jackknife)、自...

426100
来自专栏开心的学习之路

贝叶斯决策理论(数学部分)

概率质量函数(Probability Mass Function)是针对离散值而言的,通常用大写字母P表示。假设某个事

16930
来自专栏专知

【论文推荐】最新6篇图像分割相关论文—隐马尔可夫随机场、级联三维全卷积、信号处理、全卷积网络、多源域适应、循环分割

【导读】专知内容组整理了最近六篇图像分割(Image Segmentation)相关文章,为大家进行介绍,欢迎查看! 1.Combination of Hidd...

41660
来自专栏Deep Learning in Ads

基于Field的DeepFM稀疏化实现

DeepFM是一个集成了FM和DNN的神经网络框架,思路和Google的Wide&Deep相似,都包括wide和deep两部分。W&D模型的wide部分是广...

71380
来自专栏专知

【论文推荐】最新6篇行人重识别相关论文—深度空间特征重构、生成对抗网络、图像生成、系列实战、图像-图像域自适应方法、行人检索

【导读】专知内容组整理了最近六篇行人重识别(Person Re-identification)相关文章,为大家进行介绍,欢迎查看! 1. Deep Spatia...

76660
来自专栏决胜机器学习

机器学习(三) ——k-近邻算法基础

机器学习(三)——k-近邻算法基础 (原创内容,转载请注明来源,谢谢) 一、概述 k近邻算法(kNN),是监督学习的一种,主要用于分类,通过...

376110
来自专栏专知

【论文推荐】最新六篇行人再识别(ReID)相关论文—和谐注意力网络、时序残差学习、评估和基准、图像生成、三元组、对抗属性-图像

【导读】专知内容组整理了最近六篇行人再识别(Person Re-Identification)相关文章,为大家进行介绍,欢迎查看! 1. Harmonious ...

80450
来自专栏深度学习与计算机视觉

理解Logistic回归算法原理与Python实现

一般的机器学习的实现大致都是这样的步骤: 1.准备数据,包括数据的收集,整理等等 2.定义一个学习模型(learning function model)...

43880
来自专栏fangyangcoder

python机器学习实战(四)

http://www.cnblogs.com/fydeblog/p/7364317.html

28120
来自专栏磐创AI技术团队的专栏

基于word2vec训练词向量(二)

作者 | 荔枝boy 编辑 | 磐石 出品 | 磐创AI技术团队 ---- 【磐创AI导读】:前几篇文章中我们介绍了一些机器学习、深度学习入门资源项目合集,本篇...

48090

扫码关注云+社区

领取腾讯云代金券