机器学习笔记

序言

最近在看机器学习相关的知识,然而当时看懂了,时间一久就忘了。我可不是张无忌在学太极,忘了是不行的。记下一些当时看懂的,好的基本点和相关链接,尤其是当时的aha moment,希望后续后帮助。长远看当知识形成体系之后,会再做整理。
理解这些方法,可以参照各个博客,但是很多博客都只有只言片语,很多都语焉不详,但是看看原始论文,就能恍然大悟。

概述

机器学习要解决的问题可以分成两大类:分类和回归。所谓分类,就是顾名思义的分类;相对的,回归是预测具体的值而不是一个类别。举个例子,预测明天的天气(晴、阴、雨、雪、雾)是分类问题;预测明天的气温是回归问题,因为温度是连续的,不是离散的几个值。

从方法上来说,可以分成几大类:传统的统计机器学习(贝叶斯、马尔科夫等),决策树(xgboost, adaboost, gdbt等)和神经网络(DNN,CNN,RNN).

各个方法基本都涉及到的问题:损失函数,模型训练等。

特征工程

One-Hot 编码

这个在神经网络(不止限于神经网络是很重要的一个概念),一个简单的理解:

比如根据水果的特征来对水果进行分类,颜色是其中的一个特征。我们可以只用一个维度来表示这个特征,0-红色,1-黄色,2-绿色,3-橙色,4-紫色,5-白色。这里的问题是特征表示的是一个相似性的距离问题,因为只有一个数字,这里就默认了黄色比紫色和红色相比更加相似,然而这个假设是不一定成立的,即使成立,应该由训练来得出,而不应是处理特征的时候就加了这个假设。为了解决这个问题,常用的解决办法是One-Hot编码,对于红色、黄色、绿色的编码分别为
R e d = [ 1 , 0 , 0 , 0 , 0 , 0 ] Y e l l o w = [ 0 , 1 , 0 , 0 , 0 , 0 ] G r e e n = [ 0 , 0 , 1 , 0 , 0 , 0 ] . . . \begin{aligned} Red&=[1,0,0,0,0,0]\\ Yellow&=[0,1,0,0,0,0]\\ Green&=[0,0,1,0,0,0]\\ ... \end{aligned} RedYellowGreen...=[1,0,0,0,0,0]=[0,1,0,0,0,0]=[0,0,1,0,0,0]
除了对应的位置为1其余都是0,这样好处就是Red/Yellow/Green在空间的距离都是1,他们相互之间都是一样的,坏处也显而易见,特征维数爆炸。如果很多特征都用One-Hot来编码,总的特征维数就是所有可用label的乘积,维数相当高。维数高有两个问题:1.运算量大;2.数据稀疏。通常的做法是在输入之后加入一个维度低很多的神经网络隐层,做一个降维,这个降维之后的向量就是embedding(全连接层只是降维的一种手段,还有其他的,比如FM里的 w i = < v i , v j > w_i=\bold{<v_i,v_j>} wi=<vi,vj>)
这样表示并非总是合理,比如在NLP中,实际使用One-Hot编码不能体现出近义词和非近义词的差别,使用One-Hot就不太合理。在NLP中也是会使用多加一层神经网络计算embedding,使用embedding表示单词,可以解决近义词问题。并且由于NLP中,段落本身就是文本,可以只用非监督学习来得出embedding.

传统统计学方法

这部分积累还比较少,待之后补充

决策树

据说决策树的方法在各种kaggle比赛中大行其道,然而从原理上,这么个感觉上相对粗糙的做法很难想象能有这么好的效果。这种现象产生的原因可能是kaggle上的问题数据量相对较小,数据量较小的时候,决策树会把信息上最大的特征放在第一层分类,这是一种贪心算法,相当于在人的干预下对参数作了优化,这种优化在数据量较小的情况下,NN模型是很难学到的。但是当数据量变大的时候,这种“贪心”中的局部最优问题会有一些影响。
决策树的生成一些常用算法C4.5,ID3和CART等.
C4.5 https://www.cnblogs.com/gispathfinder/p/5770217.html
ID3 C4.5是ID3的提升
CART 损失函数是GINI系数
这几个算法都是一些数学公式和定义,顾名思义也挺好理解的。
一些决策树方法

