优点

  • 解决了特征稀疏的问题,能在非常非常稀疏数据的情况下进行预估
  • 解决了特征组合的问题
  • FM是一个通用的模型,适用于大部分的场景
  • 训练速度快,线性复杂度

开始

先附上视频的地址:机器学习算法讲堂(3):FM算法 Factorization Machine

我们首先从线性回归解法的角度来看一个特征组合的问题,如果现在数据涉及到训练集中的两个特征,那么LR就要写成:
$f(x)=w_0+\sum_{i=1}^nw_ix_i+\sum_{i=1}^{n-1}\sum_{j=i+1}^nw_{ij}x_ix_j$

可以看到在这个方程中,随着特征选取的数量变多,特征组合之后的复杂度是特征数量个N相乘,这是在训练过程中不能接受的,并且线性回归的方法只能在$w_{ij}x_ix_j$不为0的情况下进行训练,对于稀疏的数据来说训练是不充分的.而FM解决的就是LR复杂度过高和对稀疏数据训练不充分的缺点.

FM的思路就是将W分解为$vv^T$,这也就是FM名字的由来,等于是因式分解W.接下来是FM的推导的过程:
首先引入辅助变量$v_i=(v_{i1},v_{i2},\cdots,v_{ik})^T\in\mathbb{R}^k,i=1,2,3\ldots,n$

已知特征矩阵W为:
$$
\begin{pmatrix} w_{11} & w_{12} & w_{13} & \cdots & w_{1n} \\ w_{21} & w_{22} & w_{23} & \cdots & w_{2n} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ w_{n1} & w_{n2} & w_{n3} & \cdots & w_{nn} \\ \end{pmatrix}
$$
V矩阵为:
$$
\begin{pmatrix} v_{11} & v_{12} & v_{13} & \cdots & v_{1k} \\ v_{21} & v_{22} & v_{23} & \cdots & v_{2k} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ v_{n1} & v_{n2} & v_{n3} & \cdots & v_{nk} \\ \end{pmatrix}
$$
且有结论:当k足够大时,对于任意对称正定实矩阵$w\in\mathbb{R}^{n\times n}$,均存在实矩阵$v\in\mathbb{R}^{n\times k}$使得$w=vv^T$

这样一来,我们只要找到一个$vv^T=w$就可以解决这个问题了,而分解成$vv^T$的优势在于有效的降低了算法的复杂度,下面是对FM算法的求解:

根据上面的分解,可以将FM公式写为:
$$
y=w_0+\sum_{i=1}^nw_ix_i+\sum_{i=1}^{n-1}\sum_{j=i+1}^n<v_i,v_j>x_ix_j, <v_i,v_j>=\sum_{f=1}^kv_{i,f}\cdot v_{j,f}
$$
这里主要需要求解的就是最后一项:
$$
\begin{split} &\sum_{i=1}^{n-1}\sum_{j=i+1}^n<v_i,v_j>x_ix_j \\ =&\frac {1} {2}\sum_{i=1}^n\sum_{j=1}^n<v_i,v_j>-\frac {1} {2}\sum_{i=1}^n<v_i,v_i>x_ix_i \text{,把j化成i,需要减去重复的部分} \\ =&\frac {1} {2} \left( \sum_{i=1}^n\sum_{j=1}^n\sum_{f=1}^kv_{i,f}v_{j,f}x_ix_j-\sum_{i=1}^n\sum_{f=1}^kv_{i,f}v_{i,f}x_ix_i \right) \text{,把上面的等式代入进来} \\ =&\frac {1} {2} \sum_{f=1}^k \left( \left( \sum_{i=1}^nv_{i,f}x_i \right) \left( \sum_{j=1}^nv_{j,f}x_j \right)-\sum_{i=1}^nv_{i,f}^2x_i^2 \right) \text{,提出公共的求和部分} \\ =&\frac {1}{2} \sum_{f=1}^k \left( \left( \sum_{i=1}^nv_{i,f}x_i \right)^2-\sum_{i=1}^nv_{i,f}^2x_i^2 \right) \text{,前面2项除了下标的i,j不同之外是一样的,所以合并} \\ \end{split}
$$
我们可以看到公式化简到最后,复杂度就只和求和符号上的k,n相关了,所以复杂度可以简单的记为O(nk),但是这已经比之前的线性回归的解法复杂度低了很多了,这可以视为是线性的复杂度.

