首页 > 编程语言 >简单易学的机器学习算法——因子分解机(Factorization Machine)

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

时间:2023-06-14 21:01:08浏览次数:52  
标签:dataMatrix Factorization FM Machine 因子 分解 classLabels inter 易学


一、因子分解机FM的模型


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


1、因子分解机FM的优势




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


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


2、因子分解机FM的模型


       对于度为2的因子分解机FM的模型为:



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


其中,参数

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


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


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


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

表示的是两个大小为

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

的向量

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

和向量

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

的点积:



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


其中,

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

表示的是系数矩阵

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

的第

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

维向量,且

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


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

称为超参数。在因子分解机FM模型中,前面两部分是传统的线性模型,最后一部分将两个互异特征分量之间的相互关系考虑进来。


    因子分解机FM也可以推广到高阶的形式,即将更多互异特征分量之间的相互关系考虑进来。


二、因子分解机FM算法


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


  1. 回归问题(Regression)
  2. 二分类问题(Binary Classification)
  3. 排序(Ranking)


1、回归问题(Regression)


    在回归问题中,直接使用

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

作为最终的预测结果。在回归问题中使用最小均方误差(the least square error)作为优化的标准,即



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


其中,

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

表示样本的个数。


2、二分类问题(Binary Classification)


    与Logistic回归类似,通过阶跃函数,如Sigmoid函数,将

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

映射成不同的类别。在二分类问题中使用logit loss作为优化的标准,即



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


其中,

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

表示的是阶跃函数Sigmoid。具体形式为:



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


三、因子分解机FM算法的求解过程

1、交叉项系数


    在基本线性回归模型的基础上引入交叉项,如下:



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


若是这种直接在交叉项

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

的前面加上交叉项系数

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

的方式在稀疏数据的情况下存在一个很大的缺陷,即在对于观察样本中未出现交互的特征分量,不能对相应的参数进行估计。


    对每一个特征分量

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

引入辅助向量

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

,利用

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

对交叉项的系数

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

进行估计,即



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




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




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


这就对应了一种矩阵的分解。对

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

值的限定,对FM的表达能力有一定的影响。



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


2、模型的求解



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


这里要求出

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

,主要采用了如公式

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

求出交叉项。具体过程如下:



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


3、基于随机梯度的方式求解



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


对于回归问题:



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


对于二分类问题:



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




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


四、实验(求解二分类问题)

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、实验结果:



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


五、几点疑问


    在传统的非稀疏数据集上,有时效果并不是很好。在实验中,我有一点处理,即在求解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

标签:dataMatrix,Factorization,FM,Machine,因子,分解,classLabels,inter,易学
From: https://blog.51cto.com/u_16161414/6481120

相关文章

  • 简单易学的机器学习算法——K-Means算法
    一、聚类算法的简介  聚类算法是一种典型的无监督学习算法,主要用于将相似的样本自动归到一个类别中。聚类算法与分类算法最大的区别是:聚类算法是无监督的学习算法,而分类算法属于监督的学习算法。  在聚类算法中根据样本之间的相似性,将样本划分到不同的类别中,对于不同的相似......
  • 简单易学的机器学习算法——K-Means++算法
    一、K-Means算法存在的问题由于K-Means算法的简单且易于实现,因此K-Means算法得到了很多的应用,但是从K-Means算法的过程中发现,K-Means算法中的聚类中心的个数k需要事先指定,这一点对于一些未知数据存在很大的局限性。其次,在利用K-Means算法进行聚类之前,需要初始化k个聚类中心,在上述的......
  • Rockchip RK3399 - rt5651 ALSA Machine驱动
    一、Machine驱动Machinedriver描述了如何控制CPU数字音频接口(DAI)和Codec,使得互相配合在一起工作,Machine驱动代码位于sound/soc/generic/simple-card.c文件。1.1设备节点rt5651-sound我们在arch/arm64/boot/dts/rockchip/rk3399-evb.dts文件添加设备节点rt5651-sound;rt5651_......
  • COMP9417 Machine Learning 机器学习
    COMP9417-MachineLearningHomework1:RegularizedRegression&NumericalOptimizationIntroductionInthishomeworkwewillexploresomealgorithmsforgradientbasedoptimization.Thesealgorithmshavebeencrucialtothedevelopmentofmachinelearnin......
  • 聊聊Cola-StateMachine轻量级状态机的实现
    背景在分析Seata的saga模式实现时,实在是被其复杂的json状态语言定义文件劝退,我是有点没想明白为啥要用这么来实现状态机;盲猜可能是基于可视化的状态机设计器来定制化流程,更方便快捷且上手快吧,毕竟可以通过UI直接操作,设计状态流转图,但我暂时不太能get到。对于Saga模式的实现,之前......
  • iOS MachineLearning 系列(19)—— 分析文本中的问题答案
    iOSMachineLearning系列(19)——分析文本中的问题答案本篇文章将介绍Apple官方推荐的唯一的一个文本处理模型:BERT-SQuAD。此模型用来分析一段文本,并根据提供的问题在文本中寻找答案。需要注意,BERT模型不会生成新的句子,它会从提供的文本中找到最有可能的答案段落或句子。BERT模型的......
  • iOS MachineLearning 系列(20)—— 训练生成CoreML模型
    iOSMachineLearning系列(20)——训练生成CoreML模型本系列前面的文章详细的介绍了在iOS中与AI能力相关的API的使用,也介绍了如何使用训练好的CoreML模型来实现更强大的AI能力。然而,无论是成熟的API提供的能力,还是各种各样的三方模型,有时候都并不能满足某一领域内的定制化需求。当我......
  • Machine Learning 【note_02】
    note_02Keywords:Classification,LogisticRegression,Overfitting,Regularization1MotivationClassification:"binaryclassification":\(y\)canonlybeoneoftwovaluesclass/categoryTryusinglinearregressiontodo:Itseemswork......
  • Machine Learning 【note_01】
    Declaration(2023/06/02):Thisnoteisthefirstnoteofaseriesofmachinelearningnotes.Atpresent,themainlearningresourceisthe2022AndrewY.NgmachinelearningDeeplearning.aicourse,fromwhichmostoftheknowledgeandsomepicturesinthe......
  • spring StateMachine简易使用
    SpringStateMachine是一个状态机框架,在Spring框架项目中,开发者可以通过简单的配置就能获得一个业务状态机,而不需要自己去管理状态机的定义、初始化等过程。今天这篇文章,我们通过一个案例学习下SpringStateMachine框架的用法。 pom依赖中添加<parent><groupId>org.......