zoukankan      html  css  js  c++  java
  • 机器学习技法 之 矩阵分解(Matrix Factorization)

    线性神经网络(Linear Network Hypothesis)

    这里用推荐系统的应用实例引出矩阵分解:

    现在有一个电影评分预测问题,那么数据集的组成为:

    [left{ left( ilde { mathbf { x } } _ { n } = ( n ) , y _ { n } = r _ { n m } ight) : ext { user } n ext { rated movie } m ight} ]

    其中 ( ilde { mathbf { x } } _ { n } = (n)) 是一种抽象的类别(categorical)特征。

    什么是类别特征呢?举例来说:比如ID号,血型(A,B,AB,O),编程语言种类(C++,Python,Java)。

    但是大部分机器学习算法都是基于数值型特征实现的,当然决策树除外。所以现在需要将类别特征转换(编码,encoding)为数值特征。这里需要转换的特征是ID号。使用的工具是二值向量编码(binary vector encoding),也就是向量的每个元素只有两种数值选择,这里选择的是 0/1 向量编码,对应关系是向量中的第 ID 个元素为 1,其他元素均为 0。

    那么第 m 个电影编码后的数据集 (mathcal D_m) 可以表示为:

    [left{ left( mathbf { x } _ { n } = ext { Binary VectorEncoding } ( n ) , y _ { n } = r _ { n m } ight) : ext { user } n ext { rated movie } m ight} ]

    如果将全部的电影数据整合到一起的数据集 (mathcal D) 可以表示为:

    [left{ left( mathbf { x } _ { n } = ext { Binary VectorEncoding } ( n ) , mathbf { y } _ { n } = left[ egin{array} { l l l l l l } r _ { n 1 } & ? & ? & r _ { n 4 } & r _ { n 5 } & ldots & r _ { n M } end{array} ight] ^ { T } ight) ight} ]

    其中 (?) 代表了该电影未评分。

    现在的想法是使用一个 (N - ilde { d } - M) 神经网络进行特征提取:

    在这里插入图片描述
    现在先使用线性的激活函数,那么由此得到的线性神经网络的结构示意图为:

    在这里插入图片描述

    基本矩阵分解(Basic Matrix Factorization)

    那么现在将权重矩阵进行重命名:

    [mathrm { V } ^ { T } ext { for } left[ w _ { n i } ^ { ( 1 ) } ight] ext { and } mathrm { W } ext { for } left[ w _ { i m } ^ { ( 2 ) } ight] ]

    那么假设函数可以写为:

    [mathrm { h } ( mathrm { x } ) = mathrm { W } ^ { T } underbrace { mathrm { Vx } } _ { Phi ( mathrm { x } ) } ]

    矩阵 (mathrm { V }) 实际上就是特征转换 (Phi ( mathrm { x } )),然后再使用 (mathrm { W }) 进行实现一个基于转换数据的线性模型。那么根据 ID 的数值编码规则,第 (n) 个用户的假设函数可以写为:

    [mathrm { h } left( mathrm { x } _ { n } ight) = mathrm { W } ^ { T } mathbf { v } _ { n } , ext { where } mathbf { v } _ { n } ext { is } n ext { -th column of } mathrm { V } ]

    (m) 个电影的假设函数可以写为:

    [h _ { m } ( mathbf { x } ) = mathbf { w } _ { m } ^ { T } mathbf { Phi } ( mathbf { x } ) ]

    那么对于推荐系统来说现在需要进行 (mathrm { W })(mathrm { V }) 的最优解求取。

    对于(mathrm { W })(mathrm { V }) 来说理想状态是:

    [r _ { n m } = y _ { n } approx mathbf { w } _ { m } ^ { T } mathbf { v } _ { n }= mathbf { v } _ { n } ^ { T } mathbf { w } _ { m } Longleftrightarrow mathbf { R } approx mathbf { V } ^ { T } mathbf { W } ]

    也就是说特征转换矩阵 (mathbf { V }) 和线性模型矩阵 (mathbf { W }) 相乘的结果是评分矩阵。
    在这里插入图片描述
    还记得在机器学习基石中的评分预测示意图吗?观看者和电影都有自己的特征向量,只需要计算两个向量的相似度便可以用了预测评分。观看者和电影向量在这里指的是 (mathbf { v } _ { n })(mathbf { w } _ { m })

    在这里插入图片描述

    那么对于数据集 (mathcal D) ,该假设函数的基于平方误差的误差测量为:

    [E _ { mathrm { in } } left( left{ mathbf { w } _ { m } ight} , left{ mathbf { v } _ { n } ight} ight) = frac { 1 } { sum _ { m = 1 } ^ { M } left| mathcal { D } _ { m } ight| } sum _ { ext {user } n ext { rated movie } m } left( r _ { n m } - mathbf { w } _ { m } ^ { T } mathbf { v } _ { n } ight) ^ { 2 } ]

    那么现在就要根据数据集 (mathcal D) 进行 (mathbf { v } _ { n })(mathbf { w } _ { m }) 的学习来保证误差最小。

    [egin{aligned} min _ { mathrm { W } , mathrm { V } } E _ { mathrm { in } } left( left{ mathbf { w } _ { m } ight} , left{ mathbf { v } _ { n } ight} ight) & propto sum _ { mathrm { user } n ext { rated movie } m } left( r _ { n m } - mathbf { w } _ { m } ^ { T } mathbf { v } _ { n } ight) ^ { 2 } \ & = sum _ { m = 1 } ^ { M } left( sum _ { left( mathbf { x } _ { n } , r _ { n m } ight) in mathcal { D } _ { m } } left( r _ { n m } - mathbf { w } _ { m } ^ { T } mathbf { v } _ { n } ight) ^ { 2 } ight) (1)\ & = sum _ { n = 1 } ^ { N } left( sum _ { left( mathbf { x } _ { n } , r _ { n m } ight) in mathcal { D } _ { m } } left( r _ { n m } - mathbf { v } _ { n } ^ { T } mathbf { w } _ { m } ight) ^ { 2 } ight) (2) end{aligned} ]

    由于上式中有 (mathbf { v } _ { n })(mathbf { w } _ { m }) 两个变量,同时优化的话可能会很困难,所以基本的想法是使用交替最小化操作(alternating minimization):

    1. 固定 (mathbf { v } _ { n }),也就是说固定用户特征向量,然后求取每一个 (mathbf { w } _ { m } equiv ext { minimize } E _ { ext {in } } ext { within } mathcal { D } _ { m })
    2. 固定 (mathbf { w } _ { m }),也就是说电影的特征向量,然后求取每一个 (mathbf { v } _ { n } equiv ext { minimize } E _ { ext {in } } ext { within } mathcal { D } _ { m })

    这一过程叫做交替最小二乘算法(alternating least squares algorithm)。该算法的具体实现如下:

    [egin{array} { l } ext { initialize } ilde { d } ext { dimension vectors } left{ mathbf { w } _ { m } ight} , left{ mathbf { v } _ { n } ight} \ ext { alternating optimization of } E _ { ext {in } } : ext { repeatedly } \ qquad ext { optimize } mathbf { w } _ { 1 } , mathbf { w } _ { 2 } , ldots , mathbf { w } _ { M } ext { : } ext { update } mathbf { w } _ { m } ext { by } m ext { -th-movie linear regression on } left{ left( mathbf { v } _ { n } , r _ { n m } ight) ight} \ qquad ext { optimize } mathbf { v } _ { 1 } , mathbf { v } _ { 2 } , ldots , mathbf { v } _ { N } ext { : } ext { update } mathbf { v } _ { n } ext { by } n ext { -th-user linear regression on } left{ left( mathbf { w } _ { m } , r _ { n m } ight) ight} \ ext { until converge } end{array} ]

    初始化过程使用的是随机(randomly)选取。随着迭代的过程保证了 (E _ { ext {in } }) 不断下降,由此保证了收敛性。交替最小二乘的过程更像用户和电影在跳探戈舞。

    线性自编码器与矩阵分解(Linear Autoencoder versus Matrix Factorization)

    [egin{array}{c|c|c} & ext{Linear Autoencoder}& ext{Matrix Factorization}\ hline ext{goal} &mathrm { X } approx mathrm { W } left( mathrm { W } ^ { T } mathrm { X } ight)&mathbf { R } approx mathbf { V } ^ { T } mathbf { W }\ hline ext{motivation}& ext { special } d - ilde { d } - d ext { linear NNet }&N - ilde { d } - M ext { linear NNet }\ hline ext{solution} & ext { global optimal at eigenvectors of } X ^ { T } X & ext {local optimal via alternating least squares } \ hline ext { usefulness} & ext { extract dimension-reduced features } & ext { extract hidden user/movie features } end{array} ]

    所以线性自编码器是一种在矩阵 (mathrm{X}) 做的特殊的矩阵分解。

    随机梯度法(Stochastic Gradient Descent)

    相比交替迭代优化,另一种优化思路是随机梯度下降法。

    回顾一下矩阵分解的误差测量函数:

    [E _ { mathrm { in } } left( left{ mathbf { w } _ { m } ight} , left{ mathbf { v } _ { n } ight} ight) propto sum _ { ext {user } n ext { rated movie } m } underbrace { left( r _ { n m } - mathbf { w } _ { m } ^ { T } mathbf { v } _ { n } ight) ^ { 2 } } _ { ext {err(user } n , ext { movie } m , ext { rating } r_{nm} )} ]

    随机梯度下降法高效且简单,可以拓展于其他的误差测量。

    由于每次只是拿出一个样本进行优化,那么先观察一下单样本的误差测量:

    [operatorname { err } left( ext {user } n , ext { movie } m , ext { rating } r _ { n m } ight) = left( r _ { n m } - mathbf { w } _ { m } ^ { T } mathbf { v } _ { n } ight) ^ { 2 } ]

    那么偏导数为:

    [egin{array} { r l } abla _ { mathbf { v } _ { n } } & operatorname { err } left( ext { user } n , ext { movie } m , ext { rating } r _ { n m } ight) = - 2 left( r _ { n m } - mathbf { w } _ { m } ^ { T } mathbf { v } _ { n } ight) mathbf { w } _ { m } \ abla _ { mathbf { w } _ { m } } & operatorname { err } left( ext { user } n , ext { movie } m , ext { rating } r _ { n m } ight) = - 2 left( r _ { n m } - mathbf { w } _ { m } ^ { T } mathbf { v } _ { n } ight) mathbf { v } _ { n } end{array} ]

    也就是说只对当前样本的 (mathbf { v } _ { n })(mathbf { w } _ { m }) 有影响,而其他的参数的偏导均为零。总结来说就是:

    [ ext {per-example gradient } propto - ( ext { residual } ) ( ext { the other feature vector } ) ]

    那么使用随机梯度下降法求解矩阵分解的实际步骤为:

    [egin{array} { l } ext { initialize } ilde { d } ext { dimension vectors } left{ mathbf { w } _ { m } ight} , left{ mathbf { v } _ { n } ight} ext { randomly } \ ext{ for } t = 0,1 , ldots , T \ qquad ext { (1) randomly pick } ( n , m ) ext { within all known } r _ { n m } \ qquad ext { (2) calculate residual } ilde { r } _ { n m } = left( r _ { n m } - mathbf { w } _ { m } ^ { T } mathbf { v } _ { n } ight) \ qquad ext { (3) SGD-update: } \ qquadqquadqquad egin{aligned} mathbf { v } _ { n } ^ { n e w } & leftarrow mathbf { v } _ { n } ^ { o l d } + eta cdot ilde { r } _ { n m } mathbf { w } _ { m } ^ { o l d } \ mathbf { w } _ { m } ^ { n e w } & leftarrow mathbf { w } _ { m } ^ { o l d } + eta cdot ilde { r } _ { n m } mathbf { v } _ { n } ^ { o l d } end{aligned} end{array} ]

    但是注意一点随机梯度下降法是针对随机选到的样本进行优化的,那么针对一些对时间比较敏感的数据分析任务,比如近期的数据更有效,那么随机梯度下降法的随机选取应该偏重于近期的数据样本,那么效果可能会好一些。如果你明白这一点,那么在实际运用中会更容易修改该算法。

    提取模型总结(Map of Extraction Models)

    提取模型:思路是将特征转换作为隐变量嵌入线性模型(或者其他基础模型)中。也就是说除了模型的学习,还需要从资料中学到怎么样作转换能够有效的表现资料。

    在这里插入图片描述
    在神经网络或者深度学习中,隐含层的前 L - 1 层(( ext { weights } w _ { i j } ^ { ( ell ) }))是进行特征的转换,最后一层是线性模型(( ext { weights } w _ { i j } ^ { ( L ) }))。也就是说在学习线性模型的同时,也学到了那些隐藏的转换。

    在RBF网络中,最后一层也是线性模型(( ext { weights } eta _{ m }),而中间潜藏的变数(中心代表,( ext { RBF centers } mu _ { m }))也是一种特征的学习。

    而在矩阵分解中,学习到了两个特征那就是 (mathbf { w } _ { m })(mathbf { v } _ { n }),两者可以叫线性模型的权重也可以叫特征向量,这是相对于用户还是电影,不同的对象功能不同。

    而在 自适应提升和梯度提升(Adaptive/Gradient Boosting)中,实际上假设函数 (g_t) 的求解就是一种特征的学习,而所学习到的系数 (alpha_t) 则是线性模型的权重系数。

    相对来说在 k 邻近算法中,这 Top k 的邻居则是一种特征转换。而各个邻居投票系数 (y_n) 则是一种线性模型的权重系数。

    提取技术总结(Map of Extraction Techniques)

    在这里插入图片描述

    在神经网络或者深度学习中,则使用的是基于随机梯度下降法(SGD)的反向传播算法(backprop)。同时其中有一种特殊的实现:自编码器,将输入和输出保持一样,学习出一种压缩编码。

    在RBF网络中,使用 k 均值聚类算法(k-means clustering)找出那些中心。

    而在矩阵分解中,则可以使用的是 交替最小二乘(alternating leastSQR)和随机梯度下降(SGD)。

    而在 自适应提升和梯度提升(Adaptive/Gradient Boosting)中,使用的技巧是梯度下降法(functional gradient descent)的思路还获取假设函数 (g_t) 的。

    相对来说在 k 邻近算法中,则使用的是一种 lazy learning,什么意思呢?在训练过程中不做什么事情,而在测试过程中,拿已有的数据做一些推论。

    提取模型的优缺(Pros and Cons of Extraction Models)

    提取模型(Neural Network/Deep Learning、RBF Network 、Matrix Factorization)的优缺点如下:

    优点:

    • easy: reduces human burden in designing features
      简单:减小了设计特征的人力负担
    • powerful : if enough hidden variables considered
      强有力:如果考虑足够多的隐变量的话

    缺点

    • hard: non-convex optimization problems in general
      困难:通常是非凸优化问题
    • overfitting: needs proper regularization/validation
      过拟合:由于很有力,所以要合理使用正则化和验证工具
    任世事无常,勿忘初心
  • 相关阅读:
    C++ 内置宏定义 与 预编译指令
    C++ 反射机制的简单实现
    Intellij打包jar文件,“java.lang.SecurityException: Invalid signature file digest for Manifest main attrib
    IntelliJ IDEA 运行你的第一个Java应用程序 idea运行main方法
    IDEA重新打jar包时报错MANIFEST.MF already exists in VFS
    在 RPA10.X 运行异常,RPA9 却正常的问题处理
    Python判断文件是否存在的三种方法
    Python日期时间函数
    Chrome提示:"请停用以开发者模式运行的扩展程序"的解决办法
    Win10提示“无法打开此计算机上的组策略对象”如何解决
  • 原文地址:https://www.cnblogs.com/FlameBlog/p/14715226.html
Copyright © 2011-2022 走看看