GithubHelp home page GithubHelp logo

dod-o / statistical-learning-method_code Goto Github PK

View Code? Open in Web Editor NEW
10.8K 308.0 2.9K 50.32 MB

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

Python 61.60% Jupyter Notebook 38.40%
machine-learning-algorithms code statistical-learning-method

statistical-learning-method_code's Introduction

【广告】每日Arxiv(中文版)

每日Arxiv(中文版)立志paper汉化,目前翻译目前涵盖标题摘要,AI学科近期支持论文全文汉化

一天阅读百篇paper不是梦!

链接: 学术巷子(xueshuxiangzi.com)

前言

力求每行代码都有注释,重要部分注明公式来源。具体会追求下方这样的代码,学习者可以照着公式看程序,让代码有据可查。

image

如果时间充沛的话,可能会试着给每一章写一篇博客。先放个博客链接吧:传送门

注:其中Mnist数据集已转换为csv格式,由于体积为107M超过限制,改为压缩包形式。下载后务必先将Mnist文件内压缩包直接解压。

【Updates】

书籍出版:目前已与人民邮电出版社签订合同,未来将结合该repo整理出版机器学习实践相关书籍。同时会在book分支中对代码进行重构,欢迎在issue中提建议!同时issue中现有的问题也会考虑进去。(Feb 12 2022)

线下培训:女朋友计划近期开办ML/MLP/CV线下培训班,地点北上广深杭,目标各方向快速入门,正在筹备。这里帮她打个广告,可以添加微信15324951814(备注线下培训)。本人也会被拉过去义务评估课程质量。。。(Feb 12 2022)

无监督部分更新:部分无监督算法已更新!!! 该部分由Harold-Ran提供,在此感谢! 有其他算法补充的同学也欢迎添加我微信并pr!(Jan 27 2021)

实现

监督部分

第二章 感知机:

博客:统计学习方法|感知机原理剖析及实现
实现: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

无监督部分

第十四章 聚类方法

实现:K-means_Clustering.py

实现:Hierachical_Clustering.py

第十六章 主成分分析

实现:PCA.py

第十七章 潜在语意分析

实现:LSA.py

第十八章 概率潜在语意分析

实现:PLSA.py

第二十章 潜在狄利克雷分配

实现:LDA.py

第二十一章 PageRank算法

实现:Page_Rank.py

许可 / License

本项目内容许可遵循Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

The content of this project itself is licensed under the Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

联系

欢迎pr,有疑问也可通过issue、微信或邮件联系。
此外如果有需要MSRA实习内推的同学,欢迎*扰。
Wechat: lvtengchao(备注“blog-学校/单位-姓名”)
Email: [email protected]

statistical-learning-method_code's People

Contributors

dod-o avatar harold-ran avatar jason-liew avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

statistical-learning-method_code's Issues

adaboost.py 空间划分

adaboost 中,div是不是对输入空间的切分?为什么代码中取值是 -0.5, 0.5, 1.5。输入空间不是二值化了,然后应该是0到1了

CART Code?

你好,请问是还没有实现CART树吗,项目里好像没找到?

Adaboost里的Zm为什么是Sum(D)?

代码:D = np.multiply(D, np.exp(-1 * alpha * np.multiply(trainLabelArr, Gx))) / sum(D)

书里公式中分母应该是Zm,但是代码里是 sum(D),不是很清楚。

EM算法中,main函数的输出控制顺序错误

原始为:

print('alpha0:%.1f, mu0:%.1f, sigmod0:%.1f, alpha1:%.1f, mu1:%.1f, sigmod1:%.1f'%(
    alpha0, alpha1, mu0, mu1, sigmod0, sigmod1
))

正确为:

print('alpha0:%.1f, mu0:%.1f, sigmod0:%.1f, alpha1:%.1f, mu1:%.1f, sigmod1:%.1f'%(
    alpha0, mu0, sigmod0, alpha1, mu1, sigmod1
))  

关于KNN算法的实现

算法并没有用kd树,想看看kd树搜索算法怎么写,尤其是当k近邻的k大于1时。

感知机里算法的迭代问题

提问!感知机算法的实现里,对于判定条件的计算中,w初始化为一个1n的向量,xi.T为n1的向量,我们预期的结果应该是一个实数吧,如果使用numpy的*是不是有些不太合逻辑呢,是否考虑使用dot。

KNN向量化,只需20S

#coding=utf-8
#Author:Dodo
#Date:2018-11-16
#Email:[email protected]

'''
数据集:Mnist
训练集数量:60000
测试集数量:10000(实际使用:200)

运行结果:(邻近k数量:25)
向量距离使用算法——欧式距离
正确率:97%
运行时长:308s
向量距离使用算法——曼哈顿距离
正确率:14%
运行时长:246s
'''

