线性回归
首先,用线性回归的前提,线性线性,他是能区分可由一个直线(面)来回归模拟的数据。如果训练数据包含非线性关系,你需要选择:调整数据(进行数据转换)、增加特征数量(多项式回归,曲线)或改用其他模型。其次线性回归很容易受到异常值的影响,所以做线性回归时最好能剔除异常值。
线性回归的基本技巧都是先随机一条回归线,然后通过数据与点的举例进而逐步调整回归线,下面有几种方式:
一、梯度下降
整个梯度下降的过程不用想的太复杂,一言以蔽之,如图,对error function求导并求负就知道了w变量的方向,或者说是delta w,逐步循环迭代,从而到达error的最低点。
那么针对error function,课程中介绍了下面两种:
二、error function1:平均绝对误差 mean absolute error
那么通过平均绝对误差这个error function求导,则引出了我们的绝对值技巧absolute trik:
绝对值技巧,最根本的理念就是数据点希望回归线更靠近自己。那么为了应对这个理念,我们引入下面具体的知识。
线性的回归线除去输入x和输出y外,是由W回归线的斜率和b回归线在y轴上的偏移组成,那么想让线靠近数据点,改变的就是回归线的w和b,改变b会上线上下平移,而改变w则会改变回归线的角度。
那么如何改变呢,如上图,我们将w加上或减去x轴的大小(有正有负)*a学习速率,而b加上或者减去学习速率,具体加减是看数据与线的关系,如果点在线上我们是加上,点在线下我们是减去,这很好理解,就拿b来说,点在线下,线想更靠近点b,那么自然是像下平移。
三、error function2:平均平方误差 mean squared error
那么通过平均平方误差这个error function求导,则引出了我们的平方技巧square trick:
引入平方技巧的原因是,我们希望线不是按照固定的脚步去移动的,我们希望他在数据离他非常远的时候多移动一点,而在离的很近的时候少移动一点,这么来说的话,绝对值技巧就不够了,那么如下图:
可以看到我们将数据点到数据线的y方向距离计入了变化量当中。而且平方技巧还有个优点是统一了加减的符号,即使数据点在回归线之下我们仍是应用加号(因为q-y为负了)。
由上面所讲,其实我们也能看出使用平均绝对误差和平均平方误差最大的不同,那就是平方误差会将误差放大化,这样有助于我们找到更优的权重。
四、求解方程组方式来求w和b
当然我们也可以不用梯度下降方法来算w和b,可以直接用error function求w和b的偏导,将偏导都设为0,求解方程组,但因为我们可能有n维,那么计算会非常复杂,所以最好的方法还是梯度下降法,具体求解见相关图:
以上是线性方程求解的解法。
五、使用神经网络实现分段线性达到线性回归
首先这里介绍一个比较好的文章,点击这里
总的来说就是跟神经网络分类比较下,两个地方的区别:
(1)最后一层不激活,直接输出。或者说把激活函数看作f(x)=x
(2)损失函数函数改为MSE或者MAE(当然,MSE好求导,所以比较多)
六、sklearn中的线性回归
>>> from sklearn.linear_model import LinearRegression
>>> model = LinearRegression()
>>> model.fit(x_values, y_values)
>>> print(model.predict([ [127], [248] ]))
[[ 438.94308857, 127.14839521]]
sklearn,其实往后看会发现,都是一个流程,首先import 对应的模型,新建这个模型,用模型训练训练集,用模型测试测试集,很简单。
另外这里要特别注意一点,输入的x_values和y_values都是二维的,一条数据一行这样。
超参数:
感知器算法
这一节笔记请看【机器学习】第四篇、深度学习的第一部分内容
决策树
一、entropy 熵
其实在【机器学习】第四篇、深度学习中我也有提过(五),这里我照搬课程里的总结:集合越稳固或越具有同类性,其熵越低,反之亦然,换成我的理解的话,是对结果的不确定程度的度量,越不确定,熵越高(概率越低),越确定,熵越低(概率越高)。信息熵还可以作为一个系统复杂程度的度量,如果系统越复杂,出现不同情况的种类越多,那么他的信息熵是比较大的。
如果一个系统越简单,出现情况种类很少(极端情况为1种情况,那么对应概率为1,那么对应的信息熵为0),此时的信息熵较小。
下面放一下熵的正式定义:
举例:
上面呢,是信息熵,那么还有一个叫条件熵,我们的条件熵的定义是:定义为X给定条件下,Y的条件概率分布的熵对X的数学期望
设有随机变量(X,Y),其联合概率分布为
条件熵H(Y|X)表示在已知随机变量X的条件下随机变量Y的不确定性。随机变量X给定的条件下随机变量Y的条件熵H(Y|X)
下面推导一下条件熵的公式:
注意,这个条件熵,不是指在给定某个数(某个变量为某个值)的情况下,另一个变量的熵是多少,变量的不确定性是多少
因为条件熵中X也是一个变量,意思是在一个变量X的条件下(变量X的每个值都会取),另一个变量Y熵对X的期望。
其实条件熵意思是按一个新的变量的每个值对原变量进行分类,然后在每一个小类里面,都计算一个小熵,然后每一个小熵乘以各个类别的概率,然后求和。
我们用另一个变量对原变量分类后,原变量的不确定性就会减小了,因为新增了Y的信息,可以感受一下。不确定程度减少了多少就是信息的增益(下一个部分讨论)。
这里放出两篇比较好的文章一,信息熵,文章二,条件熵,上面部分内容取自这两篇文章。
二、信息增益
首先放个链接。
信息增益是特征选择的一个重要指标,它定义为一个特征能够为分类系统带来多少信息,带来的信息越多,说明该特征越重要,相应的信息增益也就越大。上面我们已经知道了信息熵(代表随机变量的复杂度(不确定度))和条件熵(代表在某一个条件下,随机变量的复杂度(不确定度)),那么信息的增益,就是基于上面两个熵得出的。直接上公式,信息增益 = 信息熵-条件熵。
换句话说,信息增益代表了在一个条件下,信息复杂度(不确定性)减少的程度。那么我们现在也很好理解了,在决策树算法中,我们的关键就是每次选择一个特征,特征有多个,那么到底按照什么标准来选择哪一个特征。这个问题就可以用信息增益来度量。如果选择一个特征后,信息增益最大(信息不确定性减少的程度最大),那么我们就选取这个特征作为决策点进行树操作,如此循环,持续找子树的最大增益,直到将树分割完全。
三、sklearn中的决策树
>>> from sklearn.tree import DecisionTreeClassifier
>>> model = DecisionTreeClassifier()
>>> model.fit(x_values, y_values)
>>> print(model.predict([ [0.2, 0.8], [0.5, 0.4] ]))
[[ 0., 1.]]
超参数:
最后备注下,课程中的随机森林,其实是一半属于决策树一半属于Bagging集成算法,主要是在Bagging上做操作,所以将随机森林知识点放到了集成算法中去
朴素贝叶斯Naive Bayes
一、先验概率,后验概率,条件概率,敏感性(真正例率),特异性(真负例率)
先验概率:
事件发生前的预判概率。可以是基于历史数据的统计,可以由背景常识得出,也可以是人的主观观点给出。一般都是单独事件概率,如P(x),P(y)。
后验概率:
事件发生后求的反向条件概率;或者说,基于先验概率求得的反向条件概率。概率形式与条件概率相同。
条件概率:
一个事件发生后另一个事件发生的概率。一般的形式为P(x|y)表示y发生的条件下x发生的概率。
这两其实不属于贝叶斯,不过贝叶斯的问题中常用这两名词,所以了解下:
敏感性:
特异性:
二、贝叶斯定理
可以参考知乎方便理解
贝叶斯定理是关于随机事件A和B的条件概率的一则定理。首先看下公式:
其中P(A|B)是指在事件B发生的情况下事件A发生的概率。
在贝叶斯定理中,每个名词都有约定俗成的名称:
- P(A|B)是已知B发生后A的条件概率,也由于得自B的取值而被称作A的后验概率。
- P(A)是A的先验概率(或边缘概率)。之所以称为"先验"是因为它不考虑任何B方面的因素。
- P(B|A)是已知A发生后B的条件概率,也由于得自A的取值而被称作B的后验概率。
- P(B)是B的先验概率或边缘概率。
按这些术语,贝叶斯定理可表述为:
后验概率 = (似然性*先验概率)/标准化常量
也就是说,后验概率与先验概率和相似度的乘积成正比。
另外,比例P(B|A)/P(B)也有时被称作标准似然度(standardised likelihood),贝叶斯定理可表述为:
后验概率 = 标准似然度*先验概率
具体计算就像课程中的举例一样:
三、朴素贝叶斯
既然知道了贝叶斯定理,那么我们直接放朴素贝叶斯的定义吧
朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。通俗来说,就好比这么个道理,你在街上看到一个黑人,我问你你猜这哥们哪里来的,你十有八九猜非洲。为什么呢?因为黑人中非洲人的比率最高,当然人家也可能是美洲人或亚洲人,但在没有其它可用信息下,我们会选择条件概率最大的类别,这就是朴素贝叶斯的思想基础。
简单概述一下,贝叶斯定理等式左边和等式右边的分子成比例,如图:
简单来说的贝叶斯定理和朴素贝叶斯的区别,贝叶斯定理中的特征必须相互独立,否则贝叶斯定理求出来的值为0,而朴素贝叶斯不需要,因为朴素贝叶斯是假设所有特征相互之间是独立的。
四、三种常用贝叶斯模型与sklearn中的贝叶斯
高斯朴素贝叶斯
有些特征可能是连续型变量,比如说人的身高,物体的长度,这些特征可以转换成离散型的值,比如如果身高在160cm以下,特征值为1;在160cm和170cm之间,特征值为2;在170cm之上,特征值为3。也可以这样转换,将身高转换为3个特征,分别是f1、f2、f3,如果身高是160cm以下,这三个特征的值分别是1、0、0,若身高在170cm之上,这三个特征的值分别是0、0、1。不过这些方式都不够细腻,高斯模型可以解决这个问题。高斯模型假设这些一个特征的所有属于某个类别的观测值符合高斯分布,也就是:
>>> from sklearn import datasets
>>> iris = datasets.load_iris()
>>> iris.feature_names # 四个特征的名字
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
>>> iris.data
array([[ 5.1, 3.5, 1.4, 0.2],
[ 4.9, 3. , 1.4, 0.2],
[ 4.7, 3.2, 1.3, 0.2],
[ 4.6, 3.1, 1.5, 0.2],
[ 5. , 3.6, 1.4, 0.2],
[ 5.4, 3.9, 1.7, 0.4],
[ 4.6, 3.4, 1.4, 0.3],
[ 5. , 3.4, 1.5, 0.2],
......
[ 6.5, 3. , 5.2, 2. ],
[ 6.2, 3.4, 5.4, 2.3],
[ 5.9, 3. , 5.1, 1.8]]) #类型是numpy.array
>>> iris.data.size
600 #共600/4=150个样本
>>> iris.target_names
array(['setosa', 'versicolor', 'virginica'],
dtype='|S10')
>>> iris.target
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,....., 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ......, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
>>> iris.target.size
150
>>> from sklearn.naive_bayes import GaussianNB
>>> clf = GaussianNB()
>>> clf.fit(iris.data, iris.target)
>>> clf.predict(iris.data[0])
array([0]) # 预测正确
>>> clf.predict(iris.data[149])
array([2]) # 预测正确
>>> data = numpy.array([6,4,6,2])
>>> clf.predict(data)
array([2]) # 预测结果很合理
多项式朴素贝叶斯
该模型常用于文本分类,特征是单词,值是单词的出现次数。
其中,N_ykxi是类别yk下特征xi出现的总次数;N_yk是类别yk下所有特征出现的总次数。对应到文本分类里,如果单词word在一篇分类为label1的文档中出现了5次,那么N_label1,word的值会增加5。如果是去除了重复单词的,那么N_label1,word的值会增加1。n是特征的数量,在文本分类中就是去重后的所有单词的数量。α的取值范围是[0,1],比较常见的是取值为1。
待预测样本中的特征xi
在训练时可能没有出现,如果没有出现,则N_ykxi值为0,如果直接拿来计算该样本属于某个分类的概率,结果都将是0。在分子中加入α,在分母中加入αn可以解决这个问题。
下面的代码来自sklearn的示例:
>>> import numpy as np
>>> X = np.random.randint(5, size=(6, 100))
>>> y = np.array([1, 2, 3, 4, 5, 6])
>>> from sklearn.naive_bayes import MultinomialNB
>>> clf = MultinomialNB()
>>> clf.fit(X, y)
MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)
>>> print(clf.predict(X[2]))
[3]
值得注意的是,多项式模型在训练一个数据集结束后可以继续训练其他数据集而无需将两个数据集放在一起进行训练。在sklearn中,MultinomialNB()类的partial_fit()方法可以进行这种训练。这种方式特别适合于训练集大到内存无法一次性放入的情况。
在第一次调用partial_fit()时需要给出所有的分类标号。
>>> import numpy
>>> from sklearn.naive_bayes import MultinomialNB
>>> clf = MultinomialNB()
>>> clf.partial_fit(numpy.array([1,1]), numpy.array(['aa']), ['aa','bb'])
GaussianNB()
>>> clf.partial_fit(numpy.array([6,1]), numpy.array(['bb']))
GaussianNB()
>>> clf.predict(numpy.array([9,1]))
array(['bb'],
dtype='|S2')
伯努利朴素贝叶斯
伯努利模型中,对于一个样本来说,其特征用的是全局的特征。
在伯努利模型中,每个特征的取值是布尔型的,即true和false,或者1和0。在文本分类中,就是一个特征有没有在一个文档中出现。
如果特征值xi值为1,那么
如果特征值xi值为0,那么
这意味着,“没有某个特征”也是一个特征。
下面的示例来自sklearn官方文档:
>>> import numpy as np
>>> X = np.random.randint(2, size=(6, 100))
>>> Y = np.array([1, 2, 3, 4, 4, 5])
>>> from sklearn.naive_bayes import BernoulliNB
>>> clf = BernoulliNB()
>>> clf.fit(X, Y)
BernoulliNB(alpha=1.0, binarize=0.0, class_prior=None, fit_prior=True)
>>> print(clf.predict(X[2]))
[3]
BernoulliNB()类也有partial_fit()函数。
SVM支持向量机
一、支持向量(Support Vector),决策面(超平面hyperplane),间隔(magin)
支持向量 Support Vector
如图所示,支持向量 (Support Vector)是指在训练集 (Training data set)中,在分类时给予最多信息的点集合,被红色框围起来的这四个训练资料点就被称之为支持向量机。
支持向量就是与分类边界距离最近的训练资料点。从支持向量机的最佳化问题可以推导出一个重要性质:支持向量机的分类边界可由支持向量决定,而与其他资料点无关。这也是它们称为“支持向量”的原因。
决策面(超平面hyperplane)
面对一个线性可分的二分类问题,将正负样本分开的超平面,称为决策面。如图,下面三条线都是决策面。
和 线性回归 模型一样,这里一般会使用一些特征函数ϕ(x),将输入空间映射到新的特征空间中,再进行计算。
这里f(⋅) 叫做激活函数,w是线性模型的系数,b一般被叫做偏置:
这里输出的取值为 t∈{+1,−1} ,即正负样本。这里的 {+1,−1} 仅仅是一个标号,代表正负样本,并不是具体的数值。如果感觉不喜欢{+1,−1},使用{0,1}也行。而且,可以使用{+1,−1}主要也是因为这里是二分类问题,遇到多分类问题的时候,还得考虑其他的标号方式。
作为一个决策面:
当样本的标号 t_n=+1的时候,该样本为正样本。如果样本被正确分类,那么 wTϕ(x_n)+b>0,f(wTϕ(x)+b)=+1
当样本的标号 tn=−1的时候,该样本为负样本。如果样本被正确分类,那么 wTϕ(x_n)+b<0,f(wTϕ(x)+b)=−1
注意这里引入的特征函数ϕ(x)其实就是我们课程中所对应的不同的核函数kernel function,他将我们的输入映射到不同的空间上去(传说中的维度变换),从而达到线性可分(面)的目的
最优决策面和间隔
我们在感知机那节就知道我们让数据可分,误差最小的解不止一个,就跟上面决策面那个图一样,那么哪个决策面是最好的呢?
那么,这些训练误差最小的感知机模型中,如何针对当前数据集,选择一个最好的感知机模型呢?现在就需要考虑模型的 泛化误差 了。即,在所有训练误差最小的感知机中,选择泛化误差最小的那个感知机,这就是SVM算法最初的目的。
基本的SVM(最大间隔分类器)是一种二分类模型,它是定义在特征空间上的间隔最大的线性分类器,间隔最大是SVM和感知机不同的地方,间隔最大化对应于泛化误差最小。
最大间隔分类器认为,决策面的泛化误差可以用训练样本集合中,离决策面最近的样本点到决策面的间隔(margin)来表示,离决策面最近的样本点,到决策面的间隔(margin)越大,那么,这个决策面的泛化误差就越小。直观的来讲,最优决策面差不多就是下面这幅图中,中间的那个决策面。
什么是间隔?
答:首先,要搞清楚是谁和谁的间隔,在这里指的是一个 训练样本点 和 决策面 之间的间隔。
那么,间隔又如何定义的呢?
答:间隔,就是样本点到决策面之间的距离,由中学的知识就可以知道,一个样本点 x_n
到一个面 w^Tϕ(x)+b=0,的距离为(这里可以直接认为是点到直线的距离):
但这个距离在数值上会存在正负的问题,由于样本点类别取值 tn∈{+1,−1} ,所以样本点到决策面的间隔可以改为:
当 t_n=+1的时候,如果样本被正确分类, w^Tϕ(x_n)+b>0,上述样本点到决策面的间隔 rn 取正值
当 t_n=−1的时候,如果样本被正确分类, w^Tϕ(x_n)+b<0,上述样本点到决策面的间隔 rn 仍然取正值
这样,分类正确的样本点的间隔就永远是正的了。
显然,一旦决策面有了,那么训练集合中的每个样本点 xn 到决策面都会有一间隔 rn 。自此,就可以定义样本集合到决策面最小的间隔 r 为:
既然 r 是最小间隔,毫无疑问,对于任意一个样本点 x_n 而言:
二、边际误差magin error - 最小间隔最大化
要使用决策面在训练样本中的最小间隔 r 来表示决策面的训练误差:最小间隔 r 越大,那么其泛化误差就越小,模型就越好。而我们这里,就是在所有可选的决策中,找出其对应的最小间隔 r 最大的那个决策面,而决策面是用参数 w 和 b 定义的,所以,最小间隔最大化可以形式化为:
用优化理论的形式重写一下上面的式子,可以得到:
将上面的约束条件变一下型可得:
在前面已经提到过,对于一个决策面wTϕ(xi)+b=0 而言, 重要的不是w 和 b 的取值,w^Tϕ(x)+b=0 和 2w^Tϕ(x)+2b=0 的所得到的x的点集是一样的,即其决策面是一样的,这里真正重要的是 w 和 b的比值。
w和 b的比值,决定了一个决策面的点集,也就决定了一个决策面。
所以,只要有一个决策面,那么,唯一确定的是w和 b 的比值,但是,w 和 b 具体的取值是可以改变的,只要w 和 b按比例改变,决策面就是确定不变的。
也就是说,w和 b 的比值比值不变的情况下,w是可以任意取值的。这样的话,为了便于计算,我们就取:
那么,上面的式子又可以改写为:
可以看到,上面的式子最大化的目标函数变成了 1/||w|| ,很容易知道,其等价于 最小化 ||w||^2 ,那么最小间隔最大化,最终就可以变为下面这个最小化的约束优化问题:
这里,最小间隔为:
最小间隔最大化后得到的决策面,就是我们要找的泛化误差最小的决策面。对于下图中两特征的二分类问题而言,可以看出, 最小间隔为1/||w||,即,正样本到决策面的最小间隔为1/||w||;同时,负样本到决策面的最小间隔也为1/||w||。所以正负样本之间的最小间隔为2/||w||。
由于间隔最小的样本点 x_n 满足:
所以,间隔最小的正样本点 x_n 满足:
间隔最小的负样本点 x_n 满足:
这里定义,拥有最小间隔的正负样本点为支持向量(support vector),也就是上图中w^Tϕ(x_n)+b=1 和 w^Tϕ(x_n)+b=−1 所对应的那三个样本点。
ps一下再次解释support vector
关于支持向量机的名字,这里可以稍微说一下,因为这个名字并不是特别的好理解。首先是支持(support),根据柯林斯词典,support的主要意思:the activity of providing for or maintaining by supplying with money or necessities,表示的是提供一些必须品的意思。vector指的就是样本点,这个问题不大。那么问题来了,为什么将间隔最小的那些样本点叫做support vector(或者可以直接说是support point)呢?答:从图中可以看出,对于决策面而言,要想唯一的确定这个决策面,就是要根据最小的间隔 r 来得到,也就是说,决策面仅仅和拥有最小间隔的那些样本点相关,和其他那些间隔大于最小间隔的样本点,是没有关系的。即:拥有最小间隔的那些样本点是决策面所必须的,而间隔大于最小间隔的样本点的有无,对决策面并不构成影响。所以将拥有最小间隔的那些样本点叫做support point, 也就是support vector。
上面是一种解释方法,当然我们课程中是另外一种解释方法:
假设了三根线
Wx+b=1
Wx+b=0
Wx+b=−1
由于这三条线为等距平行线,要想确定第一条线和第三条线之间的距离,我们只需要计算前两条线之间的距离,接着将这个数字乘以二。这也就是说我们需要确定图 1 中前两条线之间的距离。
请注意,由于我们只需计算线条之间的距离,因此也可以将线条平移,直到其中一条线与原点相交。这时得到的方程如下:
Wx=0
Wx=1
现在,第一条线的方程为 Wx=0,这意味着它与标记为红色的向量 W=(w1,w2)垂直
该向量与方程为 Wx=1 的线条相交于蓝点。假设该点的坐标为 (p,q)。那么我们可以得到下面两个结果:
- w1p+w2q=1(由于该点位于这条线上)
- 该点位于向量 W=(w1,w2)上,(p,q)是 (w1,w2)的倍数。
三、分类误差与误差函数
上面的图就比较明了了,他并非用决策面来做分类error的,而是通过margin线来做分类error的。
知道了classification error和margin error,最后就是将两者相加作为总的error,进行梯度下降来进行优化
针对误差函数我们有一个参数可以调试,那就是C参数,他控制分类错误的比重,来让模型选择是否接受多一些的错误从而来达到更大的magin。
四、核函数kernel function
首先推荐的写的比较好的博文
其实我们前面也说过ϕ(x)这个变换我们输入的函数就是传说中的kernel function,最简单最容易理解的kernel function其实就是多项式kernel,他将我们二维的数据映射到三维中甚至更高维度中,来寻求线性可分的超平面,用下面的图更好理解,不管是直接使用线性函数还是多项式函数,其实方法追其根本是一样的。
一个函数是否能称为核函数,是有非常严格的要求的,但是,我们在实际的使用中,一般都会使用一些常用的核函数,这里提供四个最常用的核函数。
那么我们核函数重点就是RBF kernel
RBF(radio basis function) kernel:
RBF非常实用,这里推荐一个油管视频
从下图可以看出,RBF的基本模型其实是衡量dataset与x_n的距离的影响和,下图最顶的位置就是x_n,如果某个点x,越远则影响越小,越下面,越近,则影响越大,越接近顶端,
而rbf算法,其实就是求解w,让ϕ(x) = y,如下图:
那么如下图,跟我们所理解正态分布中的结果一样,gamma越大,sigmod越小,那么图形越瘦,反之,gamma越小,曲线越平坦。
五、[sklearn 中的支持向量机])(http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html)
>>> from sklearn.svm import SVC
>>> model = SVC()
>>> model.fit(x_values, y_values)
>>> print(model.predict([ [0.2, 0.8], [0.5, 0.4] ]))
[[ 0., 1.]]
集成算法
随机森林random forest vs bagging(bootstrap aggregation) vs boosting
以下内容部分参考这里
注意,bagging和boosting不仅试用于树,还试用于其他算法。
Bagging的策略:
- 从原始样本集中抽取训练集。每轮从原始样本集中使用Bootstraping的方法抽取n个训练样本(在训练集中,有些样本可能被多次抽取到,而有些样本可能一次都没有被抽中)。共进行k轮抽取,得到k个训练集。(k个训练集之间是相互独立的)
- 每次使用一个训练集得到一个模型,k个训练集共得到k个模型。(注:这里并没有具体的分类算法或回归方法,我们可以根据具体问题采用不同的分类或回归方法,如决策树、感知器等)
-
对分类问题:将上步得到的k个模型采用投票的方式得到分类结果;对回归问题,计算上述模型的均值作为最后的结果。(所有模型的重要性相同)
Random Forest是Tree + Bagging的改良,其实也是一种bagging的方式。
- 从样本集中用Bootstrap采样选出n个样本
- 在树的每个节点上,从所有属性中随机选择k个属性,选择出一个最佳分割属性作为节点
- 重复以上两步m次,i.e.build m棵CART
- 这m个CART形成Random Forest
Random Forest可以既可以处理属性为离散值的量,也可以处理属性为连续值的量。
跟bagging的区别是,bagging随机取的样本,Random Forest既随机取了样本,而后又随机取了属性。
最后是boosting
其主要思想是将弱分类器组装成一个强分类器。在PAC(概率近似正确)学习框架下,则一定可以将弱分类器组装成一个强分类器。
关于Boosting的两个核心问题:
1)在每一轮如何改变训练数据的权值或概率分布?
通过提高那些在前一轮被弱分类器分错样例的权值,减小前一轮分对样例的权值,来使得分类器对误分的数据有较好的效果。
2)通过什么方式来组合弱分类器?
通过加法模型将弱分类器进行线性组合,比如AdaBoost通过加权多数表决的方式,即增大错误率小的分类器的权值,同时减小错误率较大的分类器的权值。
而提升树通过拟合残差的方式逐步减小残差,将每一步生成的模型叠加得到最终模型。
关于应用最多的boosting Adaboost
Adaboot(自适应增强算法)
算法过程如下:假设拟合第一个学习器,以最大程度保证准确率,或最小程度上减少数量,接着拟合第二个学习器,第二个学习器需要修正第一个学习器的错误,所以我们需要筛选出错误,放大这些错误的权重,使错误的点新的权重相加与正确的点权重相加的和相等,那么这个学习器就着重修正这些错误的点了,以此循环,第三个学习器继续修正第二个学习器的错误,建立在放大第二个学习器判断错误点的权重上,同样使错误的点新的权重相加与正确的点权重相加的和相等,等等,直到建立够我们所需的弱学习器数量,接着,设置这些弱学习器的权重通过weight = ln (correct/incorrect)来求得,最后进行弱学习器的融合,通过上面弱学习的权重来融合,以此来结合强学习器。
伪代码如下:
Bagging,Boosting二者之间的区别
1)样本选择上:
Bagging:训练集是在原始集中有放回选取的,从原始集中选出的各轮训练集之间是独立的。
Boosting:每一轮的训练集不变,只是训练集中每个样例在分类器中的权重发生变化。而权值是根据上一轮的分类结果进行调整。
2)样例权重:
Bagging:使用均匀取样,每个样例的权重相等
Boosting:根据错误率不断调整样例的权值,错误率越大则权重越大。
3)预测函数:
Bagging:所有预测函数的权重相等。
Boosting:每个弱分类器都有相应的权重,对于分类误差小的分类器会有更大的权重。
4)并行计算:
Bagging:各个预测函数可以并行生成
Boosting:各个预测函数只能顺序生成,因为后一个模型参数需要前一轮模型的结果。
这两种方法都是把若干个分类器整合为一个分类器的方法,只是整合的方式不一样,最终得到不一样的效果,将不同的分类算法套入到此类算法框架中一定程度上会提高了原单一分类器的分类效果,但是也增大了计算量。
下面是将决策树与这些算法框架进行结合所得到的新的算法:
1)Bagging + 决策树 = 随机森林
2)AdaBoost + 决策树 = 提升树
3)Gradient Boosting + 决策树 = GBDT
sklearn 中的集成方法
>>> from sklearn.ensemble import AdaBoostClassifier
>>> model = AdaBoostClassifier()
>>> model.fit(x_train, y_train)
>>> model.predict(x_test)
正则化 Regularization
正则化其实穿插在各个算法中,主要作用是为了防止过拟合,起到降低模型复杂度的作用。通常是使用范数作为正则化项,使用较频繁的是L1范数和L2范数。
那么讲到范数,首先要了解什么是范数?
在线性代数等数学分支中,范数(Norm)是一个函数,其给予某向量空间(或矩阵)中的每个向量以长度或称之为大小。对于零向量,其长度为零。直观的说,向量或矩阵的范数越大,则我们可以说这个向量或矩阵也就越大。有时范数有很多更为常见的叫法,如绝对值其实便是一维向量空间中实数或复数的范数,范数的一般化定义:设 p≥1p≥1 ,p-norm用以下来表示
此处,当p=1时,我们称之曼哈顿范数(Manhattan Norm)。其来源是曼哈顿的出租车司机在四四方方的曼哈顿街道中从一点到另一点所需要走过的距离。也即我们所要讨论的L1范数。其表示某个向量中所有元素绝对值的和。 而当p=2时,则是我们最为常见的Euclidean norm。也称为Euclidean distance,中文叫欧几里得范数,也即我们要讨论的L2范数,他也经常被用来衡量向量的大小。 而当p=0时,严格的说此时p已不算是范数了,但很多人仍然称之为L0范数。
那么我们引入范数作为正则化项的作用是什么呢?
先看一个加入正则化项的损失函数的例子:
正则化是对w权重做了约束,那么就是在原有模型error的基础上,与模型权重的均衡,w越大,模型复杂度越高,那么自然加号两边的权衡会让模型达到相对来说的更优。
一般都会在正则化项之前添加一个系数,Python中用α表示,一些文章也用λ表示。这个系数需要用户指定。而这个λ规定的是对L2惩罚项的比重,如果λ越大,对模型复杂度的惩罚度越高,模型越简单,反之λ越小,模型越自由,模型会偏向复杂。
下面的图展示整理正则化的例子,方便理解:
可以看出左右两边模型的复杂度和w权重,很明显如果不加正则项,我们最优的模型是右边的。
很明显,如果加上L1或者L2惩罚项:
那么结果就会不同了,我们会更趋向于选择简单的模型。
那么来看下λ的引入:
λ的大小也影响了模型的选择,改变了对权重正则项的“重视程度”。
那么最后来看下L1和L2的区别:
最后给出一片很好的文章的链接,来帮助理解。