machine_learning
课程地址
https://www.coursera.org/learn/machine-learning
两种定义:
“关于赋予计算机一种不需要显式编码的学习能力的研究领域”——来自Arthur Samuel的旧定义
“一个计算机程序可以从一些类别任务T和表现衡量P相关的经验E中进行学习,如果它在任务中的表现T,由P来衡量,随着经验E而完善。”——来自Tom Mitchell的更现代的定义
例子:玩西洋棋
E = 玩很多西洋棋的经验
T = 玩西洋棋的任务
P = 程序赢得下一盘游戏的概率
通常来说,任何机器学习问题都可以分为两大类:监督学习和无监督学习
在监督学习中我们拥有一个数据集并已经知道正确的输出是怎样的,知道输入和输出之间有关系。
监督学习可以分为“回归”和“分类”问题。在回归问题中,我们尝试在连续输出中预测结果,意味着我们把输入变量映射到一些连续函数。在分类问题中,我们尝试以离散输出形式预测结果,把输入变量映射到离散类别中。
无监督学习允许我们解决不知道或者很少知道结果是怎样的问题。我们可以从数据中获得结构,在这些数据中我们不必知道变量的效果。
我们可以根据数据中变量的关系对数据进行聚集,来获得这个结构。
无监督学习没有根据预测结果的反馈,即没有老师来更正你。
分为聚类问题和非聚类问题(鸡尾酒派对问题)
在回归问题中,我们用输入变量把输出值拟合到一个连续函数上。
单变量线性回归也叫“通用线性回归”。
当你想从一个单输入变量X预测一个单输出变量y的时候,通用线性回归就得到使用。
我们这时在做监督学习,所以这意味着我们已经知道输入输出的原因和效果应该是怎样。
我们的假设函数有以下一般形式:
我们可以用一个损失函数来衡量假设函数的精准性。
这采用所有从X的输入得到的假设结果与实际的输出y之间比较的平均值(实际上是一种更新奇的平均数版本)。
如果我们尝试从视觉角度来看,我们的训练数据集分散在x-y平面上。我们正尝试画一条直线(由定义),它穿过这个分散的数据集。我们的目标是得到最合适的直线。最合适的直线将会使得分散的点到直线的垂直距离的平方的的均值最小。在最好的情况下,这条线会穿过所有训练集中的点。在这中情况下的值是0。
现在我们有了假设函数和衡量它能多好地拟合数据的方法。现在我们需要估计假设函数中的参数。
这就是梯度下降的用武之处。
假想我们根据和画出来假设函数(实际上我们画出损失函数作为参数估计的函数)。这有点令人疑惑;我们开始更高层的抽象。我们不是在画x和y自身,而是假设函数的参数范围和选择特定参数集带来的损失。
我们把放在x轴上,放在y轴上,损失函数放在垂直的z轴上。图像上的点将会是随着那些特定的theta参数使用我们的假设得到的损失函数的结果。
我们都知道当我们的损失函数在图像的凹点的底部时我们就成功了,即当它的值最小时。
做到这个的方法是通过计算损失函数的导数(函数的切线)。切线的斜率就是那个点的导数,并给予我们移动的方向。我们沿着梯度最陡峭的方向一步步走下损失函数,每步 的大小由一个参数决定,叫做学习率。
梯度下降算法是:
重复直到收敛:
当应用到线性回归的情况时,一种新的梯度下降等式就衍生出来了。我们代替实际的损失函数和实际的假设函数,并把等式修改为
这里m是训练集的大小,是随着同步改变的常量,是给定训练集的值。
注意到我们把两个关于的情况分开成单独的关于和的等式;针对由于导数我们在末尾乘了个。
这里的要点是如果我们用一个假设而且随后不断重复应用这些梯度下降算法,我们的假设会变得越来越精确。
加法和标量乘法都是针对元素的,所以你可以简单地加或减每个对应元素。
加或减的两个矩阵的维度一定相等。
在标量乘法中,我们简单地把每个元素乘以标量值。
我们把向量的每一列映射到矩阵的每一行上,乘以每一个元素并把结果求和。
一个m*n矩阵乘一个n*1向量的结果是m*1向量。
两个矩阵相乘是通过把它分成几个向量乘法并把结果连在一起。
一个m*n矩阵乘一个n*o矩阵的结果是m*o矩阵。
两个矩阵相乘,第一个矩阵的列数等于第二个矩阵的行数。
一个方阵和逆阵相乘等于单位阵。
非方阵没有逆阵。
没有逆阵的矩阵叫奇异或退化(singular or degenerate)。
矩阵的转置就像把矩阵顺时针转九十度然后翻转。
定义以下记号:
是的向量
向量形式:
改善模型,考虑把多个特征合成一个
通过对特征取幂形成新的特征,得到多项式假设函数
或者取个平方根
使用这些方法时,特征放缩非常重要
是一种不用迭代寻找最优值的方法
注意:
逻辑斯特回归
虽有回归之名,其实解决的是分类问题
0为负类,1为正类
当假设满足
为了得到二元分类,我们约定:
逻辑斯特函数输出大于等于0.5,表示
逻辑斯特函数输出小于0.5,表示
记住逻辑斯特的函数图像
决策边界就是y=0和y=1的分界线
原来的用不了了,原来那个已经不是凸函数了
向量形式:
与之前的没区别
向量形式多套一个而已
先算逻辑斯特函数的导数:
再对损失函数关于求偏导:
和式的偏导等于偏导的和式,找到变量所在的项,复合函数求导,
注意到
(x的各个分量的线性组合对第j个分量求导的结果)
分子分母约一下,合并一下,得到
向量形式:
更好的优化手段:共轭梯度、BFGS、L-BFGS
BFGS算法(以四个人的名字首字母命名):
对二阶优化方法————牛顿算法的一种改进,因为牛顿算法考虑二阶导数,而计算Hassian矩阵很耗时,BFGS提出一种方法近似求得Hassian矩阵。
http://www.cnblogs.com/kemaswill/p/3352898.html
L-BFGS算法:
当Hassian矩阵比较大的时候,用Limited-memory BFGS
https://en.wikipedia.org/wiki/Limited-memory_BFGS
目标是把数据分成n+1类(y={0,1...n})
把问题分割成n+1个二元分类问题
在每个问题中,计算y属于第k个类的概率
然后求概率最大值
选择一个类,然后把其他剩下的类看作一个整体,反复运用二元逻辑斯特回归,然后求概率最大值
正则化用来解决过拟合问题
高偏差(high bias)/欠拟合:假设函数不能很好地预测数据的趋势。原因是函数太简单或者特征太少
高方差(high variance)/过拟合:能够拟合已有数据的假设函数没有很好地泛化来预测新数据。原因是函数太复杂,产生太多与数据无关的曲线和角
解决过拟合的手段:
减少特征的数量:
正则化
保留所有特征,但减小参数
当我们有很多稍微有用(slightly useful)的特征时,正则化有效。
通过增加损失来减小假设函数中某些项的权重(值)
例如:如果我想让一个四阶函数更像平方函数,那么就要减小三阶和四阶变量的影响(而不是把它们从假设函数中移除),我们可以在损失函数中加上三阶和四阶变量对应的参数,并赋予很大的权值。如果想要损失函数接近零,那么就要使得三阶和四阶变量对应的参数接近零,从而达到减小三阶和四阶变量影响的目的。
也可以通过求和来正则化所有的参数
使用带有求和项的损失憾事,我们可以把假设函数的输出光滑化(smooth),从而减小过拟合。但是如果正则化参数太大,会导致过于平滑而欠拟合。
把跟其他参数分开,因为没必要惩罚它(它不控制x分量)
损失函数
梯度下降
跟上文一样
在训练开始之前,加一个常量特征到特征集中是很重要的。这个特征一般是一个全1的集合。
例如,当特征矩阵是X时,就是全一向量。
解释:
神经网络之表示
线性回归很少见
有若干个变量,两两相乘组成一个多项式,配以相关系数,加上常数项,外面套一个函数,形成假设函数。
如果变量一多,这种方法会产生大量特征,不实际。
神经网络是对我们大脑工作原理的有限模拟。它们最近经历了一个很大的复兴,因为计算机硬件的发展。
大脑只用一种学习算法来完成不同函数。这个准则就是“神经可塑性”。
权重矩阵的维度是
其中+1来自偏移单元和。
输入包含偏移单元,而输出不包含。
令输入层n+1维向量,那么
输出层是一个由0和1组成的向量,1表示属于该分类。
神经网络之学习
定义:
是网络总层数
是第l层除去偏移单元之外的节点数
是输出节点数,即分类数
是产生第k个输出的假设
假设函数:
对所有样本的所有输出节点求和。
正则化项对把所有参数平方求和。
用来最小化损失函数的算法
给定训练集
设定初始值为0
对于从1到m的第t个训练样本:
令
说明:
1. 代表第l层第j个节点的“误差”
2. 作为一个“误差累加器”,累计所有层误差以激活为权重的和
3. 是把经过正则化、取平均后的结果,表示损失函数对的偏导数
当输出只有一个节点时,第t个样本的损失是
把多个矩阵合成一个矩阵,为了方便调用优化函数
得到结果后展开
使用数值方法求一个梯度
如果初始权重全为零,那么所有节点的值将会是相同的。
所以需要随机初始化。
一种初始化方法是:
首先选择一个网络构架
训练神经网络
1. 随机初始化权重
2. 通过forword propagation求得假设函数
3. 求损失函数
4. 通过back propagation求偏导
5. 使用梯度验证确保back propagation有效
6. 使用梯度下降或者内置优化函数通过权重最小化损失函数
forword propagation和back propagation在遍历样本的循环中进行。
https://github.com/FengZiYjun/Markdown-Notes/blob/master/image/backpropagation.png
应用机器学习的建议
把数据集分为训练集和测试集:
为了选择最好的模型,需要检查每个多项式的次数和误差结果
用来作为一个训练多项式次数的中间数据集
划分数据集的例子:
(从不同次数的多项式中选择最合适的)
1. 对每个多项式次数使用训练集优化参数
2. 使用交叉验证集找出误差最小的多项式次数
3. 使用测试集把误差最小的多项式次数代入损失函数,估计总的误差
high bias 是欠拟合,high variance 是过拟合,怎样平衡?
考察正则化参数对bias/variance的影响
很小的:high variance, overfitting, 训练集误差小,交叉验证集误差大
小训练集:训练集误差小,交叉验证集误差大
大训练集:都很大,近似相等
增加训练样本对high bias于事无补
小训练集:训练集误差小,交叉验证集误差大
大训练集:训练集误差增加,交叉验证集误差减小,但差距依然显著
增加训练样本对high variance可能有用
修补high variance:
1. 增加训练样本
2. 减少特征
3. 增大正则化参数
修补high bias:
1. 增加特征
2. 减小正则化参数
用交叉验证在很多隐藏层上训练网络?
怎样选择哪个多项式次数?
bias是估计的误差,是期望值和最优值之间的差距
variance是由于有限数据引起的估计误差
正则化参数
解决机器学习问题的推荐方法
误差结果应该是一个单一数值。然而评估算法很难。
对输入数据的预处理
有时候很难说误差的减少是否真的是算法的改进。
例如:二元分类中把所有输入都归入一类,会得到低误差,但算法没有改进
这就是偏类(skewed class)的情况:当某一个类在整个数据集里非常稀罕
另一种说法是,数据集中某一类的样本远多于其他类
这种情况下,我们用准确/回召(Precision/Recall):
- | 预测真 | 预测假 |
---|---|---|
实际真 | true positive | false negative |
实际假 | false positive | true negative |
准确率(pricision):预测为真的样本当中实际为真的比例
好的分类器两者都应该很高
当我们在做逻辑斯特回归时,如果需要一个确信的结果,其中一种方法是提高预测为真的阀值
但这样就会使得准确率很高,但回召率很低
相反地,如果我们降低阀值,就会得到安全的预测,但是回召率很高而准确率很低
为了把这两种指标合起来,我们采用F值(F value)
而简单地取平均不能反应我们的需求(两个都要高)
所以应该取调和平均数
训练要用多少数据?
很多时候,有足够数据的差算法能够胜于不足数据的好算法
我们必须选择特征来确保有足够的信息(以人类专家的角度来判断?)
大数原理:一个low bias的算法拥有越多数据,越不容易过拟合,在测试集上越准确
支持向量机(SVM, support vector machine)
一种监督学习方法,有时更简洁更强大
在逻辑斯特回归的损失函数当中,是一条凹曲线,可以用一条折线近似,折线转折点在(1,0)
对另外包含log的一项,同理也可以用折线来近似,转折点在(-1,0)
折线使用分段函数表示,所以原来的损失函数中关于z的函数被替换成分段函数关于的函数,分别用和表示
由
支持向量机是一个判别函数
把支持向量机看作大边缘分类器
若y=1,我们希望
若y=0,我们希望
逻辑斯特回归中的决策边界是区分正负样本的一条直线
在SVM中,决策边界有一种特殊的性质——尽可能远离正负样本
决策边界到最邻近的样本的距离成为边缘(margin)
SVM最大化这种边缘,故称之为大边缘分类器
SVM会通过一个大边缘区分正负样本
只有当C很大时,才能使用SVM。因为C很大,为了最小化损失函数,对的要求更高
此时损失函数简化成
当数据能被一根直线分为正负时,称数据为线性可分的
如果出现离群值,我们可以降低C值,不让它影响决策边界
C的调增与正则化参数的调整效果相反
向量的长度
向量的投影
記是v在u方向上的投影,则
把SVM的损失函数重写成
这造成大边缘的原因是:向量垂直于决策边界
为了实现优化目标(最小化损失函数,最小化长度),我们需要投影的绝对值尽可能大
在样本向量长度一定的情况下,只能找到某个位置的,使得样本向量与它之间的夹角最小,而决策边界也随之确定
核方法允许我们通过SVM构造复杂的非线性分类器
给定x,依据到标志的接近度计算新特征
先定义相似度
相似度函数的性质:
把每个标志代入相似度函数得到一个,把这些作为特征,与的线性组合构成关于X的假设函数
得到标志的一种方法是,把所有训练样本的空间位置都当作标志,所以就有了m个标志
对于样本中的每一个向量,可以通过高斯核转化为关于自身到m个标志的相似度向量
现在就代替了,我们可以对使用SVM算法
核方法并不只能用来SVM中,但SVM与核方法结合会使得速度很快
选择C(=)
C很大,high variance, low bias
C很小,low variance, high bias
选择
很大,f特征很光滑,high bias, low variance
很小,f特征不光滑,low bias, high variance
用库函数,不要自己写
真正需要选择的是:
注意:
1. 在使用高斯核之前,要进行特征放缩(feature scaling)
2. 不是所有相似度函数都是合理的核,必须满足Mercer's Theorem,保证优化结果不出偏差
3. 可以用训练集和交叉验证集训练C和核参数
就像逻辑斯特回归那样,用一对多方法
聚类
跟监督学习相对,使用未标注的数据集
换句话说,没有y向量,只有特征数据集
聚类有助于
最普遍最常用的自动分类算法,把数据自动分类成凝聚的子集
我们主要的变量是:
Randomly initialize K cluster centroids mu(1), mu(2), ..., mu(K)
Repeat:
for i = 1 to m:
c(i):= index (from 1 to K) of cluster centroid closest to x(i)
for k = 1 to K:
mu(k):= average (mean) of points assigned to cluster k
第一个循环是聚类分配,c(i)表示x(i)被分配到第几个类
以数学形式表示为
一般的欧拉距离是要开方的,但这里没有开方,为了计算方便而且增长快速
第二个循环是移动中心。
数学形式为
如果有一个聚类没有分配到点,那么可以重新随机初始化到一个新的点,也可以简单地去除这个聚类。
在一定次数的迭代之后,算法会收敛,新的迭代不影响现有聚类情况
对于没有内在分隔或者自然结构的数据,K-Means算法也能均匀地把数据分隔成K份
参数如下
定义损失函数:
优化目标是
即寻找集合c(代表所有聚类)以及(代表所有中心)来最小化每个训练样本到相应聚类中心的平均距离
上述损失函数也成为训练样本的失真(distortion)
在聚类分配的步骤,我们的目标是保持不变,用c来最小化J
在移动中心的步骤,我们的目标是用来最小化J
K-Means算法的损失函数不可能递增,只能递减。
一种推荐的方法
K-Means会陷入局部最优解。为了降低这种事发生的几率,你可以在多个不同的随机初始化上进行算法。当K<10的情况,推荐在一个随机初始化的循环里跑一下。
for i = 1 to 100:
randomly initialize k-means
run k-means to get 'c' and 'm'
compute the cost function (distortion) J(c,m)
pick the clustering that gave us the lowest cost
K的选择是相当随意和模凌两可的
The elbow method: 画出损失函数J和聚类数目K。J应当随着K的增加而减小(除非陷入局部最优),然后趋于平滑。选择损失函数开始平滑的那个K值。
但是通常曲线变化很平缓(gradual),没有一个清晰的elbow。
另一种选择K的方法是观察K-Means怎样在下游的目的(downstream purpose)中表现,即根据使用这些聚类的实际需求。
https://stats.stackexchange.com/questions/133656/how-to-understand-the-drawbacks-of-k-means
有三个assumption:
1. k-means assumes the variance of the distribution of each attribute (variable) is spherical;
2. all variables have the same variance;
3. the prior probability for all k clusters is the same, i.e., each cluster has roughly equal number of observations;
失效情况:
Clustering non-clustered data
Sensitive to scale
Even on perfect data sets, it can get stuck in a local minimum.
If you want a theoretical model of what k-means does, consider it a quantization approach, not a clustering algorithm.
k-means finds (sometimes) the best reduction to k values of a multidimensional data set. Where "best" is the least squared error.
把数据降到3维就可以可视化了
我们要找新的三个特征来有效归纳(summarize)所有其他特征
最常用的降维算法Principal Component Analysis (PCA)
给定两个特征,我们项找一条直线能够一次性有效描述它们,然后把旧的特征映射到这条新的线上。
三个特征也一样,映射到一个平面
PCA的目标是减小所有特征到投影直线的平均距离,这叫投影误差
从n维降到k维:寻找K个向量,使得数据在它们上的投影的误差最小
PCA最小化的是到数据点的最短距离,或者叫最短正交距离
线性回归做的是拿x来“预测”y
给定训练集x(1),x(2),...,x(m)
1. 预处理(特征放缩、均值正则化)
2. 计算协方差矩阵(covariance matrix)
[U,S,V] = svd(\sigma)
注意:U矩阵的特殊性质
U矩阵是一个酋矩阵(unitary matrix)
其逆矩阵是自身的共轭矩阵,在实数范围内就是自身的转置
怎样选择k,也就是主成分的数目?k是降维到达的维度。
使用一下公式:
给定平均平方投影误差:
也给定数据的总偏移(total variation):
选择最小的k使得
选择K的算法
1. 令k=1,2...使用PCA
2. 计算
3. 检查上述公式
实际上有更快的方法:利用矩阵S
[U,S,V] = svd(\sigma)
常用来加速监督学习
把一万维度的特征减到一千维度
注意:
异常检测
给定数据集,想知道一个新的样本是否异常
构造一个模型,用来判定这个样本正常的概率
设定阀值,如果概率小于阀值,就判定为异常
如果这个异常检测器标记出太多异常样本,那么有必要减小阀值了
高斯分布类似于一个钟形曲线,能用函数表述
x是一个实数,如果x的概率分布是高斯分布
: is distributed as
其中是均值,决定曲线的中心
是标准差,决定曲线的宽度
独立性假设:训练集样本的各个特征直接没有相关性
記
为了评估我们的算法, 拿来一些标记数据,把它们分为正常和异常样本
在数据中,拿极大部分好的、非异常数据作为训练集来训练
然后拿一小部分异常与非异常混合的样本(异常依然是少数)作为交叉验证集和测试集
注意:交叉验证集可以用来选择阀值
使用异常检测的情况:
使用监督学习的情况:
通过画出数据的柱状图、检查钟形曲线来检查特征是否成高斯分布
一些有用的变换:取对数、开方等
选择出现在异常中的过大或者过小的特征
一次性为建模
参数是
正常计算和,然后利用上述公式
多元高斯模型能够自动检测不同特征之间的相关性
但缺点是需要更多数据、计算成本高
假设要给用户推荐电影
对每个用户评价过的电影使用线性回归
除了消除了常数之外跟线性回归没有什么不同
让用户告诉我们他们喜欢哪些种类的电影,通过提供他们的参数向量
从用户的参数推断电影参数,需要以下的平方误差函数
为了加速,我们可以同步最小化特征和参数
给定矩阵X(每行包含一部电影的特征)和矩阵(每行包含对于一个特定用户来说那些特征的权重),那么所有用户评价所有电影的预测就是
预测两部电影如何类似可以用它们向量之间的距离(各种距离)
新用户没有看过电影,会把所有电影评估为0,不合理
解决这个问题要把数据归一化到平均值
首先用一个矩阵Y储存从以前的评价中得到的数据,每行对应电影,每列对应用户
然后计算一个新的向量
大数据集通常有m=100,000,000
传统的梯度下降(也叫批量梯度下降batch gradient descent)每次要对很大的m求和,我们想办法避免这一点
是梯度下降的变种,对大数据集更加灵活
算法如下:
1. 随机捣乱数据集
2. 对于i从1到m:
算法每次只拟合一个训练样本。这样我们可以在无需扫描全部m个样本的前提下在梯度下降取得进步。
随机梯度下降不太可能会收敛到全局最小值,而是会在它旁边随机游荡,但通常会产生一个足够靠近的结果。
随机梯度下降通常会采取1-10次遍历数据集来接近全局最小值。
有时候比随机梯度下降更快
每次使用一定数量b的样本
b的取值可以是2-100
对i从1,1+b,1+2b...m-b+1
怎样选择学习率?
怎样确保它尽量靠近全局
一种策略是画出每1000左右个样本的假设的平均损失,我们可以在迭代中保存这些值
一个较小的学习率可能会得到一个更好的结果,因为随机梯度下降会在全局最优附近震荡跳跃,小学习率会带来小步伐的随机跳跃
如果增加画图的平均样本数,曲线变得平滑。
如果取平均的样本数太小,曲线会变得聒噪并很难找到趋势
一种真正收敛到全局最优的策略是慢慢降低学习率
但这很少做到,因为人们不想瞎搞那么多参数了
伴随着连续的网站用户流,我们可以运行一个永不停止的循环来收集用户行为作为特征X来预测一些行为y
你可以收集到的数据对每个用户修改参数,这样就可以适应新的用户群,因为你在不停地修改参数
把批量梯度下降分开,把对一个数据子集的损失函数分配到不同的机器中,于是就可以并行训练算法了
不同机器求不同部分的和
Map Reduce会负责这些调度(map)工作并通过计算减少(reduce)它们
你的算法是可以用Map Reduce的(MapReduceable),如果它能被表示成训练集函数的求和。
线性回归和逻辑斯特回归很容易并行处理。
对于神经网络,你可以在数据的子集上用不同机器计算forward propagation和back propagation,然后把导数回报给主机。