下面看一下FM的梯度的计算,我们对$w_0,w_i,v_i$分别求偏导可以写为:
$$
\frac {dy} {d\theta}= \begin{cases} 1, & \text{if $\theta=w_0$} \\ x_i, & \text{if $\theta=w_i$} \\ x_i\sum_{j=1,j\neq i}^nv_{j,f}x_j & \text{if $\theta=v_{i,f}$} \\ \end{cases}
$$
最后一个公式可以化为:
$$
x_i\sum_{j=1,j\neq i}^nv_{j,f}x_j = x_i\sum_{j=1}^nv_{j,f}x_j-v_{i,f}x_i^2
$$
我们可以看到这个梯度计算的公式中,计算复杂度也只和n相关也就是说:复杂度是O(n)!相比于简单的LR动不动的N方的复杂度来说,FM的复杂度可以说是相当的低了.

拓展

这里就只是先列举一下FM的一些拓展使用:

  • FFM
  • DeepFM
  • DCN
  • xDeepFM

下面就放几个图片吧(这次是自己截图放的图床)
DeepFM:
DeepFM
xDeepFM:
xDeepFM

贴一下论文的地址:
Factorization Machines

xDeepFM: Combining Explicit and Implicit Feature Interactions for Recommender Systems

开始

在一个普通的周末打开哔哩哔哩刷新动态的时候突然看到qsc投稿了视频的我是表示震惊的!当看到标题是机器学习算法讲堂的时候,我知道:是时候了,是时候开始学一点机器学习了,那么这也算是最近周末的常驻项目之一了.既然看了视频并且手推了一遍,肯定是要搞个大新闻的,那么就开个博客记录一下自己的笔记吧.

先来贴一下qsc视频的地址:
机器学习算法讲堂(2):线性回归推导
机器学习算法讲堂(2.1):最大似然与线性回归

线性回归

首先允许我再盗一张图:

这是一个非常经典的二维的线性回归的图片.我们的任务就是找到这样一条直线,使得这条直线到平面上所有的点的距离之和最小,写成函数就是这样:
$ f(x)=w_0+w_1x_1+w_2x_2+\cdots=w_nx_n = w^Tx, x\in\mathbb{R}^d,y\in\mathbb{R} $

判断这个函数的好坏我们就定义一个损失函数(loss function)如下(最小二乘法):
$ E=\frac {1} {N}\sum_{i=1}^N(f(x_i)-y_i)^2 $
解释:对每个$x_i$应用预测函数的值f($x_i$)减去数据集中的正确值的差再平方,求1…N所有误差的和再除以N取平均

定义W为使得E最小时的参数:W=argminE,然后我们可以把这个问题转化为求E的导数,找到E的导数为0的点就是E最小的点
先将E化为矩阵的表示形式(这里的x和y都是矩阵的形式):
$$
\begin{split}
E &= \begin{Vmatrix} Xw-y \end{Vmatrix}^2 \\
&=(Xw-y)^T(Xw-y)
\end{split}
$$

接下来对E求导(左导右不导加上右导左不导):
$$
\begin{split}
dE&= (Xdw)^T(Xw-y)+(Xw-y)^TXdw \\
&=2(Xw-y)^TXdw \\
\frac {dE^T} {dw}&=(2(Xw-y)^TX)^T \\
&=2X^T(Xw-y) \Rightarrow \nabla
\end{split}
$$

我们可以把$\nabla$当做是训练的梯度,当$2X^T(Xw-y)=0$的时候w可以取到最小,转换一下:
$w=(X^TX)^{-1}X^Ty$
当$X^TX$可逆的时候就可以直接求解,不可逆的时候就需要使用梯度下降的方法来训练使得E收敛到最小获得w的值.
梯度下降:$w(t+1)=w(t)-\lambda\nabla$,$\lambda$为梯度下降的步长.

最大似然