import numpy as np
import time
from collections import Counter

def loadData(fileName):
'''
加载文件
:param fileName:要加载的文件路径
:return: 数据集和标签集
'''
print('start read file')
#存放数据及标记
dataArr = []; labelArr = []
#读取文件
fr = open(fileName)
#遍历文件中的每一行
for line in fr.readlines():
#获取当前行,并按“,”切割成字段放入列表中
#strip:去掉每行字符串首尾指定的字符(默认空格或换行符)
#split:按照指定的字符将字符串切割成每个字段,返回列表形式
curLine = line.strip().split(',')
#将每行中除标记外的数据放入数据集中(curLine[0]为标记信息)
#在放入的同时将原先字符串形式的数据转换为整型
dataArr.append([int(num) for num in curLine[1:]])
#将标记信息放入标记集中
#放入的同时将标记转换为整型
labelArr.append(int(curLine[0]))
#返回数据集和标记
return dataArr, labelArr

def calcDist(x1, x2):
'''
计算两个样本点向量之间的距离
使用的是欧氏距离,即 样本点每个元素相减的平方 再求和 再开方
欧式举例公式这里不方便写,可以百度或谷歌欧式距离(也称欧几里得距离)
:param x1:向量1
:param x2:向量2
:return:向量之间的欧式距离
'''
return np.sqrt(np.sum(np.square(x1 - x2)))

#马哈顿距离计算公式
# return np.sum(x1 - x2)

def getClosest(trainDataMat, trainLabelMat, X, topK):
'''
预测样本x的标记。
获取方式通过找到与样本x最近的topK个点,并查看它们的标签。
查找里面占某类标签最多的那类标签
(书中3.1 3.2节)
:param trainDataMat:训练集数据集
:param trainLabelMat:训练集标签集
:param x:要预测的样本x
:param topK:选择参考最邻近样本的数目(样本数目的选择关系到正确率,详看3.2.3 K值的选择)
:return:预测的标记
'''
#建立一个存放向量x与每个训练集中样本距离的列表
#列表的长度为训练集的长度,distList[i]表示x与训练集中第
## i个样本的距离
distList = [0] * len(trainLabelMat)
#遍历训练集中所有的样本点,计算与x的距离
'''
for i in range(len(trainDataMat)):
#获取训练集中当前样本的向量
x1 = trainDataMat[i]
#计算向量x与训练集样本x的距离
curDist = calcDist(x1, x)
#将距离放入对应的列表位置中
distList[i] = curDist
'''
num_test = X.shape[0]
num_train = trainDataMat.shape[0]
dists = np.zeros((num_test, num_train))
minus_tmp = np.matmul(X,trainDataMat.T) *(-2) #shape 500,5000
x_square = np.sum(X2,axis = 1,keepdims = True)
train_square = np.sum(trainDataMat
2,axis = 1)
dists = (minus_tmp + x_square + train_square)**(0.5)

#对距离列表进行排序
#argsort:函数将数组的值从小到大排序后,并按照其相对应的索引值输出
#例如:
#   >>> x = np.array([3, 1, 2])
#   >>> np.argsort(x)
#   array([1, 2, 0])
#返回的是列表中从小到大的元素索引值,对于我们这种需要查找最小距离的情况来说很合适
#array返回的是整个索引值列表,我们通过[:topK]取列表中前topL个放入list中。
#----------------优化点-------------------
#由于我们只取topK小的元素索引值,所以其实不需要对整个列表进行排序,而argsort是对整个
#列表进行排序的,存在时间上的浪费。字典有现成的方法可以只排序top大或top小,可以自行查阅
#对代码进行稍稍修改即可
#这里没有对其进行优化主要原因是KNN的时间耗费大头在计算向量与向量之间的距离上,由于向量高维
#所以计算时间需要很长,所以如果要提升时间,在这里优化的意义不大。(当然不是说就可以不优化了,
#主要是我太懒了)


y_pred = np.zeros(num_test)
for i in range(num_test):
    # A list of length k storing the labels of the k nearest neighbors to
    # the ith test point.
    closest_y = []
    
    sortedarry = np.argsort(dists[i])
    for j in range(topK):
        label_tmp = trainLabelMat[sortedarry[j]]
        closest_y.append(label_tmp)
    
    label_most = Counter(closest_y).most_common(1)

print(label_most)

    y_pred[i] = label_most[0][0]

#max(labelList):找到选票箱中票数最多的票数值
#labelList.index(max(labelList)):再根据最大值在列表中找到该值对应的索引,等同于预测的标记
return y_pred

