├── .gitignore
├── LICENSE
├── README.md
├── datasets
├── MNIST
│ └── raw
│ │ ├── load_data.py
│ │ ├── t10k-images-idx3-ubyte
│ │ ├── t10k-images-idx3-ubyte.gz
│ │ ├── t10k-labels-idx1-ubyte
│ │ ├── t10k-labels-idx1-ubyte.gz
│ │ ├── train-images-idx3-ubyte
│ │ ├── train-images-idx3-ubyte.gz
│ │ ├── train-labels-idx1-ubyte
│ │ └── train-labels-idx1-ubyte.gz
└── README.ipynb
├── ml-with-numpy
├── AdaBoost
│ ├── AdaBoost.py
│ └── README.md
├── DecisionTree
│ ├── DecisionTree.md
│ └── DecisionTree.py
├── EM
│ └── EM.md
├── HMM
│ └── 10.HMM.ipynb
├── LinearRegression
│ ├── BGD.png
│ ├── LiR_np.py
│ ├── LinearRegression.ipynb
│ └── cross_valid.png
├── LogisticRegression
│ ├── LogisticRegression.ipynb
│ └── README.md
├── MLP
│ ├── MLP_np.py
│ ├── README.md
│ └── assets
│ │ └── img.png
├── SVM
│ ├── README.md
│ ├── SVM_np.ipynb
│ ├── SVM_np.py
│ └── assets
│ │ ├── 1042406-20161125104106409-1177897648.png
│ │ ├── 1042406-20161125104737206-364720074.png
│ │ ├── 20180214224342909.png
│ │ └── image-20210809104104109.png
└── kNN
│ ├── README.md
│ └── kNN.py
├── ml-with-sklearn
├── .gitignore
├── 01-LinearRegression
│ ├── LinearRegression.ipynb
│ ├── assets
│ │ ├── BGD.png
│ │ ├── cross_valid.png
│ │ └── 线性回归.jpg
│ ├── 多项式回归.py
│ ├── 线性回归.md
│ ├── 线性回归.pdf
│ └── 线性回归.py
├── 02-LogisticRegression
│ ├── LogisticRegression.ipynb
│ ├── LogisticRegression.py
│ ├── 逻辑回归.md
│ └── 逻辑回归.pdf
├── 03-DecisionTree
│ ├── DecisionTree.ipynb
│ ├── DecisionTree.md
│ ├── DecisionTree.pdf
│ ├── DecisionTree.py
│ ├── DecisionTree_visualization.ipynb
│ └── assets
│ │ └── WeChat39e385eab473a12c016dd13b725eff9b.png
├── 04-MLP
│ ├── MLP.assets
│ │ └── WeChatb8270a9e865ca875dbbc163459504707.png
│ ├── MLP.ipynb
│ ├── MLP.md
│ ├── MLP.pdf
│ └── MLP.py
├── 05-SVM
│ ├── SVM.ipynb
│ ├── datasets.zip
│ ├── svm.md
│ ├── svm.pdf
│ └── svm.py
├── 06-Bayes
│ ├── NBayes.ipynb
│ ├── NBayes.py
│ ├── 贝叶斯.md
│ ├── 贝叶斯.pdf
│ └── 贝叶斯分类器.ipynb
├── 07-Random Forest
│ ├── bagging与随机森林.ipynb
│ ├── bagging和随机森林.ipynb
│ ├── bagging和随机森林.md
│ ├── bagging和随机森林.pdf
│ └── bagging和随机森林.py
├── 08-AdaBoost
│ ├── AdaBoost.ipynb
│ ├── AdaBoost.py
│ ├── AdaBoost算法.ipynb
│ └── README.md
├── 09-K-means
│ ├── k-means.ipynb
│ ├── k-means.md
│ ├── k-means.pdf
│ ├── k-means.py
│ └── res
│ │ ├── k-means-1.png
│ │ ├── k-means-2.webp
│ │ ├── k-means-3.jpg
│ │ └── k-means-4.png
├── 10-kNN
│ ├── knn.ipynb
│ ├── knn.md
│ ├── knn.pdf
│ ├── knn.py
│ └── res
│ │ ├── knn-1.png
│ │ ├── knn-2.png
│ │ └── knn-3.jpg
├── 11-PCA
│ ├── PCA.ipynb
│ ├── PCA.md
│ ├── PCA.pdf
│ ├── PCA.py
│ ├── data
│ │ └── cars.csv
│ └── res
│ │ ├── pca-0.png
│ │ ├── pca-1.png
│ │ ├── pca-2.png
│ │ ├── pca-3.png
│ │ └── pca-4.gif
├── 12-HMM
│ ├── HMM.ipynb
│ ├── HMM.md
│ ├── HMM.pdf
│ ├── HMM.py
│ ├── data
│ │ ├── HMMTrainSet.txt
│ │ └── testArtical.txt
│ └── res
│ │ ├── hmm-1.svg
│ │ ├── hmm-2.webp
│ │ ├── hmm-3.webp
│ │ ├── hmm-4.webp
│ │ └── hmm-5.svg
├── 13-Visualization
│ ├── asset
│ │ ├── output_11_0.png
│ │ ├── output_11_1.png
│ │ ├── output_13_1.png
│ │ ├── output_13_2.png
│ │ ├── output_16_0.png
│ │ ├── output_18_0.png
│ │ ├── output_18_1.png
│ │ ├── output_20_0.png
│ │ ├── output_20_1.png
│ │ ├── output_22_0.png
│ │ ├── output_24_0.png
│ │ ├── output_26_0.png
│ │ ├── output_28_0.png
│ │ ├── output_30_0.png
│ │ ├── output_33_0.png
│ │ ├── output_36_0.png
│ │ └── output_38_0.png
│ ├── visualization_report.ipynb
│ ├── visualization_report.md
│ ├── visualization_report.pdf
│ └── visualization_report.py
└── 组队学习
│ └── sklearn机器学习介绍.pptx
├── src
├── 1f9174e32387cd4dbc0212efbde06eada8173c937666927d4287155d8cc6f988.jpg
├── 80b58c8d6044a0f0a6c38b32de319994a570a5f40400a2bc30046f7fcb339fcb.jpg
├── 82a1f7c37889cc9d03a7ca97b56db6c796fed916d2e2576577d97586c52c80ed.jpg
├── 88dcdba0d98766b40896dfbf1809ed4456b85dc1e17a6e5b9ac952830760ab1d.jpg
├── b167b1042d0a59ae8a0c68c6fb9915e49f9e16f30e645adef405cca797607778.jpg
├── cd28bdb3dab6a33f137ceb4fde2527b14e4e6a41f8ef0bc8a6957dcd2324c840.jpg
└── de17622c-0887-46d8-a32a-ee8da80a7c54.png
├── 天池金融风控.ipynb
├── 西瓜书代码实战.md
└── 西瓜书代码实战.pdf
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .vscode
3 | .git
4 | __pycache__
5 | .ipynb_checkpoints
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 johnjim0816
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [西瓜书代码实战](https://github.com/datawhalechina/machine-learning-toy-code)
2 |
3 | 本项目以西瓜书以及[南瓜书](https://datawhalechina.github.io/pumpkin-book/#/)为主要参考,其他资料为辅助,来进行常见机器学习代码的实战。主要特色为力求数码结合,即数学公式与相关代码的形神对应,能够帮助读者加深对公式的理解以及代码的熟练。
4 |
5 | 详细教程请阅读 西瓜书代码实战.pdf
6 |
7 | ## 算法进度
8 |
9 | | 算法名称 | 相关材料 | 进度 | 备注 |
10 | | :----------: | :------: | :--: | ---- |
11 | | 01-LinearRegression |sklearn | OK | |
12 | | 02-LogisticRegression |sklearn | OK | |
13 | | 03-DecisionTree |sklearn | OK | |
14 | | 04-MLP |sklearn | OK | |
15 | | 05-SVM |sklearn | OK | |
16 | | 06-Bayes |sklearn | OK | |
17 | | 07-Random Forest |sklearn | OK | |
18 | | 08-AdaBoos |sklearn | OK | |
19 | | 09-K-means |sklearn | OK | |
20 | | 10-kNN |sklearn | OK | |
21 | | 11-PCA |sklearn | OK | |
22 | | 12-HMM |hmmlearn | OK | |
23 | | 13-Visualization |sklearn | OK | |
24 |
25 | ## 算法项目实战
26 |
27 | 学习完了西瓜书,手动实现相关的算法后,接下来就是到了实战的环节,datawhale开源的数据竞赛项目给大家施展自己coding的平台
28 |
29 | - [数据挖掘实践(二手车价格预测)](https://github.com/datawhalechina/team-learning-data-mining/tree/master/SecondHandCarPriceForecast)
30 |
31 | - [数据挖掘实践(金融风控)](https://github.com/datawhalechina/team-learning-data-mining/tree/master/FinancialRiskControl)
32 | - [数据挖掘实践(心跳信号分类)](https://github.com/datawhalechina/team-learning-data-mining/tree/master/HeartbeatClassification)
33 |
34 |
35 | ## 贡献者
36 |
37 |
Y以最小化总体风险
9 | $$
10 | R(h)=E_x[R(h(x)|x)]
11 | $$
12 | 显然,对于每个样本x,若h能最小化条件风险R(h(x)|x)则总体风险R(h)也将被最小化,这就产生了贝叶斯判定准则:为最小化总体风险,只需在每个样本上选择那个能使条件风险R(c|x)最小的类别标记,即
13 | $$
14 | h^*(x)= argmin_{c∈Y}R(c|x)
15 | $$
16 | 此时,为贝叶斯最优分类器,与之对应的总体风险$R(h^*)$称为贝叶斯风险,$1-R(h^*)$反映了分类器所能达到的最好性能,即通过机器学习所能产生的模型精度的理论上限。
17 | 具体来说,若目标是最小化分类错误率,则误判损失$\lambda_{ij}$可以表示为,当i=j时,$\lambda_{ij}=0$,否则为1。
18 | 此时条件风险为*
19 | $$
20 | R(c|x)=1-P(c|x)
21 | $$
22 | *,于是,最小化分类错误率的贝叶斯最优分类器为
23 | $$
24 | h^*(x)= argmax_{c∈Y}P(c|x)
25 | $$
26 |
27 |
28 |
29 | # 朴素贝叶斯分类器
30 | 朴素贝叶斯分类器采用了“属性条件独立性假设”:对已知类别,假设所有属性相互独立,换言之,假设每个属性独立地对分类结果发生影响。基于属性条件独立性假
31 | $$
32 | P(c|x)=\frac{P(c)P(x|c)}{P(x)}=\frac{P(c)}{P(x)}\displaystyle\prod_{i=1}^dP(x_i|c)
33 | $$
34 | 由于对于所有类别来说P(x)相同,贝叶斯判定准则有
35 | $$
36 | h_{nb}(x)=argmax_{c∈Y}P(c)\displaystyle\prod_{i=1}^dP(c|x)
37 | $$
38 |
--------------------------------------------------------------------------------
/ml-with-sklearn/06-Bayes/贝叶斯.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/06-Bayes/贝叶斯.pdf
--------------------------------------------------------------------------------
/ml-with-sklearn/06-Bayes/贝叶斯分类器.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "resident-number",
6 | "metadata": {},
7 | "source": [
8 | "# 贝叶斯分类器"
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "id": "handy-palestine",
14 | "metadata": {},
15 | "source": [
16 | "贝叶斯决策论是概率框架下实施决策的基本方法,对于分类任务来说,在所有相关概率都已知的理想情况下,贝叶斯决策论考虑如何基于这些概率和误判损失来选择最优的类别标记。"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "id": "soviet-colon",
22 | "metadata": {},
23 | "source": [
24 | "假设有N种可能的类别标记,即$Y ={c_1,c_2,c_3...c_N},\\lambda_{ij} $是将一个真实标记为$ c_j $的样误分类为$ c_i $所产生的损失.基于后验概率P($c_i$|x)可以获得将样本x误分类成$c_i$所产生的的期望损失,记载样本x上的“条件风险”\n",
25 | "$$R(c_i|x)=\\displaystyle\\sum_{j=1}^N \\lambda_{ij}P(c_i|x)$$"
26 | ]
27 | },
28 | {
29 | "cell_type": "markdown",
30 | "id": "oriented-radical",
31 | "metadata": {},
32 | "source": [
33 | "我们的任务是寻找一个判定准则h:X<->Y以最小化总体风险\n",
34 | "$$R(h)=E_x[R(h(x)|x)]$$"
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "id": "light-conspiracy",
40 | "metadata": {},
41 | "source": [
42 | "显然,对于每个样本x,若h能最小化条件风险R(h(x)|x)则总体风险R(h)也将被最小化,这就产生了贝叶斯判定准则:为最小化总体风险,只需在每个样本上选择那个能使条件风险R(c|x)最小的类别标记,即$$ h^*(x)= argmin_{c∈Y}R(c|x)$$"
43 | ]
44 | },
45 | {
46 | "cell_type": "markdown",
47 | "id": "reserved-pendant",
48 | "metadata": {},
49 | "source": [
50 | "此时,为贝叶斯最优分类器,与之对应的总体风险$R(h^*)$称为贝叶斯风险,$1-R(h^*)$反映了分类器所能达到的最好性能,即通过机器学习所能产生的模型精度的理论上限。"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "id": "adopted-pottery",
56 | "metadata": {},
57 | "source": [
58 | "具体来说,若目标是最小化分类错误率,则误判损失$\\lambda_{ij}$可以表示为,当i=j时,$\\lambda_{ij}=0$,否则为1。\n",
59 | "此时条件风险为$$R(c|x)=1-P(c|x)$$,于是,最小化分类错误率的贝叶斯最优分类器为$$h^*(x)= argmax_{c∈Y}P(c|x)$$"
60 | ]
61 | },
62 | {
63 | "cell_type": "markdown",
64 | "id": "occupied-survey",
65 | "metadata": {},
66 | "source": [
67 | "# 朴素贝叶斯分类器"
68 | ]
69 | },
70 | {
71 | "cell_type": "markdown",
72 | "id": "southwest-method",
73 | "metadata": {},
74 | "source": [
75 | "朴素贝叶斯分类器采用了“属性条件独立性假设”:对已知类别,假设所有属性相互独立,换言之,假设每个属性独立地对分类结果发生影响。基于属性条件独立性假$$P(c|x)=\\frac{P(c)P(x|c)}{P(x)}=\\frac{P(c)}{P(x)}\\displaystyle\\prod_{i=1}^dP(x_i|c)$$"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "id": "acknowledged-violin",
81 | "metadata": {},
82 | "source": [
83 | "由于对于所有类别来说P(x)相同,贝叶斯判定准则有\n",
84 | "$$h_{nb}(x)=argmax_{c∈Y}P(c)\\displaystyle\\prod_{i=1}^dP(c|x)$$"
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": null,
90 | "id": "smooth-industry",
91 | "metadata": {},
92 | "outputs": [],
93 | "source": []
94 | }
95 | ],
96 | "metadata": {
97 | "kernelspec": {
98 | "display_name": "Python 3",
99 | "language": "python",
100 | "name": "python3"
101 | },
102 | "language_info": {
103 | "codemirror_mode": {
104 | "name": "ipython",
105 | "version": 3
106 | },
107 | "file_extension": ".py",
108 | "mimetype": "text/x-python",
109 | "name": "python",
110 | "nbconvert_exporter": "python",
111 | "pygments_lexer": "ipython3",
112 | "version": "3.9.2"
113 | }
114 | },
115 | "nbformat": 4,
116 | "nbformat_minor": 5
117 | }
118 |
--------------------------------------------------------------------------------
/ml-with-sklearn/07-Random Forest/bagging与随机森林.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "identical-indie",
6 | "metadata": {},
7 | "source": [
8 | "# bagging与随机森林"
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "id": "elementary-tours",
14 | "metadata": {},
15 | "source": [
16 | "欲得到泛化性能强的集成,集成中的个体学习器应尽可能相互独立;虽然“独立”在现实任务中无法做到,但可以设法使基学习器尽可能具有较大的差异.给定一个训练数据集,一种可能的做法是对训练样本进行采样,由于训练数据不同,我们获得的基学习器可望具有比较大的差异.然而,为获得好的集成,我们同时还希望个体学习器不能太差,如果采样出的每个子集都完全不同,则每个基学习器只用到了一小部分训练数据,甚至不足以进行有效学习,这显然无法确保产生出比较好的基学习器.为解决这个问题,我们可考虑使用相互有交叠的采样子集."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "id": "consecutive-entity",
22 | "metadata": {},
23 | "source": [
24 | "## Bagging"
25 | ]
26 | },
27 | {
28 | "cell_type": "markdown",
29 | "id": "perfect-museum",
30 | "metadata": {},
31 | "source": [
32 | "给定包含m个样本的数据集,我们先随机取出一个样本放入采样集中,再把该样本放回初始数据集,使得下次采样时该样本仍有可能被选中,这样,经过m\n",
33 | "次随机采样操作,我们得到含m个样本的采样集,初始训练集中有的样本在采样集里多次出现,有的则从未出现.初始训练集中约有63.2%,\n",
34 | "照这样,我们可采样出T个含m个训练样本的采样集,然后基于每个采样集训练出一个基学习器,再将这些基学习器进行结合.这就是Bagging的基本流程.在对预测输出进行结合时,Bagging通常对分类任务使用简单投票法,对回归任务使用简单平均法.若分类预测时出现两个类收到同样票数的情形,则最简单的做法是随机选择-一个,也可进一步考察学习器投票的置信度来确定最终胜者. "
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "id": "supreme-vitamin",
40 | "metadata": {},
41 | "source": [
42 | "算法描述如下:\n",
43 | "输入: 训练集$D={(x_1,y_1),(x_2,y_2),...,(x_m,y_m)}$\n",
44 | " 基学习算法$\\xi$\n",
45 | " 训练轮次T\n",
46 | "过程:\n",
47 | "1. for t=1,2,3..T do\n",
48 | "2. $h_t=\\xi(D,D_{bs})$\n",
49 | "3. end for\n",
50 | "\n",
51 | "输出:$H(x)=arg\\max\\limits_{y∈Y}\\displaystyle\\sum_{t=1}^TII(h_t(x)=y)$"
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "id": "raised-round",
57 | "metadata": {},
58 | "source": [
59 | "## 随机森林"
60 | ]
61 | },
62 | {
63 | "cell_type": "markdown",
64 | "id": "outer-davis",
65 | "metadata": {},
66 | "source": [
67 | "随机森林(Random Forest,简称RF)是Bagging的一个扩展变体.RF在以决策树为基学习器构建Bagging集成的基础上,进一步在决策树的训练过程中引入了随机属性选择.具体来说,传统决策树在选择划分属性时是在当前结点的属性集合(假定有d个属性)中选择-一个最优属性;而在RF中,对基决策树的每个结点,先从该结点的属性集合中随机选择一个包含k个属性的子集,然后再从这个子集中选择一个最优属性用于划分.这里的参数k控制了随机性的引入程度:若令k=d,则基决策树的构建与传统决策树相同;若令k= 1,则是随机选择-一个属性用于划分;一般情况下,推荐值$k = log_2d$"
68 | ]
69 | }
70 | ],
71 | "metadata": {
72 | "kernelspec": {
73 | "display_name": "Python 3",
74 | "language": "python",
75 | "name": "python3"
76 | },
77 | "language_info": {
78 | "codemirror_mode": {
79 | "name": "ipython",
80 | "version": 3
81 | },
82 | "file_extension": ".py",
83 | "mimetype": "text/x-python",
84 | "name": "python",
85 | "nbconvert_exporter": "python",
86 | "pygments_lexer": "ipython3",
87 | "version": "3.9.2"
88 | }
89 | },
90 | "nbformat": 4,
91 | "nbformat_minor": 5
92 | }
93 |
--------------------------------------------------------------------------------
/ml-with-sklearn/07-Random Forest/bagging和随机森林.md:
--------------------------------------------------------------------------------
1 | # bagging与随机森林
2 | 欲得到泛化性能强的集成,集成中的个体学习器应尽可能相互独立;虽然“独立”在现实任务中无法做到,但可以设法使基学习器尽可能具有较大的差异.给定一个训练数据集,一种可能的做法是对训练样本进行采样,由于训练数据不同,我们获得的基学习器可望具有比较大的差异.然而,为获得好的集成,我们同时还希望个体学习器不能太差,如果采样出的每个子集都完全不同,则每个基学习器只用到了一小部分训练数据,甚至不足以进行有效学习,这显然无法确保产生出比较好的基学习器.为解决这个问题,我们可考虑使用相互有交叠的采样子集.
3 | ## Bagging
4 | 给定包含m个样本的数据集,我们先随机取出一个样本放入采样集中,再把该样本放回初始数据集,使得下次采样时该样本仍有可能被选中,这样,经过m
5 | 次随机采样操作,我们得到含m个样本的采样集,初始训练集中有的样本在采样集里多次出现,有的则从未出现.初始训练集中约有63.2%,
6 | 照这样,我们可采样出T个含m个训练样本的采样集,然后基于每个采样集训练出一个基学习器,再将这些基学习器进行结合.这就是Bagging的基本流程.在对预测输出进行结合时,Bagging通常对分类任务使用简单投票法,对回归任务使用简单平均法.若分类预测时出现两个类收到同样票数的情形,则最简单的做法是随机选择-一个,也可进一步考察学习器投票的置信度来确定最终胜者.
7 | 算法描述如下:
8 | 输入: 训练集$D={(x_1,y_1),(x_2,y_2),...,(x_m,y_m)}$
9 | 基学习算法$\xi$
10 | 训练轮次T
11 | 过程:
12 | 1. for t=1,2,3..T do
13 | 2. $h_t=\xi(D,D_{bs})$
14 | 3. end for
15 |
16 | 输出:
17 | $$
18 | H(x)=arg\max\limits_{y∈Y}\displaystyle\sum_{t=1}^TII(h_t(x)=y)
19 | $$
20 |
21 | ## 随机森林
22 | 随机森林(Random Forest,简称RF)是Bagging的一个扩展变体.RF在以决策树为基学习器构建Bagging集成的基础上,进一步在决策树的训练过程中引入了随机属性选择.具体来说,传统决策树在选择划分属性时是在当前结点的属性集合(假定有d个属性)中选择-一个最优属性;而在RF中,对基决策树的每个结点,先从该结点的属性集合中随机选择一个包含k个属性的子集,然后再从这个子集中选择一个最优属性用于划分.这里的参数k控制了随机性的引入程度:若令k=d,则基决策树的构建与传统决策树相同;若令k= 1,则是随机选择-一个属性用于划分;一般情况下,推荐值$k = log_2d$
--------------------------------------------------------------------------------
/ml-with-sklearn/07-Random Forest/bagging和随机森林.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/07-Random Forest/bagging和随机森林.pdf
--------------------------------------------------------------------------------
/ml-with-sklearn/07-Random Forest/bagging和随机森林.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | from sklearn.datasets import load_wine
3 | from sklearn.model_selection import train_test_split
4 | from sklearn.metrics import accuracy_score
5 | from sklearn.tree import DecisionTreeClassifier
6 | import matplotlib.pyplot as plt
7 |
8 | wine = load_wine()#使用葡萄酒数据集
9 | print(f"所有特征:{wine.feature_names}")
10 | X = pd.DataFrame(wine.data, columns=wine.feature_names)
11 | y = pd.Series(wine.target)
12 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=1)
13 | #构建并训练决策树分类器,这里特征选择标准使用基尼指数,树的最大深度为1
14 | base_model = DecisionTreeClassifier(max_depth=1, criterion='gini',random_state=1).fit(X_train, y_train)
15 | y_pred = base_model.predict(X_test)#对训练集进行预测
16 | print(f"决策树的准确率:{accuracy_score(y_test,y_pred):.3f}")
17 |
18 | ## bagging
19 | from sklearn.ensemble import BaggingClassifier
20 | # 建立AdaBoost分类器,每个基本分类模型为前面训练的决策树模型,最大的弱学习器的个数为50
21 | model = BaggingClassifier(base_estimator=base_model,
22 | n_estimators=50,
23 | random_state=1)
24 | model.fit(X_train, y_train)# 训练
25 | y_pred = model.predict(X_test)# 预测
26 | print(f"BaggingClassifier的准确率:{accuracy_score(y_test,y_pred):.3f}")
27 |
28 |
29 | # 测试估计器个数的影响
30 | x = list(range(2, 102, 2)) # 估计器个数即n_estimators,在这里我们取[2,102]的偶数
31 | y = []
32 |
33 | for i in x:
34 | model = BaggingClassifier(base_estimator=base_model,
35 | n_estimators=i,
36 |
37 | random_state=1)
38 |
39 | model.fit(X_train, y_train)
40 | model_test_sc = accuracy_score(y_test, model.predict(X_test))
41 | y.append(model_test_sc)
42 |
43 | plt.style.use('ggplot')
44 | plt.title("Effect of n_estimators", pad=20)
45 | plt.xlabel("Number of base estimators")
46 | plt.ylabel("Test accuracy of BaggingClassifier")
47 | plt.plot(x, y)
48 | plt.show()
49 |
50 | ## 随机森林
51 |
52 | from sklearn.ensemble import RandomForestClassifier
53 | model = RandomForestClassifier(
54 | n_estimators=50,
55 | random_state=1)
56 | model.fit(X_train, y_train)# 训练
57 | y_pred = model.predict(X_test)# 预测
58 | print(f"RandomForestClassifier的准确率:{accuracy_score(y_test,y_pred):.3f}")
59 |
60 | x = list(range(2, 102, 2)) # 估计器个数即n_estimators,在这里我们取[2,102]的偶数
61 | y = []
62 |
63 | for i in x:
64 | model = RandomForestClassifier(
65 | n_estimators=i,
66 |
67 | random_state=1)
68 |
69 | model.fit(X_train, y_train)
70 | model_test_sc = accuracy_score(y_test, model.predict(X_test))
71 | y.append(model_test_sc)
72 |
73 | plt.style.use('ggplot')
74 | plt.title("Effect of n_estimators", pad=20)
75 | plt.xlabel("Number of base estimators")
76 | plt.ylabel("Test accuracy of RandomForestClassifier")
77 | plt.plot(x, y)
78 | plt.show()
--------------------------------------------------------------------------------
/ml-with-sklearn/08-AdaBoost/AdaBoost.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 14,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from sklearn.tree import DecisionTreeClassifier\n",
10 | "from sklearn.metrics import accuracy_score"
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": 19,
16 | "metadata": {},
17 | "outputs": [
18 | {
19 | "name": "stdout",
20 | "output_type": "stream",
21 | "text": [
22 | "决策树的准确率:0.694\n"
23 | ]
24 | }
25 | ],
26 | "source": [
27 | "#构建并训练决策树分类器,这里特征选择标准使用基尼指数,树的最大深度为1\n",
28 | "base_model = DecisionTreeClassifier(max_depth=1, criterion='gini',random_state=1).fit(X_train, y_train)\n",
29 | "y_pred = base_model.predict(X_test)#对训练集进行预测\n",
30 | "print(f\"决策树的准确率:{accuracy_score(y_test,y_pred):.3f}\")"
31 | ]
32 | },
33 | {
34 | "cell_type": "code",
35 | "execution_count": 23,
36 | "metadata": {},
37 | "outputs": [
38 | {
39 | "name": "stdout",
40 | "output_type": "stream",
41 | "text": [
42 | "所有特征:['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids', 'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue', 'od280/od315_of_diluted_wines', 'proline']\n",
43 | "训练数据量:142,测试数据量:36\n",
44 | "准确率:0.97\n"
45 | ]
46 | }
47 | ],
48 | "source": [
49 | "from sklearn.ensemble import AdaBoostClassifier\n",
50 | "from sklearn.model_selection import GridSearchCV\n",
51 | "from sklearn.datasets import load_wine\n",
52 | "from sklearn.model_selection import train_test_split\n",
53 | "from sklearn import metrics\n",
54 | "import pandas as pd\n",
55 | "\n",
56 | "wine = load_wine()#使用葡萄酒数据集\n",
57 | "print(f\"所有特征:{wine.feature_names}\")\n",
58 | "X = pd.DataFrame(wine.data, columns=wine.feature_names)\n",
59 | "y = pd.Series(wine.target)\n",
60 | "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=1)\n",
61 | "\n",
62 | "\n",
63 | "print(f\"训练数据量:{len(X_train)},测试数据量:{len(X_test)}\")\n",
64 | "\n",
65 | "# 定义模型,这里最大分类器数量为50,学习率为1.5\n",
66 | "model = AdaBoostClassifier(base_estimator=base_model,n_estimators=50,learning_rate=0.8)\n",
67 | "# 训练\n",
68 | "model.fit(X_train, y_train) \n",
69 | "# 预测\n",
70 | "y_pred = model.predict(X_test) \n",
71 | "acc = metrics.accuracy_score(y_test, y_pred) # 准确率\n",
72 | "print(f\"准确率:{acc:.2}\")\n"
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "metadata": {},
78 | "source": [
79 | "## 使用GridSearchCV自动调参"
80 | ]
81 | },
82 | {
83 | "cell_type": "code",
84 | "execution_count": 24,
85 | "metadata": {},
86 | "outputs": [
87 | {
88 | "name": "stdout",
89 | "output_type": "stream",
90 | "text": [
91 | "最优超参数: {'learning_rate': 0.8, 'n_estimators': 42}\n"
92 | ]
93 | }
94 | ],
95 | "source": [
96 | "hyperparameter_space = {'n_estimators':list(range(2, 102, 2)), \n",
97 | " 'learning_rate':[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]}\n",
98 | "\n",
99 | "\n",
100 | "# 使用准确率为标准,将得到的准确率最高的参数输出,cv=5表示交叉验证参数,这里使用五折交叉验证,n_jobs=-1表示并行数和cpu一致\n",
101 | "gs = GridSearchCV(AdaBoostClassifier(\n",
102 | " algorithm='SAMME.R',\n",
103 | " random_state=1),\n",
104 | " param_grid=hyperparameter_space, \n",
105 | " scoring=\"accuracy\", n_jobs=-1, cv=5)\n",
106 | "\n",
107 | "gs.fit(X_train, y_train)\n",
108 | "print(\"最优超参数:\", gs.best_params_)"
109 | ]
110 | },
111 | {
112 | "cell_type": "code",
113 | "execution_count": null,
114 | "metadata": {},
115 | "outputs": [],
116 | "source": []
117 | }
118 | ],
119 | "metadata": {
120 | "interpreter": {
121 | "hash": "47dfafb046f9703cd15ca753999a7e7c95274099825c7bcc45b473d6496cd1b0"
122 | },
123 | "kernelspec": {
124 | "display_name": "Python 3",
125 | "language": "python",
126 | "name": "python3"
127 | },
128 | "language_info": {
129 | "codemirror_mode": {
130 | "name": "ipython",
131 | "version": 3
132 | },
133 | "file_extension": ".py",
134 | "mimetype": "text/x-python",
135 | "name": "python",
136 | "nbconvert_exporter": "python",
137 | "pygments_lexer": "ipython3",
138 | "version": "3.8.3"
139 | },
140 | "toc": {
141 | "base_numbering": 1,
142 | "nav_menu": {},
143 | "number_sections": true,
144 | "sideBar": true,
145 | "skip_h1_title": false,
146 | "title_cell": "Table of Contents",
147 | "title_sidebar": "Contents",
148 | "toc_cell": false,
149 | "toc_position": {},
150 | "toc_section_display": true,
151 | "toc_window_display": false
152 | },
153 | "varInspector": {
154 | "cols": {
155 | "lenName": 16,
156 | "lenType": 16,
157 | "lenVar": 40
158 | },
159 | "kernels_config": {
160 | "python": {
161 | "delete_cmd_postfix": "",
162 | "delete_cmd_prefix": "del ",
163 | "library": "var_list.py",
164 | "varRefreshCmd": "print(var_dic_list())"
165 | },
166 | "r": {
167 | "delete_cmd_postfix": ") ",
168 | "delete_cmd_prefix": "rm(",
169 | "library": "var_list.r",
170 | "varRefreshCmd": "cat(var_dic_list()) "
171 | }
172 | },
173 | "types_to_exclude": [
174 | "module",
175 | "function",
176 | "builtin_function_or_method",
177 | "instance",
178 | "_Feature"
179 | ],
180 | "window_display": false
181 | }
182 | },
183 | "nbformat": 4,
184 | "nbformat_minor": 2
185 | }
186 |
--------------------------------------------------------------------------------
/ml-with-sklearn/08-AdaBoost/AdaBoost.py:
--------------------------------------------------------------------------------
1 | from sklearn.ensemble import AdaBoostClassifier
2 | from sklearn import datasets
3 | from sklearn.model_selection import train_test_split
4 | from sklearn import metrics
5 |
6 | iris = datasets.load_iris()
7 | X = iris.data
8 | y = iris.target
9 |
10 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
11 |
12 | print("X_train:",len(X_train),"; X_test:",len(X_test),"; y_train:",len(y_train),"; y_test:",len(y_test))
13 |
14 | # Create adaboost object
15 | Adbc = AdaBoostClassifier(n_estimators=50,
16 | learning_rate=1.5)
17 | # Train Adaboost
18 | model = Adbc.fit(X_train, y_train)
19 |
20 | #Predict the response for test dataset
21 | y_pred = model.predict(X_test)
22 |
23 | print("Accuracy:",metrics.accuracy_score(y_test, y_pred))
24 | #('Accuracy:', 0.8888888888888888)
--------------------------------------------------------------------------------
/ml-with-sklearn/08-AdaBoost/AdaBoost算法.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# AdaBoost"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "boosting是一族将弱学习器提升为强学习器的算法。这族算法的工作机制是:先从初试训练集训练出一个基学习器,再根据基学习器的表现对训练样本进行调整,使得先前基学习器做错的训练样本在后续受到更多关注,然后基于调整后的样本分布来训练下一个基分类器,如此重复进行,直至基学习器数目达到实现指定值T,最后将这T个基学习器进行加权组合"
15 | ]
16 | },
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {},
20 | "source": [
21 | "boosting族算法最著名的代表室AdaBoost,AdaBoost算法有多种推导方式,比较容易理解的是基于“加性模型”,即基学习器的线性组合$$H(x)=\\displaystyle\\sum_{t=1}^T \\alpha_ih_t(x)$$"
22 | ]
23 | },
24 | {
25 | "cell_type": "markdown",
26 | "metadata": {},
27 | "source": [
28 | "来最小化指数损失函数\n",
29 | " $$l_{exp}(H|D)=E_{X D}[e^{-f(x)H(x)}]$$"
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {},
35 | "source": [
36 | "算法步骤:\n",
37 | "输入:训练集 $D={(x_1,y_1),(x_2,y_2),..,(x_m,y_m)}$,\n",
38 | "\n",
39 | " 基学习算法$\\xi$\n",
40 | " \n",
41 | " 训练轮次T\n",
42 | " \n",
43 | "过程:\n",
44 | "\n",
45 | "1.D_1(X)=1/m\n",
46 | "\n",
47 | "2.for t =1,2,3...,T do:\n",
48 | "\n",
49 | "3. $h_t=\\xi(D,D_t)$\n",
50 | "4. $\\epsilon_t = P_{X~D_t}(h_t(x) ≠ f(x))$\n",
51 | "5. if $\\epsilon_t>0.5 then break$\n",
52 | "6. $\\alpha_t = \\frac{1}{2}ln(\\frac{1-\\epsilon_t}{\\epsilon_t})$\n",
53 | "7. $D_{t+1}(x)=\\frac{D_t(x)exp(-\\alpha f(x)h_t(x))}{Z_t}$\n",
54 | "8.end for\n",
55 | "\n",
56 | "输出:$H(x) = sign(\\displaystyle\\sum_{t=1}^T\\alpha_ih_t(x))$"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {},
62 | "source": [
63 | "\n",
64 | "其中$\\epsilon_{i}$是每个弱分类器的错误率。$Z_t$是规范化因子,以确保$D_{t+1}$是一个分布\n",
65 | "\n"
66 | ]
67 | }
68 | ],
69 | "metadata": {
70 | "kernelspec": {
71 | "display_name": "Python 3",
72 | "language": "python",
73 | "name": "python3"
74 | },
75 | "language_info": {
76 | "codemirror_mode": {
77 | "name": "ipython",
78 | "version": 3
79 | },
80 | "file_extension": ".py",
81 | "mimetype": "text/x-python",
82 | "name": "python",
83 | "nbconvert_exporter": "python",
84 | "pygments_lexer": "ipython3",
85 | "version": "3.8.3"
86 | },
87 | "toc": {
88 | "base_numbering": 1,
89 | "nav_menu": {},
90 | "number_sections": true,
91 | "sideBar": true,
92 | "skip_h1_title": false,
93 | "title_cell": "Table of Contents",
94 | "title_sidebar": "Contents",
95 | "toc_cell": false,
96 | "toc_position": {},
97 | "toc_section_display": true,
98 | "toc_window_display": false
99 | },
100 | "varInspector": {
101 | "cols": {
102 | "lenName": 16,
103 | "lenType": 16,
104 | "lenVar": 40
105 | },
106 | "kernels_config": {
107 | "python": {
108 | "delete_cmd_postfix": "",
109 | "delete_cmd_prefix": "del ",
110 | "library": "var_list.py",
111 | "varRefreshCmd": "print(var_dic_list())"
112 | },
113 | "r": {
114 | "delete_cmd_postfix": ") ",
115 | "delete_cmd_prefix": "rm(",
116 | "library": "var_list.r",
117 | "varRefreshCmd": "cat(var_dic_list()) "
118 | }
119 | },
120 | "types_to_exclude": [
121 | "module",
122 | "function",
123 | "builtin_function_or_method",
124 | "instance",
125 | "_Feature"
126 | ],
127 | "window_display": false
128 | }
129 | },
130 | "nbformat": 4,
131 | "nbformat_minor": 5
132 | }
133 |
--------------------------------------------------------------------------------
/ml-with-sklearn/08-AdaBoost/README.md:
--------------------------------------------------------------------------------
1 | Adaboost[Freund and Schapire, 1997]是一种boosting算法。与boosting算法相似的有bagging,两者同属于ensemble learning。
2 |
3 | 把准确率不高但在50%以上(比如60%)的分类器称为弱分类器,弱分类器可以是一些基础的ML算法比如单层决策树等。对于同一数据可能有多种弱分类器,adaboost就是将这些弱分类器结合起来,称为基分类器,从而有效提高整体的准确率。但是要想获得好的结合或者集成,对基分类器的要求是“好而不同”,即有一定的准确率,而且弱分类器之间要有“多样性”,比如一个判断是否为男性的任务,弱分类器1侧重从鼻子、耳朵这些特征判断是否是男人,分类器2侧重脸和眼睛等等,把这些分类器结合起来就有了所有用来判断是否男性的特征,并且adaboost还可以给每个基分类器赋值不同的权重,比如从脸比鼻子更能判断是否为男性,就可以把分类器2的权重调高一些,这也是adaboost需要学习的内容。
4 |
5 | ## 数学推导
6 |
7 | AdaBoost可以表示为基分类器的线性组合:
8 | $$
9 | H(\boldsymbol{x})=\sum_{i=1}^{N} \alpha_{i} h_{i}(\boldsymbol{x})
10 | $$
11 | 其中$h_i(x),i=1,2,...$表示基分类器,$\alpha_i$是每个基分类器对应的权重,表示如下:
12 | $$
13 | \alpha_{i}=\frac{1}{2} \ln \left(\frac{1-\epsilon_{i}}{\epsilon_{i}}\right)
14 | $$
15 | 其中$\epsilon_{i}$是每个弱分类器的错误率。
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ml-with-sklearn/09-K-means/k-means.md:
--------------------------------------------------------------------------------
1 | ### 1.聚类的概念
2 |
3 | 对于有标签的数据,我们进行有监督学习,常见的分类任务就是监督学习;而对于无标签的数据,我们希望发现无标签的数据中的潜在信息,这就是无监督学习。聚类,就是无监督学习的一种,它的概念是:将相似的对象归到同一个簇中,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。即聚类后同一类的数据尽可能聚集到一起,不同数据尽量分离。
4 |
5 | ### 2.聚类算法的分类
6 |
7 | 聚类算法有很多种分法,常见的分类方法有:
8 |
9 | 1. 基于划分的聚类:聚类目标是使得类内的点足够近,类间的点足够远,常见的如k-means及其衍生算法
10 | 2. 基于密度的聚类:当邻近区域的密度超过某个阈值,则继续聚类,如DBSCAN; OPTICS
11 | 3. 层次聚类:包括合并的层次聚类,分裂的层次聚类,实际上可以看作是二叉树的生成和分裂过程。
12 | 4. 基于图的聚类: 通过建图来进行聚类,这是聚类算法中的大头,很多较新的聚类算法都有图聚类的思想。
13 |
14 | 更多的分类可以参考[sklearn文档中关于聚类的划分](https://scikit-learn.org/stable/modules/clustering.html#k-means)
15 |
16 | 
17 |
18 | ### 3.性能度量
19 | 在机器学习中我们都需要对任务进行评价以便于进行下一步的优化,聚类的性能度量主要有一下两种。
20 | * 外部指标:是指把算法得到的划分结果跟某个外部的“参考模型”(如专家给出的划分结果)比较。其实质就是分析分错了和分对了的比例来衡量聚类效果
21 | * 内部指标:是指直接考察聚类结果,不利用任何参考模型的指标。例如轮廓系数:衡量了每个簇中的紧凑度,以及簇间的距离。当每个簇中距离越紧凑,每个簇间距离越远则认为聚类效果优秀。
22 |
23 | ### 4.距离计算
24 | 在机器学习和数据挖掘中,我们经常需要知道个体间差异的大小,进而评价个体的相似性和类别。
25 | * 欧式距离(2-norm距离):欧氏距离是最易于理解的一种距离计算方法,源自欧氏空间中两点间的距离公式。
26 | $$d(x,y)=\sqrt{\Sigma_{k=1}^n (x_k-y_k)^2}$$
27 | * 曼哈顿距离(Manhattan distance, 1-norm距离):曼哈顿距离也称为街区距离,是数学中比较常用的距离度量之一,用以表示标准坐标系下两点之间的轴距和。计算公式如下:
28 | $$d(x,y)=\Sigma_{k=1}^n \left|x_k-y_k\right|$$
29 | * 切比雪夫距离:切比雪夫距离和曼哈顿距离类似,但其采用的是两点之间的最大轴距。
30 | $$d(x,y) = \lim_{n\rightarrow \infty} (\Sigma_{k=1}^n (\left|x_k-y_k\right|)^r)^\dfrac{1}{r} = max_k (\left|x_k-y_k\right|)$$
31 | * 闵可夫斯基距离
32 | $$d(x,y)=(\Sigma_{k=1}^n (\left|x_k-y_k\right|)^r)^\dfrac{1}{r}$$
33 | 式中,r是一个可变参数,根据参数r取值的不同,闵可夫斯基距离可以表示一类距离
34 | r = 1时,为曼哈顿距离
35 | r = 2时,为欧式距离
36 | r →∞时,为切比雪夫距离
37 | 闵可夫斯基距离包括欧式距离、曼哈顿距离、切比雪夫距离都假设数据各维属性的量纲和分布(期望、方差)相同,因此适用于度量独立同分布的数据对象。
38 | * 余弦相似性:余弦相似度公式定义如下:
39 | $$cos(x,y)=\dfrac{xy}{\left|x\right|\left|y\right|} = \dfrac{\Sigma_{k=1}^n x_k y_k}{\sqrt{\Sigma_{k=1}^n x_k^2} \sqrt{\Sigma_{k=1}^n y_k^2}}$$
40 | 余弦相似度实际上是向量x和y夹角的余弦度量,可用来衡量两个向量方向的差异。如果余弦相似度为1,则x和y之间夹角为0°,两向量除模外可认为是相同的;如果预先相似度为0,则x和y之间夹角为90°,则认为两向量完全不同。在计算余弦距离时,将向量均规范化成具有长度11,因此不用考虑两个数据对象的量值。
41 | 余弦相似度常用来度量文本之间的相似性。文档可以用向量表示,向量的每个属性代表一个特定的词或术语在文档中出现的频率,尽管文档具有大量的属性,但每个文档向量都是稀疏的,具有相对较少的非零属性值。
42 | * 马氏距离
43 | $$mahalanobis(x,y)=(x-y)\Sigma^{-1}(x-y)^T$$
44 | 式中,Σ−1是数据协方差矩阵的逆。
45 | 前面的距离度量方法大都假设样本独立同分布、数据属性之间不相关。马氏距离考虑了数据属性之间的相关性,排除了属性间相关性的干扰,而且与量纲无关。若协方差矩阵是对角阵,则马氏距离变成了标准欧式距离;若协方差矩阵是单位矩阵,各个样本向量之间独立同分布,则变成欧式距离。
46 |
47 | ### 5.K-means
48 | **本次只介绍这一种算法,剩下的大家可以参考前面的sklearn文档实现。**
49 |
50 | 对于K-Means算法,首先要注意的是k值的选择,一般来说,我们会根据对数据的先验经验选择一个合适的k值,如果没有什么先验知识,则可以通 过交叉验证选择一个合适的k值。在确定了k的个数后,我们需要选择k个初始化的质心。由于我们是启发式方法,k个初始化的质心的位置选择对最后的聚 类结果和运行时间都有很大的影响,因此需要选择合适的k个质心,最好这些质心不能太近。
51 |
52 | 总结下传统的K-Means算法流程就是:
53 |
54 | - 输入是样本隻 $D=\left\{x_{1}, x_{2}, \ldots x_{m}\right\}$, 聚类的笶树 $\mathrm{k}$, 最大迭代次数 $\mathrm{N}$
55 | - 输出是笶划分 $C=\left\{C_{1}, C_{2}, \ldots C_{k}\right\}$
56 | 1. 从数据集 $\mathrm{D}$ 中随机选择 $\mathrm{k}$ 个样本作为初始的 $\mathrm{k}$ 个质心向量: $\left\{\mu_{1}, \mu_{2}, \ldots, \mu_{k}\right\}$
57 | 2. 对于 $n=1,2, \ldots, \mathrm{N}$
58 | 1. 将簇划分 $\mathrm{C}$ 初始化为 $C_{t}=\varnothing, t=1,2 \ldots k$
59 | 2. 对于 $\mathrm{i}=1,2 \ldots \mathrm{m}$, 计算样本 $x_{i}$ 和各个质心向量 $\mu_{j}(j=1,2, \ldots k)$ 的距离: $d_{i j}=\left\|x_{i}-\mu_{j}\right\|_{2}^{2}$ , 将 $x_{i}$ 标记最小的为 $d_{i j}$ 所对应的类别 $\lambda_{i}$ 。此时更 新 $C_{\lambda_{i}}=C_{\lambda_{i}} \cup\left\{x_{i}\right\}$
60 | 3. 对于 $\mathrm{j}=1,2, \ldots, \mathrm{k}$, 对 $C_{j}$ 中所有的样本点重新计算新的质心$\mu_{j}=\frac{1}{\left|C_{j}\right|} \sum_{x \in C_{j}} x$
61 | 4. 如果所有的 $k$ 个质心向量都没有发生变化,则转到步骧3
62 | 3. 输出笶划分 $C=\left\{C_{1}, C_{2}, \ldots C_{k}\right\}$
63 |
64 | **例如下图所示**
65 |
66 | 
67 |
68 |
69 | 下面是使用sklearn的一个简单demo
70 |
71 | ### 6.K-means的优缺点
72 |
73 | - **优点**
74 | - 原理比较简单,实现也是很容易,收敛速度快。
75 | - 聚类效果较优。
76 | - 算法的可解释度比较强。
77 | - 主要需要调参的参数仅仅是簇数k。
78 |
79 | - **缺点**
80 | - K值的选取不好把握
81 | - 最终结果和初始点的选择有关,容易陷入局部最优。
82 | - 对噪音和异常点比较的敏感。
83 | - 数据必须符合“数据之间的相似度可以使用欧式距离衡量”,这个是什么意思呢,看下图,这种数据的分布,样本点的距离不能简单地用欧式距离来衡量,否则分类效果会非常差。这里的距离衡量应该是“测地距离”,也就是样本沿着曲面到达另一个样本点的距离。如果在这种数据空间想要使用kmeans,必须先进行空间的转化
84 |
85 | 
86 |
87 | k-means有一些改进算法,多是针对k-means会受异常点的影响这一点来改进的,这里就不详细赘述,只是简单提一下,起一个抛砖引玉的作用。
88 | | 缺点 | 改进 | 描述 |
89 | | -------------- | --------- | ------------------------------------------------------------ |
90 | | k值的确定 | ISODATA | 当属于某个簇的样本数过少时把这个簇去除,
当属于某个簇的样本数过多、分散程度较大时把这个簇分为两个子簇|
91 | | 对奇异点敏感 | k-median | 中位数代替平均值作为簇中心 |
92 | | 只能找到球状群 | GMM | 以高斯分布考虑簇内数据点的分布 |
93 | | 分群结果不稳定 | K-means++ | 初始的聚类中心之间的相互距离要尽可能的远
94 |
95 |
96 | 详细见:https://scikit-learn.org/stable/modules/clustering.html#overview-of-clustering-methods
97 |
98 | 
99 |
100 | ### 6、代码实践
101 |
102 | - sklearn:[k-means.ipynb](./k-means.ipynb)
103 | - numpy:[k-means.py](k-means.py)
104 |
105 | ### 8.常见面试题
106 |
107 | **8.1 k值的选取**
108 |
109 | K-means算法要求事先知道数据集能分为几群,主要有两种方法定义k。
110 |
111 | - 手肘法:通过绘制k和损失函数的关系图,选拐点处的k值。
112 |
113 | - 经验选取人工据经验先定几个k,多次随机初始化中心选经验上最适合的。
114 |
115 | 通常都是以经验选取,因为实际操作中拐点不明显,且手肘法效率不高。
116 |
117 | **8.2 为什么在计算K-means之前要将数据点在各维度上归一化**
118 |
119 | 因为数据点各维度的量级不同。
120 | 举个例子,最近正好做完基于RFM模型的会员分群,每个会员分别有R(最近一次购买距今的时长)、F(来店消费的频率)和M(购买金额)。如果这是一家奢侈品商店,你会发现M的量级(可能几万元)远大于F(可能平均10次以下),如果不归一化就算K-means,相当于F这个特征完全无效。如果我希望能把常客与其他顾客区别开来,不归一化就做不到。
121 |
122 | **8.3 K-means不适用哪些数据**
123 |
124 | 1. 数据特征极强相关的数据集,因为会很难收敛(损失函数是非凸函数),一般要用kernal K-means,将数据点映射到更高维度再分群。
125 | 2. 数据集可分出来的簇密度不一,或有很多离群值(outliers),这时候考虑使用密度聚类。
126 |
127 |
128 | **8.4 K-means中空聚类的处理**
129 |
130 | 如果所有的点在指派步骤都未分配到某个簇,就会得到空簇。如果这种情况发生,则需要某种策略来选择一个替补质心,否则的话,平方误差将会偏大。一种方法是选择一个距离当前任何质心最远的点。这将消除当前对总平方误差影响最大的点。另一种方法是从具有最大SEE的簇中选择一个替补的质心。这将分裂簇并降低聚类的总SEE。如果有多个空簇,则该过程重复多次。另外编程实现时,要注意空簇可能导致的程序bug。
131 |
132 | **参考文献**
133 | - 西瓜书
134 | - 统计学习方法
135 | - 维基百科
136 | - https://www.zybuluo.com/rianusr/note/1199877
137 | - https://blog.csdn.net/zhouxianen1987/article/details/68945844
138 | - http://ddrv.cn/a/66611
139 | - https://zhuanlan.zhihu.com/p/29538307
140 | - https://github.com/Eajack/Statical-Learning-Method-LiHang_py_Eajack
141 | - https://github.com/datawhalechina/daily-interview
142 | - https://segmentfault.com/a/1190000041528708
--------------------------------------------------------------------------------
/ml-with-sklearn/09-K-means/k-means.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/09-K-means/k-means.pdf
--------------------------------------------------------------------------------
/ml-with-sklearn/09-K-means/k-means.py:
--------------------------------------------------------------------------------
1 | #coding=utf-8
2 | #Author:haobo
3 | #Date:2022-4-23
4 |
5 | from sklearn.cluster import KMeans
6 | import matplotlib.pyplot as plt
7 | import numpy as np
8 | import matplotlib as mpl
9 | from sklearn import datasets
10 |
11 |
12 | # 聚类前
13 | X = np.random.rand(100, 2)
14 | plt.scatter(X[:, 0], X[:, 1], marker='o')
15 |
16 | # 初始化我们的质心,从原有的数据中选取K个座位质心
17 | def InitCentroids(X, k):
18 | index = np.random.randint(0,len(X)-1,k)
19 | return X[index]
20 |
21 | #聚类后,假设k=2
22 | kmeans = KMeans(n_clusters=2).fit(X)
23 | label_pred = kmeans.labels_
24 | plt.scatter(X[:, 0], X[:, 1], c=label_pred)
25 | plt.show()
--------------------------------------------------------------------------------
/ml-with-sklearn/09-K-means/res/k-means-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/09-K-means/res/k-means-1.png
--------------------------------------------------------------------------------
/ml-with-sklearn/09-K-means/res/k-means-2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/09-K-means/res/k-means-2.webp
--------------------------------------------------------------------------------
/ml-with-sklearn/09-K-means/res/k-means-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/09-K-means/res/k-means-3.jpg
--------------------------------------------------------------------------------
/ml-with-sklearn/09-K-means/res/k-means-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/09-K-means/res/k-means-4.png
--------------------------------------------------------------------------------
/ml-with-sklearn/10-kNN/knn.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### 3.算法实践(sklearn)\n",
8 | "\n",
9 | "#### 3.1 KNeighborsClassifier 类\n",
10 | "\n",
11 | "sklearn 库的 neighbors 模块实现了KNN 相关算法,其中:\n",
12 | "- `KNeighborsClassifier` 类用于分类问题\n",
13 | "- `KNeighborsRegressor` 类用于回归问题\n",
14 | "\n",
15 | "这两个类的构造方法基本一致,这里我们主要介绍 KNeighborsClassifier 类,原型如下:\n",
16 | "\n",
17 | "```python\n",
18 | "KNeighborsClassifier(\n",
19 | "\tn_neighbors=5, \n",
20 | "\tweights='uniform', \n",
21 | "\talgorithm='auto', \n",
22 | "\tleaf_size=30, \n",
23 | "\tp=2, \n",
24 | "\tmetric='minkowski', \n",
25 | "\tmetric_params=None, \n",
26 | "\tn_jobs=None, \n",
27 | "\t**kwargs)\n",
28 | "```\n",
29 | "\n",
30 | "**来看下几个重要参数的含义:**\n",
31 | "- n_neighbors:即 KNN 中的 K 值,一般使用默认值 5。\n",
32 | "- weights:用于确定邻居的权重,有三种方式:\n",
33 | " - weights=uniform,表示所有邻居的权重相同。\n",
34 | " - weights=distance,表示权重是距离的倒数,即与距离成反比。\n",
35 | " - 自定义函数,可以自定义不同距离所对应的权重,一般不需要自己定义函数。\n",
36 | "- algorithm:用于设置计算邻居的算法,它有四种方式:\n",
37 | " - algorithm=auto,根据数据的情况自动选择适合的算法。\n",
38 | " - algorithm=kd_tree,使用 KD 树 算法。\n",
39 | " - KD 树是一种多维空间的数据结构,方便对数据进行检索。\n",
40 | " - KD 树适用于维度较少的情况,一般维数不超过 20,如果维数大于 20 之后,效率会下降。\n",
41 | " - algorithm=ball_tree,使用球树算法。\n",
42 | " - 与KD 树一样都是多维空间的数据结构。\n",
43 | " - 球树更适用于维度较大的情况。\n",
44 | " - algorithm=brute,称为暴力搜索。\n",
45 | " - 它和 KD 树相比,采用的是线性扫描,而不是通过构造树结构进行快速检索。\n",
46 | " - 缺点是,当训练集较大的时候,效率很低。\n",
47 | " - leaf_size:表示构造 KD 树或球树时的叶子节点数,默认是 30。\n",
48 | " 调整 leaf_size 会影响树的构造和搜索速度。\n"
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": 2,
54 | "metadata": {},
55 | "outputs": [],
56 | "source": [
57 | "#加载数据集\n",
58 | "from sklearn.datasets import load_digits\n",
59 | "digits = load_digits()\n",
60 | "data = digits.data # 特征集\n",
61 | "target = digits.target # 目标集\n"
62 | ]
63 | },
64 | {
65 | "cell_type": "code",
66 | "execution_count": 3,
67 | "metadata": {},
68 | "outputs": [],
69 | "source": [
70 | "#将数据集拆分为训练集(75%)和测试集(25%):\n",
71 | "from sklearn.model_selection import train_test_split\n",
72 | "train_x, test_x, train_y, test_y = train_test_split(\n",
73 | " data, target, test_size=0.25, random_state=33)"
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": 4,
79 | "metadata": {},
80 | "outputs": [],
81 | "source": [
82 | "#构造KNN分类器:\n",
83 | "from sklearn.neighbors import KNeighborsClassifier\n",
84 | "# 采用默认参数\n",
85 | "knn = KNeighborsClassifier() "
86 | ]
87 | },
88 | {
89 | "cell_type": "code",
90 | "execution_count": 7,
91 | "metadata": {},
92 | "outputs": [],
93 | "source": [
94 | "#拟合模型:\n",
95 | "knn.fit(train_x, train_y) \n",
96 | "\n",
97 | "#预测数据:\n",
98 | "predict_y = knn.predict(test_x) "
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": 8,
104 | "metadata": {},
105 | "outputs": [
106 | {
107 | "data": {
108 | "text/plain": [
109 | "0.9844444444444445"
110 | ]
111 | },
112 | "execution_count": 8,
113 | "metadata": {},
114 | "output_type": "execute_result"
115 | }
116 | ],
117 | "source": [
118 | "#计算模型准确度\n",
119 | "from sklearn.metrics import accuracy_score\n",
120 | "score = accuracy_score(test_y, predict_y)\n",
121 | "score"
122 | ]
123 | }
124 | ],
125 | "metadata": {
126 | "interpreter": {
127 | "hash": "5f04dd1d6b72ff9d002f9c97d3bf130820120c0ac9ec7321437503cd785f0e6e"
128 | },
129 | "kernelspec": {
130 | "display_name": "Python 3.9.7 ('base')",
131 | "language": "python",
132 | "name": "python3"
133 | },
134 | "language_info": {
135 | "codemirror_mode": {
136 | "name": "ipython",
137 | "version": 3
138 | },
139 | "file_extension": ".py",
140 | "mimetype": "text/x-python",
141 | "name": "python",
142 | "nbconvert_exporter": "python",
143 | "pygments_lexer": "ipython3",
144 | "version": "3.9.7"
145 | },
146 | "orig_nbformat": 4
147 | },
148 | "nbformat": 4,
149 | "nbformat_minor": 2
150 | }
151 |
--------------------------------------------------------------------------------
/ml-with-sklearn/10-kNN/knn.md:
--------------------------------------------------------------------------------
1 | ### 1.KNN算法简介
2 |
3 | KNN的全称是K Nearest Neighbors,意思是K个最近的邻居,可以用于分类和回归,是一种监督学习算法。它的思路是这样,如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。也就是说,该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。
4 |
5 | 以下图为例
6 |
7 | 
8 |
9 | 图中绿色的点就是我们要预测的那个点,假设K=3。那么KNN算法就会找到与它距离最近的三个点(这里用圆圈把它圈起来了),看看哪种类别多一些,比如这个例子中是蓝色三角形多一些,新来的绿色点就归类到蓝三角了。
10 |
11 | 
12 |
13 | 但是,当K=5的时候,判定就变成不一样了。这次变成红圆多一些,所以新来的绿点被归类成红圆。从这个例子中,我们就能看得出K的取值是很重要的。
14 |
15 | ### 2.KNN算法介绍
16 |
17 | #### 2.1 KNN算法三要素
18 |
19 | **2.1.1 关于距离的衡量方法**:具体介绍参见K-means介绍
20 |
21 | KNN算法中要求数据的所有特征都可以做量化,若在数据特征中存在非数值类型,必须采用手段将其量化为数值。
22 |
23 | 在sklearn中,KNN分类器提供了四种距离
24 | - 欧式距离(euclidean) - 默认
25 | - 曼哈顿距离(manhatten)
26 | - 切比雪夫距离(chebyshev)
27 | - 闵可夫斯基距离(minkowski)
28 |
29 | **2.1.2 K值的选择问题**
30 |
31 | 在KNN分类中,K值的选择往往没有一个固定的经验,可以通过不停调整(例如交叉验证)到一个合适的K值。
32 | 1. K为1。如果K值被设定为1,那么训练集的正确率将达到100%(将训练集同时作为预测集),因为每个点只会找到它本身,但同时在预测集中的正确率不会太高(极度过拟合)。
33 | 2. K为较小的值。较小的邻域往往会带来更低的训练误差,但会导致过拟合的问题降低预测集的准确率。
34 | 3. K为较大的值。较大的邻域会增大训练误差,但能够有效减少过拟合的问题。(注意,这并不意味着预测集的准确率一定会增加)
35 | 4. K为训练集样本数量。当K极端到邻域覆盖整个样本时,就相当于不再分类而直接选择在训练集中出现最多的类。
36 |
37 | 在实际应用中,K 值一般选择一个较小的数值,通常采用交叉验证的方法来选择最优的 K 值。随着训练实例数目趋向于无穷和 K=1 时,误差率不会超过贝叶斯误差率的2倍,如果K也趋向于无穷,则误差率趋向于贝叶斯误差率。(贝叶斯误差可以理解为最小误差)
38 |
39 | 三种交叉验证方法:
40 | - Hold-Out: 随机从最初的样本中选出部分,形成交叉验证数据,而剩余的就当做训练数据。 一般来说,少于原本样本三分之一的数据被选做验证数据。常识来说,Holdout 验证并非一种交叉验证,因为数据并没有交叉使用。
41 | - K-foldcross-validation:K折交叉验证,初始采样分割成K个子样本,一个单独的子样本被保留作为验证模型的数据,其他K-1个样本用来训练。交叉验证重复K次,每个子样本验证一次,平均K次的结果或者使用其它结合方式,最终得到一个单一估测。这个方法的优势在于,同时重复运用随机产生的子样本进行训练和验证,每次的结果验证一次,10折交叉验证是最常用的。
42 | - Leave-One-Out Cross Validation:正如名称所建议, 留一验证(LOOCV)意指只使用原本样本中的一项来当做验证资料, 而剩余的则留下来当做训练资料。 这个步骤一直持续到每个样本都被当做一次验证资料。 事实上,这等同于 K-fold 交叉验证是一样的,其中K为原本样本个数。
43 |
44 |
45 | **2.1.3 分类决策的准则**
46 |
47 | 明确K个邻居中所有数据类别的个数,将测试数据划分给个数最多的那一类。即由输入实例的 K 个最临近的训练实例中的多数类决定输入实例的类别。
48 | 最常用的两种决策规则:
49 | - 多数表决法:多数表决法和我们日常生活中的投票表决是一样的,少数服从多数,是最常用的一种方法。
50 | - 加权表决法:有些情况下会使用到加权表决法,比如投票的时候裁判投票的权重更大,而一般人的权重较小。所以在数据之间有权重的情况下,一般采用加权表决法。
51 |
52 | 多数表决法图示说明(其中K=4):
53 |
54 | 
55 |
56 | #### 2.2 KNN算法的步骤
57 |
58 |
59 | 输入: 训练数据集 $T=\left\{\left(\mathrm{x}_{1}, \mathrm{y}_{1}\right),\left(\mathrm{x}_{2}, \mathrm{y}_{2}\right) \ldots . . .\left(\mathrm{x}_{\mathrm{N}}, \mathrm{y}_{\mathrm{N}}\right)\right\}, \mathrm{x}_{1}$ 为实例的特征向量, $\mathrm{yi}=\left\{\mathrm{c}_{1}, \mathrm{c}_{2}, \ldots \mathrm{c}_{k}\right\}$ 为实剅类别。
60 |
61 | 输出: 实例 $\mathrm{x}$ 所属的类别 $\mathrm{y}$ 。
62 |
63 | **步骤:**
64 | 1. 选择参数 $K$
65 | 2. 计算末知实例与所有已知实例的距离 (可选择多种计算距离的方式)
66 | 3. 选择最近 $K$ 个已知实例
67 | 4. 根据少数服从多数的投眎法则(majority-voting), 让末知实例归类为 $\mathrm{K}$ 个最邻近样本中最多数的类别。加权表决法同理。
68 |
69 |
70 | #### 2.3 KNN算法的优缺点
71 |
72 | **优点**
73 | - KNN是一种较为成熟的算法,同时思路也比较简单,能够同时兼容回归与分类(KNN的回归将在日后的回归算法中提到)。
74 | - KNN时间复杂度为O(n)。因为是懒惰学习,在训练阶段速度比较快。
75 | - 可以用于非线性分类。
76 | - 未对数据进行任何假设,因此对异常点不敏感。
77 | - 通过近邻而不是通过类域判别,对类域交叉重叠“较多的样本具有较好的预测效果。
78 |
79 | **缺点**
80 | - 在特征较多的情况下,会有很大的计算量。
81 | - 需要存储所有的训练数据,对内存要求高。
82 | - 因为是懒惰学习(在测试样本阶段学习),预测阶段速度比较慢。
83 | - 在样本不平衡时,容易造成误判。
84 | - 对数据规模敏感。在大的训练集中有较高正确率,当规模小的时候正确率低。
85 |
86 | ### 3.算法实践
87 |
88 | - sklearn:[knn.ipynb](./knn.ipynb)
89 | - numpy:[knn.py](./knn.py)
90 |
91 | ### 4.常见面试题
92 |
93 | #### 4.1 为了解决KNN算法计算量过大的问题,可以使用分组的方式进行计算,简述一下该方式的原理。
94 |
95 | 先将样本按距离分解成组,获得质心,然后计算未知样本到各质心的距离,选出距离最近的一组或几组,再在这些组内引用KNN。
96 | 本质上就是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本,该方法比较适用于样本容量比较大时的情况。
97 |
98 | #### 4.2 K-Means与KNN有什么区别
99 | - KNN
100 | + KNN是分类算法
101 | + 监督学习
102 | + 喂给它的数据集是带label的数据,已经是完全正确的数据
103 | + 没有明显的前期训练过程,属于memory-based learning
104 | + K的含义:来了一个样本x,要给它分类,即求出它的y,就从数据集中,在x附近找离它最近的K个数据点,这K个数据点,类别c占的个数最多,就把x的label设为c
105 |
106 | - K-Means
107 | + 1.K-Means是聚类算法
108 | + 2.非监督学习
109 | + 3.喂给它的数据集是无label的数据,是杂乱无章的,经过聚类后才变得有点顺序,先无序,后有序
110 | + 有明显的前期训练过程
111 | + K的含义:K是人工固定好的数字,假设数据集合可以分为K个簇,由于是依靠人工定好,需要一点先验知识
112 |
113 | - 相似点
114 | - 都包含这样的过程,给定一个点,在数据集中找离它最近的点。即二者都用到了NN(Nears Neighbor)算法,一般用KD树来实现NN。
115 |
116 |
117 | #### 4.3 讲解一下用于计算邻居的算法
118 |
119 | - KD 树
120 | - 参考:https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KDTree.html
121 | - 球树
122 | - 参考:https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.BallTree.html
123 |
124 | **参考文献**
125 | - 西瓜书
126 | - 统计学习方法
127 | - 维基百科
128 | - https://www.cnblogs.com/listenfwind/p/10311496.html
129 | - https://blog.csdn.net/weixin_43179522/article/details/105665528
130 | - https://jiang-hs.github.io/post/dIjHdNcg_/
131 | - https://codeshellme.github.io/2020/11/ml-knn2/
132 | - https://github.com/datawhalechina/daily-interview/blob/8b29d467997c9ccad1d4796bace87444b4c8c751/AI%E7%AE%97%E6%B3%95/machine-learning/kNN.md
133 | - https://github.com/fengdu78/lihang-code/blob/master/%E7%AC%AC03%E7%AB%A0%20k%E8%BF%91%E9%82%BB%E6%B3%95/3.KNearestNeighbors.ipynb
--------------------------------------------------------------------------------
/ml-with-sklearn/10-kNN/knn.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/10-kNN/knn.pdf
--------------------------------------------------------------------------------
/ml-with-sklearn/10-kNN/knn.py:
--------------------------------------------------------------------------------
1 | #coding=utf-8
2 | #Author:haobo
3 | #Date:2022-4-23
4 |
5 | from sklearn.datasets import load_digits
6 | from sklearn.model_selection import train_test_split
7 | from sklearn.neighbors import KNeighborsClassifier
8 | from sklearn.metrics import accuracy_score
9 |
10 |
11 | #加载数据集
12 | digits = load_digits()
13 | data = digits.data # 特征集
14 | target = digits.target # 目标集
15 |
16 |
17 | #将数据集拆分为训练集(75%)和测试集(25%):
18 | train_x, test_x, train_y, test_y = train_test_split(
19 | data, target, test_size=0.25, random_state=33)
20 |
21 |
22 | #构造KNN分类器:采用默认参数
23 | knn = KNeighborsClassifier()
24 |
25 |
26 | #拟合模型:
27 | knn.fit(train_x, train_y)
28 | #预测数据:
29 | predict_y = knn.predict(test_x)
30 |
31 |
32 | #计算模型准确度
33 | score = accuracy_score(test_y, predict_y)
34 | print(score)
--------------------------------------------------------------------------------
/ml-with-sklearn/10-kNN/res/knn-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/10-kNN/res/knn-1.png
--------------------------------------------------------------------------------
/ml-with-sklearn/10-kNN/res/knn-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/10-kNN/res/knn-2.png
--------------------------------------------------------------------------------
/ml-with-sklearn/10-kNN/res/knn-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/10-kNN/res/knn-3.jpg
--------------------------------------------------------------------------------
/ml-with-sklearn/11-PCA/PCA.md:
--------------------------------------------------------------------------------
1 | ### 1.降维的基本介绍
2 |
3 | 机器学习领域中所谓的降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中。降维的本质是学习一个映射函数 f : x->y,其中x是原始数据点的表达,目前最多使用向量表达形式。 y是数据点映射后的低维向量表达,通常y的维度小于x的维度(当然提高维度也是可以的)。f可能是显式的或隐式的、线性的或非线性的。
4 |
5 |
6 | 关于维度灾难的一个理解角度:
7 |
8 | 假设存在下面这样一个球,D维,其半径为r=1,里面圆环的长度为$\varepsilon$
9 |
10 | 
11 |
12 | 则我们可以计算得知
13 |
14 | $$
15 | \begin{aligned}
16 | &V_{\text {外 }}=K \cdot 1^{D}=K\\
17 | &V_{\text {环 }}=V_{\text {外 }}-V_{\text {内 }}\\
18 | &=k-k \cdot(1-\varepsilon)^{D}\\
19 | &\frac{V_{环}}{V_{外}}=\frac{k-k(1-\varepsilon)^{D}}{k}={1-(1-\varepsilon)^{D}}
20 | \end{aligned}
21 | $$
22 |
23 | $K$为一个常数,由于0<$\varepsilon$<1,因此$\lim _{D^{\rightarrow \infty}}(1-\varepsilon)^{D}=0$,则$\lim _{D \rightarrow \infty} \frac{V_{环}}{V_{外}}=1$。这就是所谓的维度灾难,在高维数据中,主要样本都分布在立方体的边缘,所以数据集更加稀疏。
24 |
25 |
26 | 那从另外一个角度来看:为什么dimension reduction可能是有用的,如上图所示,假设你的data分布是这样的(在3D里面像螺旋的样子),但是用3D空间来描述这些data其实是很浪费的,其实你从资源就可以说:你把这个类似地毯卷起来的东西把它摊开就变成这样(右边的图)。所以你只需要在2D的空间就可以描述这个3D的information,你根本不需要把这个问题放到这个3D来解,这是把问题复杂化,其实你可以在2D就可以做这个task
27 |
28 | 
29 |
30 |
31 | #### 1.1常见降维算法比较
32 |
33 | **降维的算法分为:**
34 |
35 | 1. 直接降维,特征选择
36 | 2. 线性降维,PCA,MDS等
37 | 3. 分线性,流形包括 Isomap,LLE 等
38 |
39 |
40 | 
41 |
42 |
43 |
44 | #### 1.2sklearn中的降维算法
45 |
46 | 
47 |
48 |
49 | **本章节主要介绍一下PCA**
50 |
51 | ### 2. 主成分分析PCA
52 |
53 | 视频讲解参考:
54 | - [李宏毅老师视频](https://www.bilibili.com/video/BV1Ht411g7Ef?p=24):https://www.bilibili.com/video/BV1Ht411g7Ef?p=24
55 | - [白板机器学习](https://www.bilibili.com/video/BV1aE411o7qd?p=22):https://www.bilibili.com/video/BV1aE411o7qd?p=22
56 |
57 |
58 | #### 2.1损失函数
59 |
60 | 我们假设数据集为
61 | $$
62 | X_{N\times p}=(x_{1},x_{2},\cdots,x_{N})^{T},x_{i}=(x_{i1},x_{i2},\cdots,x_{ip})^{T}
63 | $$
64 | 这个记号表示有 $N$ 个样本,每个样本都是 $p$ 维向量。其中每个观测都是由 $p(x|\theta)$ 生成的。
65 |
66 | 为了方便,我们首先将协方差矩阵(数据集)写成中心化的形式:
67 | $$
68 | \begin{aligned}
69 | S &=\frac{1}{N} \sum_{i=1}^{N}\left(x_{i}-\bar{x}\right)\left(x_{i}-\bar{x}\right)^{T} \\
70 | &=\frac{1}{N}\left(x_{1}-\bar{x}, x_{2}-\bar{x}, \cdots, x_{N}-\bar{x}\right)\left(x_{1}-\bar{x}, x_{2}-\bar{x}, \cdots, x_{N}-\bar{x}\right)^{T} \\
71 | &=\frac{1}{N}\left(X^{T}-\frac{1}{N} X^{T} \mathbb{I}_{N 1} \mathbb{I}_{N 1}^{T}\right)\left(X^{T}-\frac{1}{N} X^{T} \mathbb{I}_{N 1} \mathbb{I}_{N 1}^{T}\right)^{T} \\
72 | &=\frac{1}{N} X^{T}\left(E_{N}-\frac{1}{N} \mathbb{I}_{N 1} \mathbb{I}_{1 N}\right)\left(E_{N}-\frac{1}{N} \mathbb{I}_{N 1} \mathbb{I}_{1 N}\right)^{T} X \\
73 | &=\frac{1}{N} X^{T} H_{N} H_{N}^{T} X \\
74 | &=\frac{1}{N} X^{T} H_{N} H_{N} X=\frac{1}{N} X^{T} H X
75 | \end{aligned}
76 | $$
77 | 这个式子利用了中心矩阵 $ H$的对称性,这也是一个投影矩阵。
78 |
79 |
80 | 主成分分析中,我们的基本想法是将所有数据投影到一个字空间中,从而达到降维的目标,为了寻找这个子空间,我们基本想法是:
81 |
82 | 1. 所有数据在子空间中更为分散
83 | 2. 损失的信息最小,即:在补空间的分量少
84 |
85 | 原来的数据很有可能各个维度之间是相关的,于是我们希望找到一组 $p$ 个新的线性无关的单位基 $u_i$,降维就是取其中的 $q$ 个基。于是对于一个样本 $x_i$,经过这个坐标变换后:
86 | $$
87 | \hat{x_i}=\sum\limits_{i=1}^p(u_i^Tx_i)u_i=\sum\limits_{i=1}^q(u_i^Tx_i)u_i+\sum\limits_{i=q+1}^p(u_i^Tx_i)u_i
88 | $$
89 | 对于数据集来说,我们首先将其中心化然后再去上面的式子的第一项,并使用其系数的平方平均作为损失函数并最大化:
90 | $$
91 | \begin{aligned}
92 | J &=\frac{1}{N} \sum_{i=1}^{N} \sum_{j=1}^{q}\left(\left(x_{i}-\bar{x}\right)^{T} u_{j}\right)^{2} \\
93 | &=\sum_{j=1}^{q} u_{j}^{T} S u_{j}, \text { s.t. } u_{j}^{T} u_{j}=1
94 | \end{aligned}
95 | $$
96 | 由于每个基都是线性无关的,于是每一个 $u_j$ 的求解可以分别进行,使用拉格朗日乘子法:
97 | $$
98 | \mathop{argmax}_{u_j}L(u_j,\lambda)=\mathop{argmax}_{u_j}u_j^TSu_j+\lambda(1-u_j^Tu_j)
99 | $$
100 | 于是:
101 | $$
102 | Su_j=\lambda u_j
103 | $$
104 | 可见,我们需要的基就是协方差矩阵的本征矢。损失函数最大取在本征值前 $q$ 个最大值。
105 |
106 | 下面看其损失的信息最少这个条件,同样适用系数的平方平均作为损失函数,并最小化:
107 | $$
108 | \begin{aligned}
109 | J &=\frac{1}{N} \sum_{i=1}^{N} \sum_{j=q+1}^{p}\left(\left(x_{i}-\bar{x}\right)^{T} u_{j}\right)^{2} \\
110 | &=\sum_{j=q+1}^{p} u_{j}^{T} S u_{j}, \text { s.t. } u_{j}^{T} u_{j}=1
111 | \end{aligned}
112 | $$
113 | 同样的:
114 | $$
115 | \mathop{argmin}_{u_j}L(u_j,\lambda)=\mathop{argmin}_{u_j}u_j^TSu_j+\lambda(1-u_j^Tu_j)
116 | $$
117 | 损失函数最小取在本征值剩下的个最小的几个值。数据集的协方差矩阵可以写成 $S=U\Lambda U^T$,直接对这个表达式当然可以得到本征矢。
118 |
119 | 
120 |
121 | #### 2.2SVD 与 PCoA
122 |
123 | 下面使用实际训练时常常使用的 SVD 直接求得这个 $q$ 个本征矢。
124 |
125 | 对中心化后的数据集进行奇异值分解:
126 | $$
127 | HX=U\Sigma V^T,U^TU=E_N,V^TV=E_p,\Sigma:N\times p
128 | $$
129 |
130 | 于是:
131 | $$
132 | S=\frac{1}{N}X^THX=\frac{1}{N}X^TH^THX=\frac{1}{N}V\Sigma^T\Sigma V^T
133 | $$
134 | 因此,我们直接对中心化后的数据集进行 SVD,就可以得到特征值和特征向量 $V$,在新坐标系中的坐标就是:
135 | $$
136 | HX\cdot V
137 | $$
138 | 由上面的推导,我们也可以得到另一种方法 PCoA 主坐标分析,定义并进行特征值分解:
139 | $$
140 | T=HXX^TH=U\Sigma\Sigma^TU^T
141 | $$
142 | 由于:
143 | $$
144 | TU\Sigma=U\Sigma(\Sigma^T\Sigma)
145 | $$
146 | 于是可以直接得到坐标。这两种方法都可以得到主成分,但是由于方差矩阵是 $p\times p$ 的,而 $T$ 是 $N\times N$ 的,所以对样本量较少的时候可以采用 PCoA的方法。
147 |
148 | **总结来说就是**
149 |
150 | 输入: 样本集 $D=\left\{\boldsymbol{x}_{1}, \boldsymbol{x}_{2}, \ldots, \boldsymbol{x}_{m}\right\}$;
151 | 低维空间维数 $d^{\prime}$.
152 |
153 | 过程:
154 |
155 | 1. 对所有样本进行中心化: $\boldsymbol{x}_{i} \leftarrow \boldsymbol{x}_{i}-\frac{1}{m} \sum_{i=1}^{m} \boldsymbol{x}_{i}$;
156 | 2. 计算样本的协方差矩阵 $\mathbf{X X} \mathbf{X}^{\mathrm{T}}$;
157 | 3. 对协方差矩阵 XXX
158 | 4. 取最大的 $d^{\prime}$ 个特征值所对应的特征向量 $\boldsymbol{w}_{1}, \boldsymbol{w}_{2}, \ldots, \boldsymbol{w}_{d^{\prime}}$.
159 | 5.
160 | 输出: 投影矩阵 $\mathbf{W}=\left(\boldsymbol{w}_{1}, \boldsymbol{w}_{2}, \ldots, \boldsymbol{w}_{d^{\prime}}\right)$.
161 |
162 |
163 | #### 2.3p-PCA
164 |
165 | 下面从概率的角度对 PCA 进行分析,概率方法也叫 p-PCA。我们使用线性模型,类似之前 LDA,我们选定一个方向,对原数据 $x\in\mathbb{R}^p$ ,降维后的数据为 $z\in\mathbb{R}^q,q
z1
z2
z3
--------------------------------------------------------------------------------
/ml-with-sklearn/12-HMM/res/hmm-2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/12-HMM/res/hmm-2.webp
--------------------------------------------------------------------------------
/ml-with-sklearn/12-HMM/res/hmm-3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/12-HMM/res/hmm-3.webp
--------------------------------------------------------------------------------
/ml-with-sklearn/12-HMM/res/hmm-4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/12-HMM/res/hmm-4.webp
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_11_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_11_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_11_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_11_1.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_13_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_13_1.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_13_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_13_2.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_16_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_16_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_18_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_18_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_18_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_18_1.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_20_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_20_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_20_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_20_1.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_22_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_22_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_24_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_24_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_26_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_26_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_28_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_28_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_30_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_30_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_33_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_33_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_36_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_36_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/asset/output_38_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/asset/output_38_0.png
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/visualization_report.md:
--------------------------------------------------------------------------------
1 | ## 1 简介
2 |
3 | 本次主要通过使用```Scikit-Plot```的模块来介绍机器学习的相关可视化,```Scikit-Plot```主要包括以下几个部分:
4 | * estimators:用于绘制各种算法
5 | * metrics:用于绘制机器学习的onfusion matrix, ROC AUC curves, precision-recall curves等曲线
6 | * cluster:主要用于绘制聚类
7 | * decomposition:主要用于绘制PCA降维
8 |
9 | ```Scikit-Plot```的地址:https://github.com/reiinakano/scikit-plot
10 |
11 | ```Scikit-Plot```的官方文档:https://scikit-plot.readthedocs.io/en/stable/
12 |
13 |
14 | ```python
15 | # 加载需要用到的模块
16 | import scikitplot as skplt
17 |
18 | import sklearn
19 | from sklearn.datasets import load_digits, load_boston, load_breast_cancer
20 | from sklearn.model_selection import train_test_split
21 |
22 | from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor, GradientBoostingClassifier, ExtraTreesClassifier
23 | from sklearn.linear_model import LinearRegression, LogisticRegression
24 | from sklearn.cluster import KMeans
25 | from sklearn.decomposition import PCA
26 |
27 | import matplotlib.pyplot as plt
28 |
29 | import sys
30 |
31 | print("Scikit Plot Version : ", skplt.__version__)
32 | print("Scikit Learn Version : ", sklearn.__version__)
33 | print("Python Version : ", sys.version)
34 | ```
35 |
36 | Scikit Plot Version : 0.3.7
37 | Scikit Learn Version : 0.24.2
38 | Python Version : 3.7.11 (default, Jul 27 2021, 07:03:16)
39 | [Clang 10.0.0 ]
40 |
41 |
42 | ## 2 加载数据集
43 |
44 | ### 2.1 手写数据集
45 |
46 |
47 | ```python
48 | digits = load_digits()
49 | X_digits, Y_digits = digits.data, digits.target
50 |
51 | print("Digits Dataset Size : ", X_digits.shape, Y_digits.shape)
52 |
53 | X_digits_train, X_digits_test, Y_digits_train, Y_digits_test = train_test_split(X_digits, Y_digits,
54 | train_size=0.8,
55 | stratify=Y_digits,
56 | random_state=1)
57 |
58 | print("Digits Train/Test Sizes : ",X_digits_train.shape, X_digits_test.shape, Y_digits_train.shape, Y_digits_test.shape)
59 |
60 |
61 |
62 | ```
63 |
64 | Digits Dataset Size : (1797, 64) (1797,)
65 | Digits Train/Test Sizes : (1437, 64) (360, 64) (1437,) (360,)
66 |
67 |
68 | ### 2.2 肿瘤数据集
69 |
70 |
71 | ```python
72 | cancer = load_breast_cancer()
73 | X_cancer, Y_cancer = cancer.data, cancer.target
74 |
75 | print("Feautre Names : ", cancer.feature_names)
76 | print("Cancer Dataset Size : ", X_cancer.shape, Y_cancer.shape)
77 | X_cancer_train, X_cancer_test, Y_cancer_train, Y_cancer_test = train_test_split(X_cancer, Y_cancer,
78 | train_size=0.8,
79 | stratify=Y_cancer,
80 | random_state=1)
81 |
82 | print("Cancer Train/Test Sizes : ",X_cancer_train.shape, X_cancer_test.shape, Y_cancer_train.shape, Y_cancer_test.shape)
83 | ```
84 |
85 | Feautre Names : ['mean radius' 'mean texture' 'mean perimeter' 'mean area'
86 | 'mean smoothness' 'mean compactness' 'mean concavity'
87 | 'mean concave points' 'mean symmetry' 'mean fractal dimension'
88 | 'radius error' 'texture error' 'perimeter error' 'area error'
89 | 'smoothness error' 'compactness error' 'concavity error'
90 | 'concave points error' 'symmetry error' 'fractal dimension error'
91 | 'worst radius' 'worst texture' 'worst perimeter' 'worst area'
92 | 'worst smoothness' 'worst compactness' 'worst concavity'
93 | 'worst concave points' 'worst symmetry' 'worst fractal dimension']
94 | Cancer Dataset Size : (569, 30) (569,)
95 | Cancer Train/Test Sizes : (455, 30) (114, 30) (455,) (114,)
96 |
97 |
98 | ### 2.3 波斯顿房价数据集
99 |
100 |
101 | ```python
102 | boston = load_boston()
103 | X_boston, Y_boston = boston.data, boston.target
104 |
105 | print("Boston Dataset Size : ", X_boston.shape, Y_boston.shape)
106 |
107 | print("Boston Dataset Features : ", boston.feature_names)
108 | X_boston_train, X_boston_test, Y_boston_train, Y_boston_test = train_test_split(X_boston, Y_boston,
109 | train_size=0.8,
110 | random_state=1)
111 |
112 | print("Boston Train/Test Sizes : ",X_boston_train.shape, X_boston_test.shape, Y_boston_train.shape, Y_boston_test.shape)
113 | ```
114 |
115 | Boston Dataset Size : (506, 13) (506,)
116 | Boston Dataset Features : ['CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO'
117 | 'B' 'LSTAT']
118 | Boston Train/Test Sizes : (404, 13) (102, 13) (404,) (102,)
119 |
120 |
121 | ## 3 性能可视化
122 |
123 | ### 3.1 交叉验证绘制
124 |
125 |
126 | ```python
127 | skplt.estimators.plot_learning_curve(LogisticRegression(), X_digits, Y_digits,
128 | cv=7, shuffle=True, scoring="accuracy",
129 | n_jobs=-1, figsize=(6,4), title_fontsize="large", text_fontsize="large",
130 | title="Digits Classification Learning Curve")
131 | plt.show()
132 |
133 | skplt.estimators.plot_learning_curve(LinearRegression(), X_boston, Y_boston,
134 | cv=7, shuffle=True, scoring="r2", n_jobs=-1,
135 | figsize=(6,4), title_fontsize="large", text_fontsize="large",
136 | title="Boston Regression Learning Curve ");
137 | plt.show()
138 | ```
139 |
140 |
141 | 
142 |
143 |
144 |
145 | 
146 |
147 |
148 | ### 3.2 重要性特征绘制
149 |
150 |
151 | ```python
152 | rf_reg = RandomForestRegressor()
153 | rf_reg.fit(X_boston_train, Y_boston_train)
154 | print(rf_reg.score(X_boston_test, Y_boston_test))
155 | gb_classif = GradientBoostingClassifier()
156 | gb_classif.fit(X_cancer_train, Y_cancer_train)
157 | print(gb_classif.score(X_cancer_test, Y_cancer_test))
158 |
159 | fig = plt.figure(figsize=(15,6))
160 |
161 | ax1 = fig.add_subplot(121)
162 | skplt.estimators.plot_feature_importances(rf_reg, feature_names=boston.feature_names,
163 | title="Random Forest Regressor Feature Importance",
164 | x_tick_rotation=90, order="ascending",
165 | ax=ax1);
166 |
167 | ax2 = fig.add_subplot(122)
168 | skplt.estimators.plot_feature_importances(gb_classif, feature_names=cancer.feature_names,
169 | title="Gradient Boosting Classifier Feature Importance",
170 | x_tick_rotation=90,
171 | ax=ax2);
172 |
173 | plt.tight_layout()
174 | plt.show()
175 | ```
176 |
177 | 0.9096714634570764
178 | 0.9649122807017544
179 |
180 |
181 |
182 | 
183 |
184 |
185 |
186 | 
187 |
188 |
189 | ## 4 机器学习度量(metrics)
190 |
191 | ### 4.1 混淆矩阵(Confusion Matrix)
192 |
193 |
194 | ```python
195 | log_reg = LogisticRegression()
196 | log_reg.fit(X_digits_train, Y_digits_train)
197 | log_reg.score(X_digits_test, Y_digits_test)
198 | Y_test_pred = log_reg.predict(X_digits_test)
199 |
200 | fig = plt.figure(figsize=(15,6))
201 |
202 | ax1 = fig.add_subplot(121)
203 | skplt.metrics.plot_confusion_matrix(Y_digits_test, Y_test_pred,
204 | title="Confusion Matrix",
205 | cmap="Oranges",
206 | ax=ax1)
207 |
208 | ax2 = fig.add_subplot(122)
209 | skplt.metrics.plot_confusion_matrix(Y_digits_test, Y_test_pred,
210 | normalize=True,
211 | title="Confusion Matrix",
212 | cmap="Purples",
213 | ax=ax2);
214 | plt.show()
215 | ```
216 |
217 |
218 | 
219 |
220 |
221 | ### 4.2 ROC、AUC曲线
222 |
223 |
224 | ```python
225 | Y_test_probs = log_reg.predict_proba(X_digits_test)
226 |
227 | skplt.metrics.plot_roc_curve(Y_digits_test, Y_test_probs,
228 | title="Digits ROC Curve", figsize=(12,6))
229 | plt.show()
230 | ```
231 |
232 |
233 | 
234 |
235 |
236 |
237 | 
238 |
239 |
240 | ### 4.3 PR曲线
241 |
242 |
243 | ```python
244 | skplt.metrics.plot_precision_recall_curve(Y_digits_test, Y_test_probs,
245 | title="Digits Precision-Recall Curve", figsize=(12,6))
246 | plt.show()
247 | ```
248 |
249 |
250 | 
251 |
252 |
253 |
254 | 
255 |
256 |
257 | ### 4.4 轮廓分析(Silhouette Analysis)
258 |
259 |
260 | ```python
261 | kmeans = KMeans(n_clusters=10, random_state=1)
262 | kmeans.fit(X_digits_train, Y_digits_train)
263 | cluster_labels = kmeans.predict(X_digits_test)
264 | skplt.metrics.plot_silhouette(X_digits_test, cluster_labels,
265 | figsize=(8,6))
266 | plt.show()
267 | ```
268 |
269 |
270 | 
271 |
272 |
273 | ### 4.5 可靠性曲线(Calibration Curve ,Reliability Curves)
274 |
275 |
276 | ```python
277 | lr_probas = LogisticRegression().fit(X_cancer_train, Y_cancer_train).predict_proba(X_cancer_test)
278 | rf_probas = RandomForestClassifier().fit(X_cancer_train, Y_cancer_train).predict_proba(X_cancer_test)
279 | gb_probas = GradientBoostingClassifier().fit(X_cancer_train, Y_cancer_train).predict_proba(X_cancer_test)
280 | et_scores = ExtraTreesClassifier().fit(X_cancer_train, Y_cancer_train).predict_proba(X_cancer_test)
281 |
282 | probas_list = [lr_probas, rf_probas, gb_probas, et_scores]
283 | clf_names = ['Logistic Regression', 'Random Forest', 'Gradient Boosting', 'Extra Trees Classifier']
284 | skplt.metrics.plot_calibration_curve(Y_cancer_test,
285 | probas_list,
286 | clf_names, n_bins=15,
287 | figsize=(12,6)
288 | )
289 | plt.show()
290 | ```
291 |
292 |
293 | 
294 |
295 |
296 | ### 4.6 KS检验
297 |
298 |
299 | ```python
300 | rf = RandomForestClassifier()
301 | rf.fit(X_cancer_train, Y_cancer_train)
302 | Y_cancer_probas = rf.predict_proba(X_cancer_test)
303 |
304 | skplt.metrics.plot_ks_statistic(Y_cancer_test, Y_cancer_probas, figsize=(10,6))
305 | plt.show()
306 | ```
307 |
308 |
309 | 
310 |
311 |
312 | ### 4.7 累积收益曲线
313 |
314 |
315 | ```python
316 |
317 | skplt.metrics.plot_cumulative_gain(Y_cancer_test, Y_cancer_probas, figsize=(10,6))
318 | plt.show()
319 | ```
320 |
321 |
322 | 
323 |
324 |
325 | ### 4.8 Lift 曲线
326 |
327 |
328 | ```python
329 | skplt.metrics.plot_lift_curve(Y_cancer_test, Y_cancer_probas, figsize=(10,6))
330 | plt.show()
331 | ```
332 |
333 |
334 | 
335 |
336 |
337 | ## 5 聚类方法
338 |
339 | ### 5.1 手肘法(Elbow Method)
340 |
341 |
342 | ```python
343 | skplt.cluster.plot_elbow_curve(KMeans(random_state=1),
344 | X_digits,
345 | cluster_ranges=range(2, 20),
346 | figsize=(8,6))
347 | plt.show()
348 | ```
349 |
350 |
351 | 
352 |
353 |
354 | ## 6 降维方法
355 |
356 | ### 6.1 PCA
357 |
358 |
359 | ```python
360 | pca = PCA(random_state=1)
361 | pca.fit(X_digits)
362 |
363 | skplt.decomposition.plot_pca_component_variance(pca, figsize=(8,6))
364 | plt.show()
365 | ```
366 |
367 |
368 | 
369 |
370 |
371 | ### 6.2 2-D Projection
372 |
373 |
374 | ```python
375 | skplt.decomposition.plot_pca_2d_projection(pca, X_digits, Y_digits,
376 | figsize=(10,10),
377 | cmap="tab10")
378 | plt.show()
379 | ```
380 |
381 |
382 | 
383 |
384 |
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/visualization_report.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/13-Visualization/visualization_report.pdf
--------------------------------------------------------------------------------
/ml-with-sklearn/13-Visualization/visualization_report.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # ## 1 简介
5 | #
6 | # 本次主要通过使用```Scikit-Plot```的模块来介绍机器学习的相关可视化,```Scikit-Plot```主要包括以下几个部分:
7 | # * estimators:用于绘制各种算法
8 | # * metrics:用于绘制机器学习的onfusion matrix, ROC AUC curves, precision-recall curves等曲线
9 | # * cluster:主要用于绘制聚类
10 | # * decomposition:主要用于绘制PCA降维
11 | #
12 | # ```Scikit-Plot```的地址:https://github.com/reiinakano/scikit-plot
13 | #
14 | # ```Scikit-Plot```的官方文档:https://scikit-plot.readthedocs.io/en/stable/
15 |
16 | # In[4]:
17 |
18 |
19 | # 加载需要用到的模块
20 | import scikitplot as skplt
21 |
22 | import sklearn
23 | from sklearn.datasets import load_digits, load_boston, load_breast_cancer
24 | from sklearn.model_selection import train_test_split
25 |
26 | from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor, GradientBoostingClassifier, ExtraTreesClassifier
27 | from sklearn.linear_model import LinearRegression, LogisticRegression
28 | from sklearn.cluster import KMeans
29 | from sklearn.decomposition import PCA
30 |
31 | import matplotlib.pyplot as plt
32 |
33 | import sys
34 |
35 | print("Scikit Plot Version : ", skplt.__version__)
36 | print("Scikit Learn Version : ", sklearn.__version__)
37 | print("Python Version : ", sys.version)
38 |
39 |
40 | # ## 2 加载数据集
41 |
42 | # ### 2.1 手写数据集
43 |
44 | # In[5]:
45 |
46 |
47 | digits = load_digits()
48 | X_digits, Y_digits = digits.data, digits.target
49 |
50 | print("Digits Dataset Size : ", X_digits.shape, Y_digits.shape)
51 |
52 | X_digits_train, X_digits_test, Y_digits_train, Y_digits_test = train_test_split(X_digits, Y_digits,
53 | train_size=0.8,
54 | stratify=Y_digits,
55 | random_state=1)
56 |
57 | print("Digits Train/Test Sizes : ",X_digits_train.shape, X_digits_test.shape, Y_digits_train.shape, Y_digits_test.shape)
58 |
59 |
60 |
61 | # ### 2.2 肿瘤数据集
62 |
63 | # In[6]:
64 |
65 |
66 | cancer = load_breast_cancer()
67 | X_cancer, Y_cancer = cancer.data, cancer.target
68 |
69 | print("Feautre Names : ", cancer.feature_names)
70 | print("Cancer Dataset Size : ", X_cancer.shape, Y_cancer.shape)
71 | X_cancer_train, X_cancer_test, Y_cancer_train, Y_cancer_test = train_test_split(X_cancer, Y_cancer,
72 | train_size=0.8,
73 | stratify=Y_cancer,
74 | random_state=1)
75 |
76 | print("Cancer Train/Test Sizes : ",X_cancer_train.shape, X_cancer_test.shape, Y_cancer_train.shape, Y_cancer_test.shape)
77 |
78 |
79 | # ### 2.3 波斯顿房价数据集
80 |
81 | # In[7]:
82 |
83 |
84 | boston = load_boston()
85 | X_boston, Y_boston = boston.data, boston.target
86 |
87 | print("Boston Dataset Size : ", X_boston.shape, Y_boston.shape)
88 |
89 | print("Boston Dataset Features : ", boston.feature_names)
90 | X_boston_train, X_boston_test, Y_boston_train, Y_boston_test = train_test_split(X_boston, Y_boston,
91 | train_size=0.8,
92 | random_state=1)
93 |
94 | print("Boston Train/Test Sizes : ",X_boston_train.shape, X_boston_test.shape, Y_boston_train.shape, Y_boston_test.shape)
95 |
96 |
97 | # ## 3 性能可视化
98 |
99 | # ### 3.1 交叉验证绘制
100 |
101 | # In[14]:
102 |
103 |
104 | skplt.estimators.plot_learning_curve(LogisticRegression(), X_digits, Y_digits,
105 | cv=7, shuffle=True, scoring="accuracy",
106 | n_jobs=-1, figsize=(6,4), title_fontsize="large", text_fontsize="large",
107 | title="Digits Classification Learning Curve")
108 | plt.show()
109 |
110 | skplt.estimators.plot_learning_curve(LinearRegression(), X_boston, Y_boston,
111 | cv=7, shuffle=True, scoring="r2", n_jobs=-1,
112 | figsize=(6,4), title_fontsize="large", text_fontsize="large",
113 | title="Boston Regression Learning Curve ");
114 | plt.show()
115 |
116 |
117 | # ### 3.2 重要性特征绘制
118 |
119 | # In[18]:
120 |
121 |
122 | rf_reg = RandomForestRegressor()
123 | rf_reg.fit(X_boston_train, Y_boston_train)
124 | print(rf_reg.score(X_boston_test, Y_boston_test))
125 | gb_classif = GradientBoostingClassifier()
126 | gb_classif.fit(X_cancer_train, Y_cancer_train)
127 | print(gb_classif.score(X_cancer_test, Y_cancer_test))
128 |
129 | fig = plt.figure(figsize=(15,6))
130 |
131 | ax1 = fig.add_subplot(121)
132 | skplt.estimators.plot_feature_importances(rf_reg, feature_names=boston.feature_names,
133 | title="Random Forest Regressor Feature Importance",
134 | x_tick_rotation=90, order="ascending",
135 | ax=ax1);
136 |
137 | ax2 = fig.add_subplot(122)
138 | skplt.estimators.plot_feature_importances(gb_classif, feature_names=cancer.feature_names,
139 | title="Gradient Boosting Classifier Feature Importance",
140 | x_tick_rotation=90,
141 | ax=ax2);
142 |
143 | plt.tight_layout()
144 | plt.show()
145 |
146 |
147 | # ## 4 机器学习度量(metrics)
148 |
149 | # ### 4.1 混淆矩阵(Confusion Matrix)
150 |
151 | # In[19]:
152 |
153 |
154 | log_reg = LogisticRegression()
155 | log_reg.fit(X_digits_train, Y_digits_train)
156 | log_reg.score(X_digits_test, Y_digits_test)
157 | Y_test_pred = log_reg.predict(X_digits_test)
158 |
159 | fig = plt.figure(figsize=(15,6))
160 |
161 | ax1 = fig.add_subplot(121)
162 | skplt.metrics.plot_confusion_matrix(Y_digits_test, Y_test_pred,
163 | title="Confusion Matrix",
164 | cmap="Oranges",
165 | ax=ax1)
166 |
167 | ax2 = fig.add_subplot(122)
168 | skplt.metrics.plot_confusion_matrix(Y_digits_test, Y_test_pred,
169 | normalize=True,
170 | title="Confusion Matrix",
171 | cmap="Purples",
172 | ax=ax2);
173 | plt.show()
174 |
175 |
176 | # ### 4.2 ROC、AUC曲线
177 |
178 | # In[21]:
179 |
180 |
181 | Y_test_probs = log_reg.predict_proba(X_digits_test)
182 |
183 | skplt.metrics.plot_roc_curve(Y_digits_test, Y_test_probs,
184 | title="Digits ROC Curve", figsize=(12,6))
185 | plt.show()
186 |
187 |
188 | # ### 4.3 PR曲线
189 |
190 | # In[23]:
191 |
192 |
193 | skplt.metrics.plot_precision_recall_curve(Y_digits_test, Y_test_probs,
194 | title="Digits Precision-Recall Curve", figsize=(12,6))
195 | plt.show()
196 |
197 |
198 | # ### 4.4 轮廓分析(Silhouette Analysis)
199 |
200 | # In[24]:
201 |
202 |
203 | kmeans = KMeans(n_clusters=10, random_state=1)
204 | kmeans.fit(X_digits_train, Y_digits_train)
205 | cluster_labels = kmeans.predict(X_digits_test)
206 | skplt.metrics.plot_silhouette(X_digits_test, cluster_labels,
207 | figsize=(8,6))
208 | plt.show()
209 |
210 |
211 | # ### 4.5 可靠性曲线(Calibration Curve ,Reliability Curves)
212 |
213 | # In[25]:
214 |
215 |
216 | lr_probas = LogisticRegression().fit(X_cancer_train, Y_cancer_train).predict_proba(X_cancer_test)
217 | rf_probas = RandomForestClassifier().fit(X_cancer_train, Y_cancer_train).predict_proba(X_cancer_test)
218 | gb_probas = GradientBoostingClassifier().fit(X_cancer_train, Y_cancer_train).predict_proba(X_cancer_test)
219 | et_scores = ExtraTreesClassifier().fit(X_cancer_train, Y_cancer_train).predict_proba(X_cancer_test)
220 |
221 | probas_list = [lr_probas, rf_probas, gb_probas, et_scores]
222 | clf_names = ['Logistic Regression', 'Random Forest', 'Gradient Boosting', 'Extra Trees Classifier']
223 | skplt.metrics.plot_calibration_curve(Y_cancer_test,
224 | probas_list,
225 | clf_names, n_bins=15,
226 | figsize=(12,6)
227 | )
228 | plt.show()
229 |
230 |
231 | # ### 4.6 KS检验
232 |
233 | # In[26]:
234 |
235 |
236 | rf = RandomForestClassifier()
237 | rf.fit(X_cancer_train, Y_cancer_train)
238 | Y_cancer_probas = rf.predict_proba(X_cancer_test)
239 |
240 | skplt.metrics.plot_ks_statistic(Y_cancer_test, Y_cancer_probas, figsize=(10,6))
241 | plt.show()
242 |
243 |
244 | # ### 4.7 累积收益曲线
245 |
246 | # In[27]:
247 |
248 |
249 |
250 | skplt.metrics.plot_cumulative_gain(Y_cancer_test, Y_cancer_probas, figsize=(10,6))
251 | plt.show()
252 |
253 |
254 | # ### 4.8 Lift 曲线
255 |
256 | # In[28]:
257 |
258 |
259 | skplt.metrics.plot_lift_curve(Y_cancer_test, Y_cancer_probas, figsize=(10,6))
260 | plt.show()
261 |
262 |
263 | # ## 5 聚类方法
264 |
265 | # ### 5.1 手肘法(Elbow Method)
266 |
267 | # In[29]:
268 |
269 |
270 | skplt.cluster.plot_elbow_curve(KMeans(random_state=1),
271 | X_digits,
272 | cluster_ranges=range(2, 20),
273 | figsize=(8,6))
274 | plt.show()
275 |
276 |
277 | # ## 6 降维方法
278 |
279 | # ### 6.1 PCA
280 |
281 | # In[30]:
282 |
283 |
284 | pca = PCA(random_state=1)
285 | pca.fit(X_digits)
286 |
287 | skplt.decomposition.plot_pca_component_variance(pca, figsize=(8,6))
288 | plt.show()
289 |
290 |
291 | # ### 6.2 2-D Projection
292 |
293 | # In[35]:
294 |
295 |
296 | skplt.decomposition.plot_pca_2d_projection(pca, X_digits, Y_digits,
297 | figsize=(10,10),
298 | cmap="tab10")
299 | plt.show()
300 |
301 |
--------------------------------------------------------------------------------
/ml-with-sklearn/组队学习/sklearn机器学习介绍.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/ml-with-sklearn/组队学习/sklearn机器学习介绍.pptx
--------------------------------------------------------------------------------
/src/1f9174e32387cd4dbc0212efbde06eada8173c937666927d4287155d8cc6f988.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/src/1f9174e32387cd4dbc0212efbde06eada8173c937666927d4287155d8cc6f988.jpg
--------------------------------------------------------------------------------
/src/80b58c8d6044a0f0a6c38b32de319994a570a5f40400a2bc30046f7fcb339fcb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/src/80b58c8d6044a0f0a6c38b32de319994a570a5f40400a2bc30046f7fcb339fcb.jpg
--------------------------------------------------------------------------------
/src/82a1f7c37889cc9d03a7ca97b56db6c796fed916d2e2576577d97586c52c80ed.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/src/82a1f7c37889cc9d03a7ca97b56db6c796fed916d2e2576577d97586c52c80ed.jpg
--------------------------------------------------------------------------------
/src/88dcdba0d98766b40896dfbf1809ed4456b85dc1e17a6e5b9ac952830760ab1d.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/src/88dcdba0d98766b40896dfbf1809ed4456b85dc1e17a6e5b9ac952830760ab1d.jpg
--------------------------------------------------------------------------------
/src/b167b1042d0a59ae8a0c68c6fb9915e49f9e16f30e645adef405cca797607778.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/src/b167b1042d0a59ae8a0c68c6fb9915e49f9e16f30e645adef405cca797607778.jpg
--------------------------------------------------------------------------------
/src/cd28bdb3dab6a33f137ceb4fde2527b14e4e6a41f8ef0bc8a6957dcd2324c840.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/src/cd28bdb3dab6a33f137ceb4fde2527b14e4e6a41f8ef0bc8a6957dcd2324c840.jpg
--------------------------------------------------------------------------------
/src/de17622c-0887-46d8-a32a-ee8da80a7c54.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/src/de17622c-0887-46d8-a32a-ee8da80a7c54.png
--------------------------------------------------------------------------------
/西瓜书代码实战.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/machine-learning-toy-code/9e240b434aa7cf38737c2590527b4d860b2f067c/西瓜书代码实战.pdf
--------------------------------------------------------------------------------