神经网络

组件

Logit函数

l o g i t ( p ) = l n ( p 1 − p ) = w T x logit(p)=ln(\frac p {1-p})=w^Tx logit(p)=ln(1pp)=wTx
实际上logit函数是sigmoid函数的反函数,一个神经网络最终的输出概率会在输出层的使用一个活化函数

Sigmoid函数

p = s i g m o i d ( w T x ) = 1 1 + e − w T x p=sigmoid(w^Tx)=\frac 1 {1+e^{-w^Tx}} p=sigmoid(wTx)=1+ewTx1
sigmoid函数有有很多很好的特性:

  1. 输出范围(0,1),恰好在概率区间中;
  2. 其导数为 f ( z ) ′ = f ( z ) − f ( z ) 2 f(z)'=f(z)-f(z)^2 f(z)=f(z)f(z)2,因为导数可以表示为自身的形式,在进行梯度下降中可以减少计算量。

Softmax

Softmax实际是对Sigmoid函数的推广,Sigmoid只适用于二元输出场景,对于多元,可以只用softmax
s o f t m a x ( x i ) = e x i ∑ j = 1 n e x i softmax(x_i)=\frac {e^{x_i}} {\sum\limits_{j=1}^n{e^{x_i}}} softmax(xi)=j=1nexiexi
例如如果输出是 l o g i t ( x ) = [ − 0.1 , 2 , 4 ] logit(x)=[-0.1,2,4] logit(x)=[0.1,2,4],这样的输出是没法用作概率的,并且当最终的输出不加范围限制的时候,模型不太容易收敛。为了解决这个问题,可以对输出做一个softmax(可以使用python的scipy.special.softmax进行计算)变换得到 p ( x ) = [ 0.01554136 , 0.04668881 , 0.93776983 ] p(x)=[0.01554136,0.04668881,0.93776983] p(x)=[0.01554136,0.04668881,0.93776983].

