有人手写实现李航《统计学习方法》书中全部算法

2020-05-21 11:33:27 浏览数 (1)

前言

不管你是学习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

推荐这个算法复现项目,原因有三:

  1. 仅用Python基本库即可实现
  2. 详细的博客介绍
  3. 详细的代码中文注解

注:代码已上传,文末附下载方式

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

0 人点赞