def model_test(trainDataArr, trainLabelArr, testDataArr, testLabelArr, topK):
'''
测试正确率
:param trainDataArr:训练集数据集
:param trainLabelArr: 训练集标记
:param testDataArr: 测试集数据集
:param testLabelArr: 测试集标记
:param topK: 选择多少个邻近点参考
:return: 正确率
'''
print('start test')
#将所有列表转换为矩阵形式,方便运算
trainDataMat = np.array(trainDataArr); trainLabelMat = np.array(trainLabelArr).T
testDataMat = np.array(testDataArr); testLabelMat = np.array(testLabelArr).T
testDataMat = testDataMat[:200,]
testLabelMat = testLabelMat[:200,]
#错误值技术
errorCnt = 0
#遍历测试集,对每个测试集样本进行测试
#由于计算向量与向量之间的时间耗费太大,测试集有6000个样本,所以这里人为改成了
#测试200个样本点,如果要全跑,将行注释取消,再下一行for注释即可,同时下面的print
#和return也要相应的更换注释行
# for i in range(len(testDataMat)):
'''
for i in range(200):
# print('test %d:%d'%(i, len(trainDataArr)))
print('test %d:%d' % (i, 200))
#读取测试集当前测试样本的向量
x = testDataMat[i]
#获取预测的标记
y = getClosest(trainDataMat, trainLabelMat, x, topK)
#如果预测标记与实际标记不符,错误值计数加1
if y != testLabelMat[i]: errorCnt += 1
'''
y_test_pred = getClosest(trainDataMat,trainLabelMat,testDataMat,topK)
num_correct = np.sum(y_test_pred == testLabelMat)
#返回正确率
# return 1 - (errorCnt / len(testDataMat))
return num_correct/200 #1 - (errorCnt / 200)

if name == "main":
start = time.time()

#获取训练集
trainDataArr, trainLabelArr = loadData('./Mnist/mnist_train.csv')
#获取测试集
testDataArr, testLabelArr = loadData('./Mnist/mnist_test.csv')
#计算测试集正确率
accur = model_test(trainDataArr, trainLabelArr, testDataArr, testLabelArr, 25)
#打印正确率
print('accur is:%d'%(accur * 100), '%')

end = time.time()
#显示花费时间
print('time span:', end - start)

K means 簇中心更新的计算问题

def cal_groupcenter(group, Xarray):

    center = np.zeros(Xarray.shape[1])
    for i in range(Xarray.shape[1]): #range(4)
        for n in group:
            center[i] += Xarray[n][i]  #计算当前类中第i个特征的数据之和
    center = center / Xarray.shape[0]  #计算各个特征的均值
    return center

作者您好!十分感谢你开源的机器学习代码,受益良多,想请教一下:在上面的函数中,为什么使用center = center / Xarray.shape[0] (簇的和除以总样本个数),而不是center = center / len(group) 即每一簇的中心点的均值应该是该簇的和除以该簇的数目
代码位置如下⬇ 十分感激!

center = center / Xarray.shape[0] #计算各个特征的均值

决策树算法中的一些问题

image

关于这个部分的注释。从个人的学习和实际测试来看:a[0] = 1
并且一个关于numpy的特性是,对于一维的ndarray,".T"是不起作用的。
必须用reshape / transpose才能真正把一维改成二维(即矩阵)

当然了,这仅仅是我的看法和经验,所以希望和您探讨一下。

by the way,代码简洁,注释清晰,nice!

SVM E值得更新

self.alpha[i] = alphaNew_1
self.alpha[j] = alphaNew_2
self.b = bNew

self.E[i] = self.calcEi(i)
self.E[j] = self.calcEi(j)

在每次更新完alpha1和alpha2之后,我认为应该更新所有的E值,因为alpha1和alpha2的不仅影响Ej和Ej,其他的也会受影响,下一次更新时用到的E1和E2应该是用最近一次更新之后的alpha计算的

K-means clustering

K-means clustering计算兰德系数时

sum_i = np.zeros(3)  #定义一个数组,用于保存聚类结果group_dict中每一类的个数
sum_j = np.zeros(3)  #定义一个数组,用于保存外部标签y_dict中每一类的个数

应该是
sum_i = np.zeros(k)
否则聚类数目不为3时,代码会报错

数据集下载失效

您好,您所提供的minst数据集不能下载了,不知道是我的操作问题还是您的问题

Large file management recommendation

I found that you said the MNIST dataset was exceeded the maximum storage of the Github limitation.
Maybe you can try to use git-lfs to manage that file then you won't need to keep the file in the different place!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.