前言
不管你是学习CV,还是NLP,或者其他方向,应该都多多少少看过或者听过李航教授的《统计学习方法》这本书。Amusi 认为这是一本超级棒的AI入门,再具体一点机器学习入门的书籍。
记得第一次拿到手里的时候,很是惊讶:如此"轻薄"。懂的自然懂,跟其他技术书籍相比,这本书的重量就是一股清流。"轻薄"但不简单,内容涵盖了机器学习大多数常见的算法。至2012年出版以来,印刷不断,好评不断。截止2020年5月14日,该书在豆瓣上拿到 9.0 的评分(相当之高)。
因为原书侧重算法/知识点的原理部分,所以整篇书的公式相当之多,莽下来直接看,第一遍肯定看的囫囵吞枣。但好书一定要多刷,可能每次看,都有不同的深入理解。
虽然现在每天都有大量论文和项目出来,动不动"重磅","超越xxx",但那些AI基础知识是永远不会过时,且被后人反复使用的。这一点,在秋招/春招、找实习或者社招上得到了很好的体现。比如面试中几个高频的问题:线性回归与逻辑回归(LR)的区别、LR 与 SVM的区别和联系、SVM原理等。
其实涉及ML的知识点问题,其实多看几遍《统计学习方法》以及相关知识点的博客即可。但遇到"手撕SVM代码"、"手撕K-Means代码"等代码问题,相信很多同学就懵圈了。
所以本文正是要介绍《统计学习方法》的算法实现代码。实际上复现此书代码的大佬很多,github上能搜到一堆项目,但这里分享的是 Amusi 认为最好的复现版本。
手写实现李航《统计学习方法》书中全部算法
项目作者:Dod-o
项目链接:
https://github.com/Dod-o/Statistical-Learning-Method_Code
推荐这个算法复现项目,原因有三:
- 仅用Python基本库即可实现
- 详细的博客介绍
- 详细的代码中文注解
注:代码已上传,文末附下载方式
1. 仅用Python基本库即可实现
这一点其实很考验你对代码的理解,也很符合面试的要求。不用第三方算法库,而是直接用Python基本库实现,如numpy、math等。
2. 详细的博客介绍
就如上面所说,看一遍《统计学习方法》可能看不懂原理,所以需要查相关知识点的资料。该项目作者就将学习后的内容写成详细博客,这一点推荐大家学习和参考。
如下图就是Dod-o写的关于SVM和决策树的博客(节选)
3. 详细的代码中文注解
这一部分相信是很多同学非常非常看重的。代码就是"生产力",带中文注解的代码就是"超级生产力"。
这里截几个代码段,大家可以预览感受一下
代码语言:javascript复制class SVM:
'''
SVM类
'''
def __init__(self, trainDataList, trainLabelList, sigma = 10, C = 200, toler = 0.001):
'''
SVM相关参数初始化
:param trainDataList:训练数据集
:param trainLabelList: 训练测试集
:param sigma: 高斯核中分母的σ
:param C:软间隔中的惩罚参数
:param toler:松弛变量
注:
关于这些参数的初始值:参数的初始值大部分没有强要求,请参照书中给的参考,例如C是调和间隔与误分类点的系数,
在选值时通过经验法依据结果来动态调整。(本程序中的初始值参考于《机器学习实战》中SVM章节,因为书中也
使用了该数据集,只不过抽取了很少的数据测试。参数在一定程度上有参考性。)
如果使用的是其他数据集且结果不太好,强烈建议重新通读所有参数所在的公式进行修改。例如在核函数中σ的值
高度依赖样本特征值范围,特征值范围较大时若不相应增大σ会导致所有计算得到的核函数均为0
'''
self.trainDataMat = np.mat(trainDataList) #训练数据集
self.trainLabelMat = np.mat(trainLabelList).T #训练标签集,为了方便后续运算提前做了转置,变为列向量
self.m, self.n = np.shape(self.trainDataMat) #m:训练集数量 n:样本特征数目
self.sigma = sigma #高斯核分母中的σ
self.C = C #惩罚参数
self.toler = toler #松弛变量
self.k = self.calcKernel() #核函数(初始化时提前计算)
self.b = 0 #SVM中的偏置b
self.alpha = [0] * self.trainDataMat.shape[0] # α 长度为训练集数目
self.E = [0 * self.trainLabelMat[i, 0] for i in range(self.trainLabelMat.shape[0])] #SMO运算过程中的Ei
self.supportVecIndex = []
代码语言:javascript复制def createBosstingTree(trainDataList, trainLabelList, treeNum = 50):
'''
创建提升树
创建算法依据“8.1.2 AdaBoost算法” 算法8.1
:param trainDataList:训练数据集
:param trainLabelList: 训练测试集
:param treeNum: 树的层数
:return: 提升树
'''
#将数据和标签转化为数组形式
trainDataArr = np.array(trainDataList)
trainLabelArr = np.array(trainLabelList)
#没增加一层数后,当前最终预测结果列表
finallpredict = [0] * len(trainLabelArr)
#获得训练集数量以及特征个数
m, n = np.shape(trainDataArr)
下面看一下其实现的内容完整目录
第二章 感知机:
博客:统计学习方法|感知机原理剖析及实现 实现:perceptron/perceptron_dichotomy.py
第三章 K近邻:
博客:统计学习方法|K近邻原理剖析及实现 实现:KNN/KNN.py
第四章 朴素贝叶斯:
博客:统计学习方法|朴素贝叶斯原理剖析及实现 实现:NaiveBayes/NaiveBayes.py
第五章 决策树:
博客:统计学习方法|决策树原理剖析及实现 实现:DecisionTree/DecisionTree.py
第六章 逻辑斯蒂回归与最大熵模型:
博客:逻辑斯蒂回归:统计学习方法|逻辑斯蒂原理剖析及实现 博客:最大熵:统计学习方法|最大熵原理剖析及实现
实现逻辑斯蒂回归:
Logistic_and_maximum_entropy_models/logisticRegression.py 实现最大熵:Logistic_and_maximum_entropy_models/maxEntropy.py
第七章 支持向量机:
博客:统计学习方法|支持向量机(SVM)原理剖析及实现 实现:SVM/SVM.py
第八章 提升方法:
实现:AdaBoost/AdaBoost.py
第九章 EM算法及其推广:
实现:EM/EM.py
第十章 隐马尔可夫模型:
实现:HMM/HMM.py