机器学习假设了对于某个问题存在一个上帝函数,给定一个输入就能得到一个确定的输出,计算机可以通过样本数据在假设的函数空间中找到一个近似上帝函数的函数,我们可以利用这个近似函数来进行预测。
现实世界的问题大体可以分为两类:分类和回归。
分类问题就是对一个东西判断它所属的类别,例如判断一张照片里面的动物是猫还是狗。
回归问题就是根据连续的输入可以获取到连续的输出,例如根据房屋信息预测房价。
分类和回归只是输出结果不同,本质上都是通过机器学习的方式来找到近似函数。分类一般是在函数f外面套一个sign函数将连续的数字转换为了离散的1和-1。
最简单的分类算法是感知机,它模拟了大脑神经细胞的工作方式,根据输入输出正负信号。感知机假设了多个样本点是可以用一个超平面隔开,这个超平面就是线性方程wx+b=0的几何表示。例如在二维空间里面,wx+b=0就是一条直线,感知机的假设空间就是二维空间里面的所有直线,感知机的学习算法就是要在假设空间里面找到一条直线将正负样本分开。
感知机的暴力实现就是基本思想就是当超平面是正确的时候,正样本和法向量的夹角是锐角,负样本跟法向量的夹角是钝角。在计算的时候可以利用一个结论:
- wa+b>0:样本和法向量的夹角是锐角
- wa+b=0:样本在超平面上
- wa+b<0:样本跟法向量的夹角是钝角
基于上面的思路,我们知道可以通过计算法向量与样本的角度来判断哪些超平面是我们想要的,即对一个超平面计算它跟所有样本点的角度,如果所有样本点都分类正确,那么这个超平面就是我们想要的。接下来的问题就是怎么找到这些超平面,超平面有无穷多个,理论上我们可以不断的尝试来找到正确的超平面,但是这样效率太低了,有没有更快的方法。
答案是肯定的,这里拿二维空间来举例说明。在一开始,我们可以随便找一条直线来对样本进行分类,当然这样分类的结果一定是会出错的。但我们可以通过纠正错误来找到正确的直线。错误可以分为两种情况:
一是把正样本分配到另一边,即wa+b<0,样本跟法向量的夹角是钝角,如果我们能调整一下法向量w的方向,让它跟a之间的角度变成锐角,这样就能纠正错误了。这里要利用向量加法的知识:w2=w+a,w2与a的夹角一定是锐角。所以我们只需要将w跟a相加就能得到新的法向量w2,而这个法向量对a的分类是准确的。
二是把负样本分配到另一边,即wa+b>0,样本跟法向量的夹角是锐角。同理,利用向量加法:w2=w-a,w2与a的夹角一定是钝角。
数学上可以证明,只要样本是线性可分的,即存在一个超平面可以完全把正负样本分隔开,那么只要不断让纠正法向量跟所有样本点的角度,那么最后一定能够找到一个超平面恰好将正负样本分隔开。这就是感知机的暴力实现算法。
上面的算法只能解决线性可分的问题,但现实生活中更多的是线性不可分的数据集,因为数据集总会存在噪音。在暴力实现的基础上,针对线性不可分的数据集,我们可以做两点改进:一是限制循环次数,因为线性不可分,纠错的过程不可能停止,需要人为指定一个上限;二是记录每条直线犯错次数到某个变量中,就像把每次试过的直线放到一个口袋里面,然后在算法停止的时候从口袋里面找一个犯错次数最少的直线当做最终结果。所以这个算法也叫做口袋算法。
在口袋算法中,参数w和b可以通过算法进行自动更新,但是迭代次数需要人工指定,这种需要人工指定的参数称为超参数。迭代次数会影响算法的准确率,调小了容易欠拟合,调大了浪费计算资源。随着迭代次数增加,准确率会达到一个上限,此时再增加迭代次数就不划算了。所以我们可以尝试不断的增加迭代次数直到准确率到上限,这样就能选到最佳的迭代次数。
一般来说,机器学习的数据集分为两部分,训练集和测试集。训练集顾名思义是用来训练的数据集,根据训练集训练出来的模型可以准确的对训练集的样本进行准确的分类,为了验证模型的泛化能力,即对未知数据集的预测准确率,我们引入了测试数据集来判断模型的准确率。在口袋算法中,为了找到最佳迭代次数,我们还需要引入验证数据集来计算不同迭代次数的准确率。这里为啥不用测试集来找超参呢?因为测试集是用来计算模型最终的准确率的,如果用测试集来计算超参,那么测试集就失去它判断模型准确率的作用,因为模型已经针对测试集做了优化了。如果将训练集比作我们平时刷的题目,那么验证集就是模拟考试,测试集就是高考。高考成绩才是我们最终的目标,如果拿高考题当做模拟考试来考,那大家都能考满分,因为考生已经见过高考题目了,但这样就失去的高考的意义。同理,如果用测试集来当做验证集让模型调整超参,那么模型也能考满分,这样也失去测试集判断模型真是准确的意义。
为了能够自动化调整超参数,我们新增了使用验证集计算最佳迭代次数的步骤,所以机器学习的过程就从原来的训练-预测两步变成了三步:
1. 训练:在训练集上学习参数
2. 验证:在验证集上测试准确率,增加迭代次数,然后重新回到第一步训练,直到准确率达到上限
3. 预测:在测试集上检验准确率
在机器学习中,训练集的数据越多越好,前面为了能够让超参数自动化调整,分出了一部分数据集作为验证集,导致训练集的数据量变少了。那么有没有更好的办法呢?这个办法就是k折交叉验证。
k折交叉验证的思路就是把训练集分成k份,然后每次选取1份作为验证集,剩下的作为训练集,针对每一份都训练并且验证其准确率,使用k个准确率取平均作为当前超参的结果,然后继续调整超参直到找到平均准确率最高的超参为止。最后基于选取的超参在整个训练集上面训练模型。
k折交叉验证不仅增加了训练集的数据量,还通过多次验证取平均减少了误差。当然了,k折交叉验证本身又引入了一个超参数:k的值选择多少?一般来说,经验值是10。