还是回到上面的图片中,在我们用函数来拟合这组数据的时候,因为无法完美的拟合数据,所以我们假设有我们没有观察到的因素存在导致我们的拟合函数存在误差,而这个拟合函数所缺失的不可解释的那部分误差就是直线到数据点之间的距离.
同时我们换个角度来看这个数据集,既然这些点被我们观测到了,就说明这些点被我们观测到的概率是最大的,由此可以推出,我们可以寻找一个函数,使得我们能够观测到这些点的概率最大,那我们也就找到了对些数据最好的拟合.

似然函数推导

假定存在一个数据集D=$\lbrace(x_1,y_1),(x_2,y_2),\cdots,(x_n,y_n)\rbrace$
我们定义函数$y_i=f(x_i)+\varepsilon_i,\varepsilon_i为不能完全解释的误差$
问题就转化成了:现在我们有N个f(x)函数,我们要评估哪个模型最有可能产生这一组数据,用概率来表示就是:
$P(D|x,\theta)=P(y_1,y_2,y_3,\cdots,y_N|x_1,x_2,x_3,\cdots,x_N,\theta)$
假设数据之间是相互独立的(概率相乘):
$P(y_1,y_2,y_3,\cdots,y_N|x_1,x_2,x_3,\cdots,x_N,\theta)=\prod_{j=1}^N P(y_j|x_j,\theta)$
我们的似然函数也就是:$likelihood(\theta)=\prod_{j=1}^N P(y_j|x_j,\theta)$
因为对于数据集D来说x,y已经确定所以可以将概率转换如下:
$P(y_i|x_i,\theta)=P(y_i|f(x_i)+E)=P(y_i-f(x_i)|E)$
可以看到:对于任意的x,y来说概率就和模型的预测值和实际值之间的误差E的分布相关了.

最大似然和线性回归

根据我们之前的定义:$y_i=f(x_i)+\varepsilon_i$ 我们可以推出:$\varepsilon_i=y_i-w^Tx_i$ (也就是前面线性回归推导中使用的误差)
我们假设Y服从均值为$w^Tx$ ,方差为1的分布:
$$
P(Y|x)=P(\varepsilon|x)=\frac {1} {\sqrt{2\pi}\times e^{\frac {-\varepsilon^2} {2}}}
$$
将上面的$\varepsilon_i=y_i-w^Tx_i$ 代入公式:
$$
P(Y|x)=P(\varepsilon|x)=\frac {1} {\sqrt{2\pi}\times e^{\frac {-(y_i-w^Tx_i)^2} {2}}}
$$
由于误差符合正态分布,我们将概率代入似然函数中并且对似然函数取log:
$$
likelihood(\theta)=\log \prod_{j=1}^N \frac {1} {\sqrt{2\pi}\times e^{\frac {-(y_i-w^Tx_i)^2} {2}}}
$$
化简得到:
$$
N\log(\frac {1} {\sqrt{2\pi}})+\frac {\sum_{i=1}^N-(y_i-w^Tx_i)^2} {2}
$$
去掉前面的常数项和后面的常系数之后可以化简为:
$$\sum_{i=1}^N-(y_i-w^Tx_i)^2$$
我们要使得概率最大也就是使得似然函数最大:
$$max\sum_{i=1}^N-(y_i-w^Tx_i)^2$$
也就是(去掉负号):
$$min\sum_{i=1}^N(y_i-w^Tx_i)^2$$
完成!是不是发现这和最小二乘法给出的公式(loss function)是一样的?因为最小二乘法是最大似然解法的一种特殊情况.
从最大似然解法的推导中我们可以看到:均方误差最小化求解线性回归和假设预测符合高斯分布然后利用最大似然估计求解线性回归得到的结果是相同的

总结

虽然是最简单的线性回归的推导,但是从概率的角度利用最大似然来推出loss function的那一刻还是感觉到:数学真炫酷啊~
之前看机器学习的时候感觉数学公式看到就很头疼,但是现在自己硬着头皮推一遍之后发现并没有那么复杂而且通过这种硬盒的方式来学机器学习的算法是获益匪浅.最后再说一句:qsc的视频我是期期都看啊~