这里我们考虑一个思考题,已知softmax之后的概率,能否求出原始的logit呢?答案是不能,因为有无数多组解。可以写出三个式子,但是其中只有两个是线性无关的。
{ e x 1 ∑ i = 1 3 e x i = a e x 2 ∑ i = 1 3 e x i = b e x 3 ∑ i = 1 3 e x i = c \def\ss {\sum\limits_{i=1}^3e^{x_i}} \gdef\eqai#1{\frac{e^{x_#1}}{\ss}} \begin{cases} \eqai{1}=a\\ \eqai 2=b\\ \eqai{3}=c\\ \end{cases} i=13exiex1=ai=13exiex2=bi=13exiex3=c
明显,方程两边同时1-(1)-(2)即可得到(3)。

如何理解softmax是sigmoid的更一般形式呢?对于sigmoid函数,输入是一个值 x x x,而不是向量,但是可以转换成向量的形式 [ x , 0 ] [x,0] [x,0],这样,使用softmax函数和sigmoid函数的结果就是一样的。

Hierachical Softmax

Softmax最大的问题是计算量的问题,尤其是在NLP中,对于使用One-Hot编码的单词,如果单词有20000个,每次预估和训练,都要对计算20000次指数幂,运算量相当大,有人提出了Hierachical Softmax来解决这个问题,本质上是使用一棵树来取代softmax.

常见神经网络

最简单的神经网络就是LR了。
y ^ = s i g m o i d ( ∑ i = 1 n w i x i ) \hat y = sigmoid(\sum_{i=1}^nw_ix_i) y^=sigmoid(i=1nwixi)
但是这个只有一层,没法解决异或问题,并且没有考虑二维特征交叉问题。
在推荐系统中FM可以解决特征交叉问题,并且不会导致引入二维特征交叉之后的稀疏问题。实际上FM就是一种降维,也是一种计算embedding的方式。

NLP

总领链接
NLP作为一个单独部分
distributed representations(词向量) 是相对于one-hot来说的,不是在一个特定的位置放一个1来表示,而是使用连续值的向量来表示,所以词向量是一个意译。这样做的好处有两个:1. 降低表示一个单词所使用的维度,从而降低训练和预测的计算量;2.能够表示不同单词的相近程度,包括词性、近义词等。

Word2Vec

这篇文章介绍了word2vec的精髓,简明扼要,CBOW和Skip-Gram都有讲到,相当直观了。但是现在看NLP里主要的文章都是拿来做这种概率分析,指望这个怎么做语义分析和和语句生成?太原始了吧?就这?

Attention

一些有意思的问题

1. 神经网络使用的活化函数一般是单调的,神经网络可以预测非单调函数吗(比如二次函数)?
答案:可以,但是要保证网络结构满足条件。
以预测二次函数 y = f ( x ) = x 2 y=f(x)=x^2 y=f(x)=x2为例,我们可以构建一个 1 × N 1 × N 2 × 1 1 \times N_1\times N_2\times 1 1×N1×N2×1的网络,则
{ h 1 = σ ( ∑ i = 1 i = N 1 w i ( 1 ) x + b i ( 1 ) ) y ˉ = σ ( ∑ i = 1 i = N 2 w i ( 2 ) h 1 + b i ( 2 ) ) \begin{cases} h_1=\sigma(\sum \limits _ {i=1}^{i=N_1}w_i^{(1)}x+b_i^{(1)}) \\ \bar y=\sigma(\sum\limits_{i=1}^{i=N_2}w_i^{(2)}h_1+b_i^{(2)}) \end{cases} h1=σ(i=1i=N1wi(1)x+bi(1))yˉ=σ(i=1i=N2wi(2)h1+bi(2))
为了简化,我们假设第一层只有两个神经元,如果第一层的第一个神经元权值 w 1 ( 1 ) > 0 , b 1 ( 1 ) < 0 , w 2 ( 1 ) < 0 , b 2 ( 1 ) < 0 w_1^{(1)}>0, b_1^{(1)}<0, w_2^{(1)}<0, b_2^{(1)}<0 w1(1)>0,b1(1)<0,w2(1)<0,b2(1)<0。此时,对于 x > 0 x>0 x>0。因为权重和偏置都为负,神经元 A 2 A_2 A2进入了饱和区,没有区分度,但是神经元 A 1 A_1 A1可以处在非饱和区,有区分度,且保证x和y有正相关关系。同样的,对于x<0,神经元 A 1 A_1 A1处于饱和区,神经元 A 2 A_2 A2处于非饱和区有区分度,且且保证x和y有负相关关系。

    def test_backpropagation(self):
        # 实现定制化模型,来看看各个层上的权重变化
        input = Input(shape=(1,))
        x = input
        h1 = Dense(2, activation='sigmoid', )(x)
        y = Dense(1, activation='sigmoid', )(h1)
        model = Model(inputs=input, outputs=y)
        model.compile(optimizer=RMSprop(learning_rate=0.0001), loss=MeanSquaredError(),
                      metrics=['AUC', 'MeanSquaredError', 'BinaryCrossentropy'], )
        model.summary()

        to_raw = lambda np_arr: list(map(lambda np_ele: np_ele.tolist(), np_arr))
        weights = model.get_weights()
        print(f" weights type {type(weights)} and element type {type(weights[0])} and element 0 {weights[0].tolist()}")
        print(f"model weights: {to_raw(model.get_weights())}")

        x_train = np.linspace(-1, 1, 100)
        y_train = x_train ** 2
        print(f"x is {x_train} and y is {y_train}")
        tensorboard = TensorBoard()
        model.fit(x_train, y_train, epochs=90000, callbacks=[tensorboard])
        y_pred = model.predict(x_train)
        print(f"predicted: {model.predict(x_train)}")
        print(f"model weights: {to_raw(model.get_weights())}")
        plt.plot(x_train, y_train)
        plt.plot(x_train, y_pred)
        plt.legend(labels=('y_train', 'y_pred'))
        plt.show()

模型权重和之前推导并不一致。因为之前只是一种可行解,以下解也是可以的。
[[[-4.884231090545654, -5.03098726272583]], [-3.347017765045166, 3.366368532180786], [[6.211307525634766], [-6.000507831573486]], [2.83687686920166]]

一个预测的示例
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值