需知

本文主要的内容是Hadoop-3.1.0安装Tez-0.9.1的坑和细节,详细的安装过程请参照官网的安装教程.

Hadoop生态的安装还是坑很多,很多时候安装配置之后能启动起来现在想想都还是运气好,个人感觉Hadoop生态最坑的还是各个框架之间的版本配合问题了,因为看文档说Hadoop升级到3之后性能提升了很多,也就在正式环境上部署了Hadoop-3.1.0的版本,结果在尝试更换MR为Tez的时候还是遇到了
坑.**最主要的就是:**安装各个软件的时候一定要看好版本.

安装

因为Hadoop的版本为3.1.0,所以一定一定要选择0.9.1版本的Tez,因为在0.9.1版本的org.apache.tez.runtime.api的InputInitializerContext接口中才有_addCounters(TezCounters tezCounters)_这个方法,不然在启动Tez的时候会报NoSuchMethodError这个错误(个人感觉这个巨坑,0.9.0版本的API中就没有这个方法).Tez-0.9.1版本-org.apache.tez.runtime.api

下载

所以Hadoop3.1.0个人现在推荐下载0.9.1版本的包,更老版本的Tez在其他地方也出过一些问题,最后选择了0.9.1版本成功安装了.

Tez-0.9.1官网下载

下载时需要下载源码自己进行编译,因为官网的编译好的bin包默认的_Hadoop版本_是2.6的,安装时参照官网的安装教程

安装protobuf-2.5.0

在源码编译的时候,需要安装maven和protobuf(Tez依赖),在pom.xml中可以看到Hadoop version和protobuf版本的需求,protobuf version:2.5.0.

1
2
3
4
5
6
7
8
9
10
11
12
# 下载
wget https://github.com/google/protobuf/releases/download/v2.5.0/protobuf-2.5.0.tar.gz
# 解压
tar -xzvf ./protobuf-2.5.0.tar.gz
# 编译及安装
cd protobuf-2.5.0
# --prefix为安装位置
./configure --prefix=/usr/local/protobuf
make
make check
# make install时要使用root账户,否则会因为权限的问题报错
sudo make install

修改pom.xml

在tez目录下修改pom.xml,首先将hadoop version改为当前运行的Hadoop版本.

_(可选):_因为tez-ui依赖node.js以及bower, bower install时间过久而且报错,可以在pom.xml中搜索tez-ui模块并且注释掉.

安装node.js以及bower

1
2
3
4
5
6
7
# 环境为centOS,其他linux版本请修改命令
rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-remi
yum -y install nodejs npm --enablerepo=epel
npm install -g bower

开始编译

mvn clean package -DskipTests=true -Dmaven.javadoc.skip=true -Phadoop28 -Dhadoop.version=3.1.0

注意:一定要带版本 不然编译出错

package结束之后,文件在tez-dict/target目录中,将_tez-0.9.1-minimal.tar.gz_解压之后就是Tez的本体了,可以cp出来放到软件目录下,然后将_tez-0.9.1.tar.gz_放到Hadoop的HDFS中,接下来的配置_tez.lib.uris_在官网的教程和其他的安装教程中都可以找到,这里就不再赘述了.

总结

版本问题很重要!版本问题很重要!版本问题很重要!,在历次的Hadoop的坑中都是被版本所困扰,在选择Hadoop和其他的软件的时候一定要先考虑清楚版本的兼容性再开始安装,在兼容正确的情况下安装是非常非常的轻松的,但是一旦兼容出了问题,各种问题就会从各个地方出现.(血泪教训)

安装过程中报错调试常用的技巧

hive.log是最常用的查看错误的地方,但是在这次的安装中也查看了yarn的报错信息,主要是因为yarn节点没有能够正常启动起来导致报错信息不会向上抛出,直接使用yarn命名查看log会发现没有对应的错误信息,但是在Hadoop的log文件下面还是找到了yarn启动时的log

tail -f /tmp/{username}/hive.log

yarn报错之后信息在hadoop/logs/userlog下面的app中的container中的syslog文件中
因为启动时失败,直接使用yarn查看log是看不到错误信息的

0%