更新了机器学习部分文档

This commit is contained in:
jackfrued 2025-02-13 14:12:11 +08:00
parent b4d49f38b9
commit 36d4f27f3c
3 changed files with 30 additions and 30 deletions

View File

@ -245,7 +245,7 @@ stats.pearsonr(X, Y)
PearsonRResult(statistic=0.9486293572644154, pvalue=1.2349851929268588e-25)
```
上面,我们已经确认了月收入和月网购支出之间存在强相关性,那么一个很自然的想法就是通过某人的月收入来预测他的月网购支出,反过来当然也是可以的。为了做到这一点,可以充分利用我们收集到的历史数据,让计算机通过对数据的“学习”获得相应的知识,从而实现对未知状况的预测。我们可以将上述数据中的$\small{X}$称为自变量或特征(*feature*),将$\small{Y}$称为因变量或目标值(*target***机器学习的关键就是要通过历史数据掌握如何实现从特征到目标值的映射**。
上面,我们已经确认了月收入和月网购支出之间存在强相关性,那么一个很自然的想法就是通过某人的月收入来预测他的月网购支出,反过来当然也是可以的。为了做到这一点,可以充分利用我们收集到的历史数据,让计算机通过对数据的“学习”获得相应的知识,从而实现对未知状况的预测。我们可以将上述数据中的 $\small{X}$ 称为自变量或特征(*feature*),将 $\small{Y}$ 称为因变量或目标值(*target***机器学习的关键就是要通过历史数据掌握如何实现从特征到目标值的映射**。
#### kNN算法
@ -298,11 +298,11 @@ for income in incomes:
#### 回归模型
我们换一种思路来预测网购支出,我们将月收入和月网购支出分别作为横纵坐标来绘制散点图。既然网购支出跟月收入之间存在强正相关,这就意味着可以找一条直线来拟合这些历史数据点,我们把这条直线的方程$\small{Y = aX + b}$称为回归方程或回归模型,如下图所示。
我们换一种思路来预测网购支出,我们将月收入和月网购支出分别作为横纵坐标来绘制散点图。既然网购支出跟月收入之间存在强正相关,这就意味着可以找一条直线来拟合这些历史数据点,我们把这条直线的方程 $\small{Y = aX + b}$ 称为回归方程或回归模型,如下图所示。
<img src="res/01_regression_model.png" style="zoom:50%;">
现在,我们的问题就变成了如何利用收集到的历史数据计算出回归模型的斜率$\small{a}$和截距$\small{b}$。为了评价回归模型的好坏,也就是我们计算出的斜率和截距是否理想,我们可以先定义评判标准,一个简单且直观的评判标准就是我们将月收入$\small{X}$带入回归模型,计算出月网购支出的预测值$\small{\hat{Y}}$,预测值$\small{\hat{Y}}$和真实值$\small{Y}$之间的误差越小说明我们的回归模型越理想。之前我们提到过计算误差的地方通常都需要取绝对值或者求平方我们可以用误差平方的均值来作为评判标准通常称之为均方误差MSE如下所示。
现在,我们的问题就变成了如何利用收集到的历史数据计算出回归模型的斜率 $\small{a}$ 和截距 $\small{b}$ 。为了评价回归模型的好坏,也就是我们计算出的斜率和截距是否理想,我们可以先定义评判标准,一个简单且直观的评判标准就是我们将月收入 $\small{X}$ 带入回归模型,计算出月网购支出的预测值 $\small{\hat{Y}}$ ,预测值 $\small{\hat{Y}}$ 和真实值 $\small{Y}$ 之间的误差越小说明我们的回归模型越理想。之前我们提到过计算误差的地方通常都需要取绝对值或者求平方我们可以用误差平方的均值来作为评判标准通常称之为均方误差MSE如下所示。
$$
MSE = \frac{1}{n}{\sum_{i=1}^{n}(y_{i} - \hat{y}_{i})^{2}}
$$
@ -324,7 +324,7 @@ def get_loss(X, Y, a, b):
return statistics.mean([(y - y_hat) ** 2 for y, y_hat in zip(Y, Y_hat)])
```
能让 MSE 达到最小的$\small{a}$和$\small{b}$,我们称之为回归方程的最小二乘解,接下来的工作就是要找到这个最小二乘解。简单的说,我们要将可能的$\small{a}$和$\small{b}$带入损失函数,看看什么样的$\small{a}$和$\small{b}$能让损失函数取到最小值。如果对$\small{a}$和$\small{b}$的取值一无所知,我们可以通过不断产生随机数的方式来寻找$\small{a}$和$\small{b}$,这种方法称为蒙特卡洛模拟,通俗点说就是随机瞎蒙,代码如下所示。
能让 MSE 达到最小的 $\small{a}$ $\small{b}$ ,我们称之为回归方程的最小二乘解,接下来的工作就是要找到这个最小二乘解。简单的说,我们要将可能的 $\small{a}$ $\small{b}$ 带入损失函数,看看什么样的 $\small{a}$ $\small{b}$ 能让损失函数取到最小值。如果对 $\small{a}$ $\small{b}$ 的取值一无所知,我们可以通过不断产生随机数的方式来寻找 $\small{a}$ $\small{b}$ ,这种方法称为蒙特卡洛模拟,通俗点说就是随机瞎蒙,代码如下所示。
```python
import random
@ -347,18 +347,18 @@ print(f'MSE = {min_loss}')
print(f'{a = }, {b = }')
```
上面的代码进行了`100000`次的模拟,$\small{a}$和$\small{b}$的值在$\small{[-2000, 2000)}$范围随机选择的,下面是在我的电脑上跑出来的结果。大家可以把自己蒙特卡罗模拟的结果分享到评论区,看看谁的运气更好,找到了让误差更小的$\small{a}$和$\small{b}$。
上面的代码进行了`100000`次的模拟, $\small{a}$ $\small{b}$ 的值在 $\small{[-2000, 2000)}$ 范围随机选择的,下面是在我的电脑上跑出来的结果。大家可以把自己蒙特卡罗模拟的结果分享到评论区,看看谁的运气更好,找到了让误差更小的 $\small{a}$ $\small{b}$
```
MSE = 270690.1419424315
a = 0.4824040159203802, b = -1515.0162977046068
```
对于数学知识比较丰富的小伙伴,我们可以将回归模型带入损失函数,由于$\small{X}$和$\small{Y}$是已知的历史数据,那么损失函数其实是一个关于$\small{a}$和$\small{b}$的二元函数,如下所示。
对于数学知识比较丰富的小伙伴,我们可以将回归模型带入损失函数,由于 $\small{X}$ $\small{Y}$ 是已知的历史数据,那么损失函数其实是一个关于 $\small{a}$ $\small{b}$ 的二元函数,如下所示。
$$
MSE = f(a, b) = \frac{1}{n}{\sum_{i=1}^{n}(y_{i} - (ax_{i} + b))^{2}}
$$
根据微积分的极值定理,我们可以对$\small{f(a, b)}$求偏导数并令其等于0这样我们就可以计算让$\small{f(a, b)}$取到最小值的$\small{a}$和$\small{b}$分别是多少,即:
根据微积分的极值定理,我们可以对 $\small{f(a, b)}$ 求偏导数并令其等于0这样我们就可以计算让 $\small{f(a, b)}$ 取到最小值的 $\small{a}$ $\small{b}$ 分别是多少,即:
$$
\frac{\partial{f(a, b)}}{\partial{a}} = -\frac{2}{n}\sum_{i=1}^{n}x_{i}(y_{i} - x_{i}a - b) = 0
$$
@ -376,7 +376,7 @@ $$
b = \bar{y} - a\bar{x}
$$
需要说明的是,如果回归模型本身比较复杂,不像线性模型$\small{Y = aX + b}$这么简单,可能没有办法像上面那样直接求解方程,而是要通过其他的方式来找寻极值点,这个我们会在后续的内容中会为大家讲解。回到刚才的问题,我们可以通过上面的公式计算出$\small{a}$和$\small{b}$的值,为了运算方便,下面直接使用了 NumPy 中的函数,因为 NumPy 中的运算都是矢量化的,通常不需要我们自己写循环结构,对 NumPy 不熟悉的小伙伴,可以移步到我的[《基于Python的数据分析》](https://www.zhihu.com/column/c_1217746527315496960)专栏。
需要说明的是,如果回归模型本身比较复杂,不像线性模型 $\small{Y = aX + b}$ 这么简单,可能没有办法像上面那样直接求解方程,而是要通过其他的方式来找寻极值点,这个我们会在后续的内容中会为大家讲解。回到刚才的问题,我们可以通过上面的公式计算出 $\small{a}$ $\small{b}$ 的值,为了运算方便,下面直接使用了 NumPy 中的函数,因为 NumPy 中的运算都是矢量化的,通常不需要我们自己写循环结构,对 NumPy 不熟悉的小伙伴,可以移步到我的[《基于Python的数据分析》](https://www.zhihu.com/column/c_1217746527315496960)专栏。
```python
import numpy as np

View File

@ -1,24 +1,24 @@
## k最近邻算法
k 最近邻算法kNN是一种用于分类和回归的非参数统计方法由美国统计学家伊芙琳·费克斯和小约瑟夫·霍奇斯于 1951 年提出。kNN 算法的原理是从历史数据中找到$\small{k}$个跟新输入的实例最邻近的实例根据它们中的多数所属的类别来对新实例进行分类或者输出新实例的目标值这种算法我们在前面已经为大家做了简单的展示。与主流的机器学习算法不同k 最近邻算法没有显式的学习训练过程它用的是“近朱者赤近墨者黑”这样一种简单朴素的思想来实现分类或回归。k 最近邻算法有两个关键问题,第一个是$\small{k}$值如何选择,即用多少个最近邻来判定新实例所属的类别或确定其目标值;第二个是如何判定两个实例是近还是远,这里就涉及到度量距离的问题。
k 最近邻算法kNN是一种用于分类和回归的非参数统计方法由美国统计学家伊芙琳·费克斯和小约瑟夫·霍奇斯于 1951 年提出。kNN 算法的原理是从历史数据中找到 $\small{k}$ 个跟新输入的实例最邻近的实例根据它们中的多数所属的类别来对新实例进行分类或者输出新实例的目标值这种算法我们在前面已经为大家做了简单的展示。与主流的机器学习算法不同k 最近邻算法没有显式的学习训练过程它用的是“近朱者赤近墨者黑”这样一种简单朴素的思想来实现分类或回归。k 最近邻算法有两个关键问题,第一个是 $\small{k}$ 值如何选择,即用多少个最近邻来判定新实例所属的类别或确定其目标值;第二个是如何判定两个实例是近还是远,这里就涉及到度量距离的问题。
### 距离的度量
我们可以用距离distance来衡量特征空间中两个实例之间的相似度常用的距离度量包括闵氏距离、马氏距离、余弦距离、编辑距离等。闵氏距离全称闵可夫斯基距离Minkowski Distance对于两个$\small{n}$维向量$\small{\bold{x}=(x_{1}, x_{2}, \cdots, x_{n})}$和$\small{\bold{y}=(y_{1}, y_{2}, \cdots, y_{n})}$,它们之间的距离可以定义为:
我们可以用距离distance来衡量特征空间中两个实例之间的相似度常用的距离度量包括闵氏距离、马氏距离、余弦距离、编辑距离等。闵氏距离全称闵可夫斯基距离Minkowski Distance对于两个 $\small{n}$ 维向量 $\small{\bold{x}=(x_{1}, x_{2}, \cdots, x_{n})}$ $\small{\bold{y}=(y_{1}, y_{2}, \cdots, y_{n})}$ ,它们之间的距离可以定义为:
$$
d(\bold{x}, \bold{y}) = (\sum_{i=1}^{n}{|x_{i} - y_{i}|}^{p})^{\frac{1}{p}}
$$
其中,$\small{p \ge 1}$,虽然$\small{p \lt 1}$可以计算,但不再严格满足距离的定义,通常不被视为真正的距离。
其中, $\small{p \ge 1}$ ,虽然 $\small{p \lt 1}$ 可以计算,但不再严格满足距离的定义,通常不被视为真正的距离。
当$\small{p = 1}$时,闵氏距离退化为**曼哈顿距离**,即:
$\small{p = 1}$ 时,闵氏距离退化为**曼哈顿距离**,即:
$$
d(\bold{x}, \bold{y}) = \sum_{i=1}^{n}|x_{i} - y_{i}|
$$
当$\small{p = 2}$时,闵氏距离退化为**欧几里得距离**,即:
$\small{p = 2}$ 时,闵氏距离退化为**欧几里得距离**,即:
$$
d(\bold{x}, \bold{y}) = \sqrt{\sum_{i=1}^{n}(x_{i} - y_{i})^{2}}
$$
当$\small{p \to \infty}$时,闵氏距离成为**切比雪夫距离**,即:
$\small{p \to \infty}$ 时,闵氏距离成为**切比雪夫距离**,即:
$$
d(\bold{x}, \bold{y}) = \underset{i}{max}(|x_{i} - y_{i}|)
$$
@ -172,7 +172,7 @@ array([ True, True, True, True, True, True, True, True, True,
True, True, True])
```
输出的结果中有一个`False`,这表示预测的标签跟真实的标签并不相同,是一个错误的预测结果,也就是说我们预测的准确率为$\small{\frac{29}{30} = 96.67 \%}$。当然,如果你划分训练集和测试集时跟我指定的`random_state`参数不相同,这里得到的结果可能会跟我不同。
输出的结果中有一个`False`,这表示预测的标签跟真实的标签并不相同,是一个错误的预测结果,也就是说我们预测的准确率为 $\small{\frac{29}{30} = 96.67 \%}$ 。当然,如果你划分训练集和测试集时跟我指定的`random_state`参数不相同,这里得到的结果可能会跟我不同。
#### 基于scikit-learn的实现
@ -236,25 +236,25 @@ model.score(X_test, y_test)
$$
\text{准确率} = \frac{\text{TP} + \text{TN}}{\text{TP} + \text{FP} + \text{FN} + \text{TN}}
$$
上面的例子,模型预测的准确率为:$\small{\frac{80 + 870}{80 + 30 + 20 + 870} = \frac{950}{1000} = 95\%}$。
上面的例子,模型预测的准确率为: $\small{\frac{80 + 870}{80 + 30 + 20 + 870} = \frac{950}{1000} = 95\%}$
2. **精确率**Precesion。精确率用于衡量在所有被预测为正类的样本中实际上属于正类的比例通常也被称为查准率。
$$
精确率 = \frac{\text{TP}}{\text{TP} + \text{FP}}
$$
上面的例子,模型预测的精确率为:$\small{\frac{80}{80 + 30} = \frac{80}{110} = 72.73\%}$。
上面的例子,模型预测的精确率为: $\small{\frac{80}{80 + 30} = \frac{80}{110} = 72.73\%}$
3. **召回率**Recall。召回率用于衡量在所有实际为正类的样本中被模型正确预测为正类的比例通常也被称为查全率或真正例率True Positive Rate
$$
召回率 = \frac{\text{TP}}{\text{TP} + \text{FN}}
$$
上面的例子,模型预测的召回率为:$\small{\frac{80}{80 + 20} = \frac{80}{100} = 80\%}$。
上面的例子,模型预测的召回率为: $\small{\frac{80}{80 + 20} = \frac{80}{100} = 80\%}$
4. **F1 分数**F1 Score。F1 分数是精确率和召回率的调和平均数,它在精确率和召回率之间寻求一个平衡,尤其适用于在两者之间有权衡的情况。
$$
\text{F1分数} = \frac{2}{\frac{1}{\text{精确率}} + \frac{1}{\text{召回率}}} = 2 \times \frac{\text{精确率} \times \text{召回率}}{\text{精确率} + \text{召回率}}
$$
上面的例子模型预测的F1 分数为:$\small{2 \times \frac{0.7273 * 0.8}{0.7273 + 0.8} = 76.19\%}$。
上面的例子模型预测的F1 分数为: $\small{2 \times \frac{0.7273 * 0.8}{0.7273 + 0.8} = 76.19\%}$
5. **特异度**Specificity和**假正例率**False Positive Rate。特异度用于衡量的是在所有实际为负类的样本中被模型正确预测为负类的比例类似于召回率只不过针对的是负类样本。
$$
@ -264,7 +264,7 @@ model.score(X_test, y_test)
\text{假正例率} = 1 - \text{特异度}
$$
上面的例子,模型预测的特异度为:$\small{\frac{870}{870 + 30} = \frac{870}{900} = 96.67\%}$。
上面的例子,模型预测的特异度为: $\small{\frac{870}{870 + 30} = \frac{870}{900} = 96.67\%}$
6. **ROC****AUC**
@ -272,9 +272,9 @@ model.score(X_test, y_test)
<img src="res/02_ROC_curve.png" style="zoom:38%;">
- **AUC**Area Under the Curve是 ROC 曲线下的面积衡量模型区分正类和负类的能力。AUC 值的范围是$\small[0, 1]$,值越接近 1表示模型区分正负类的能力越强。0.5 < AUC < 1说明我们的模型优于随机猜测只要这个分类器模型妥善设置阈值的话就有预测价值AUC = 0.5说明我们的模型跟随机猜测一样模型没有预测价值。AUC < 0.5模型比随机猜测还差但只要总能反向预测它的实际效果就优于随机猜测
- **AUC**Area Under the Curve是 ROC 曲线下的面积衡量模型区分正类和负类的能力。AUC 值的范围是 $\small[0, 1]$ ,值越接近 1表示模型区分正负类的能力越强。0.5 < AUC < 1说明我们的模型优于随机猜测只要这个分类器模型妥善设置阈值的话就有预测价值AUC = 0.5说明我们的模型跟随机猜测一样模型没有预测价值。AUC < 0.5模型比随机猜测还差但只要总能反向预测它的实际效果就优于随机猜测
对于多分类问题,混淆矩阵的行数和列数都等于类别数,混淆矩阵是一个方阵,也就是说如果有$\small{n}$个类别,那么混淆矩阵就是一个$\small{n \times n}$的方阵。根据上面我们得到的鸢尾花数据集的预测结果,我们先输出真实值和预测值,然后制作对应的混淆矩阵,如下所示。
对于多分类问题,混淆矩阵的行数和列数都等于类别数,混淆矩阵是一个方阵,也就是说如果有 $\small{n}$ 个类别,那么混淆矩阵就是一个 $\small{n \times n}$ 的方阵。根据上面我们得到的鸢尾花数据集的预测结果,我们先输出真实值和预测值,然后制作对应的混淆矩阵,如下所示。
```python
print(y_test)

View File

@ -20,15 +20,15 @@
$$
H(D) = -\sum_{i = 1}^{k} P(x_i)log_2P(x_i)
$$
其中,$\small{D}$代表数据集,$\small{k}$代表类别的总数,$\small{P(x_i)}$表示数据集中第$\small{i}$类样本的比例(概率)。我们用$\small{x_1}$和$\small{x_2}$来分别表示甲获胜和乙获胜,很显然,当$\small{P(x_1)=0.5}$$\small{P(x_2)=0.5}$时,$\small{H=1}$,不确定性最大;当$\small{P(x_1)=1}$$\small{P(x_2)=0}$时,$\small{H=0}$,不确定性最小;当$\small{P(x_1)=0.8}$$\small{P(x_2)=0.2}$时,$\small{H \approx 0.72}$。
其中, $\small{D}$ 代表数据集, $\small{k}$ 代表类别的总数, $\small{P(x_i)}$ 表示数据集中第 $\small{i}$ 类样本的比例(概率)。我们用 $\small{x_1}$ $\small{x_2}$ 来分别表示甲获胜和乙获胜,很显然,当 $\small{P(x_1)=0.5}$ $\small{P(x_2)=0.5}$ 时, $\small{H=1}$ ,不确定性最大;当 $\small{P(x_1)=1}$ $\small{P(x_2)=0}$ 时, $\small{H=0}$ ,不确定性最小;当 $\small{P(x_1)=0.8}$ $\small{P(x_2)=0.2}$ 时, $\small{H \approx 0.72}$
很显然,知道的信息越多,随机变量(数据集)的不确定性就越小。这些信息,可以是直接针对我们想了解的随机事件的信息,也可以是和我们关心的随机事件相关的其他事件的信息。在数学上可以严格的证明这些相关的信息也能够降低或消除不确定性,为此我们定义**条件熵**,它表示在给定特征$\small{A}$的条件下,数据集$\small{D}$的不确定性。条件熵的公式如下所示:
很显然,知道的信息越多,随机变量(数据集)的不确定性就越小。这些信息,可以是直接针对我们想了解的随机事件的信息,也可以是和我们关心的随机事件相关的其他事件的信息。在数学上可以严格的证明这些相关的信息也能够降低或消除不确定性,为此我们定义**条件熵**,它表示在给定特征 $\small{A}$ 的条件下,数据集 $\small{D}$ 的不确定性。条件熵的公式如下所示:
$$
H(D|A) = \sum_{v \in A}\frac{|D_{v}|}{|D|}H(D_{v})
$$
上面的公式中,我们让$\small{v}$取得特征$\small{A}$所有可能的取值,其中$\small{D_{v}}$代表特征$\small{A}$取值为$\small{v}$的样本子集,$\small{\frac{|D_{v}|}{|D|}}$代表权重,即特征取值为$\small{v}$的样本比例。可以证明$\small{H(D) \ge H(D|A)}$,也就是说多了特征$\small{A}$的信息之后,数据集$\small{D}$的不确定性下降了。当然,还要注意等号成立的情况,也就是说增加了特征$\small{A}$的信息,但是$\small{D}$的不确定没有下降,也就是说我们获取的信息与要研究的内容没有关系。
上面的公式中,我们让 $\small{v}$ 取得特征 $\small{A}$ 所有可能的取值,其中 $\small{D_{v}}$ 代表特征 $\small{A}$ 取值为 $\small{v}$ 的样本子集, $\small{\frac{|D_{v}|}{|D|}}$ 代表权重,即特征取值为 $\small{v}$ 的样本比例。可以证明 $\small{H(D) \ge H(D|A)}$ ,也就是说多了特征 $\small{A}$ 的信息之后,数据集 $\small{D}$ 的不确定性下降了。当然,还要注意等号成立的情况,也就是说增加了特征 $\small{A}$ 的信息,但是 $\small{D}$ 的不确定没有下降,也就是说我们获取的信息与要研究的内容没有关系。
有了上面的铺垫,接下来我们就可以给出**信息增益**的定义,它是在得到特征$\small{A}$的信息后,数据集$\small{D}$的不确定性减少的程度。换句话说,信息增益是一种描述数据集确定性增加的量,特征的信息增益越大,特征的分类能力就越强,在给定该特征后数据集的确定性就越大。信息增益可以通过下面的数学公式直观的描述:
有了上面的铺垫,接下来我们就可以给出**信息增益**的定义,它是在得到特征 $\small{A}$ 的信息后,数据集 $\small{D}$ 的不确定性减少的程度。换句话说,信息增益是一种描述数据集确定性增加的量,特征的信息增益越大,特征的分类能力就越强,在给定该特征后数据集的确定性就越大。信息增益可以通过下面的数学公式直观的描述:
$$
g(D, A) = E(D) - E(D|A)
$$
@ -96,7 +96,7 @@ g(D,A3) = 1.4420095891994646
$$
R(D, A) = \frac{g(D, A)}{E_{A}(D)}
$$
其中,$\small{E_{A}(D) = -\sum_{i=1}^{n}{\frac{|D_{i}|}{|D|}log_{2}\frac{|D_{i}|}{|D|}}}$$\small{n}$表示特征$\small{A}$的取值个数,简单的说$\small{E_{A}(D)}$就是特征$\small{A}$的信息熵,而信息增益比就是特征$\small{A}$的信息增益和特征$\small{A}$的信息熵的比值。我们用下面的函数来计算信息增益比,调用该函数可以输出四个特征对应的信息增益比。
其中, $\small{E_{A}(D) = -\sum_{i=1}^{n}{\frac{|D_{i}|}{|D|}log_{2}\frac{|D_{i}|}{|D|}}}$ $\small{n}$ 表示特征 $\small{A}$ 的取值个数,简单的说 $\small{E_{A}(D)}$ 就是特征 $\small{A}$ 的信息熵,而信息增益比就是特征 $\small{A}$ 的信息增益和特征 $\small{A}$ 的信息熵的比值。我们用下面的函数来计算信息增益比,调用该函数可以输出四个特征对应的信息增益比。
```python
def info_gain_ratio(x, y):
@ -128,7 +128,7 @@ R(D,A3) = 0.35550822529855447
根据上面的输出我们可以得知,花瓣宽度(对应上面的`A3`这个特征信息增益比最高也就是说这个特征能够完成一次良好的数据划分可以作为我们构建决策树的根结点。当然构建决策树不可能只做一次划分我们可以在划分后的数据集上继续计算信息增益比来选择新的划分特征重复这一过程直到满足一定的条件就可以构造出一棵完整的决策树模型。在经典决策树算法中C4.5 算法就是基于信息增益比进行特征选择的。
除了上面讲到的信息增益和信息增益比,**基尼指数**也是非常好的特征选择方法,它可以用于评价数据集的纯度。基尼指数也叫**基尼不纯度**Gini impurity它的取值在0到1之间数据集纯度越高基尼指数越靠近0数据集纯度越低基尼指数越靠近1。如果数据集有$\small{n}$个类别,样本属于第$\small{k}$个类别的概率为$\small{p_{k}}$,那么数据集的基尼指数可以通过下面的公式进行计算:
除了上面讲到的信息增益和信息增益比,**基尼指数**也是非常好的特征选择方法,它可以用于评价数据集的纯度。基尼指数也叫**基尼不纯度**Gini impurity它的取值在0到1之间数据集纯度越高基尼指数越靠近0数据集纯度越低基尼指数越靠近1。如果数据集有 $\small{n}$ 个类别,样本属于第 $\small{k}$ 个类别的概率为 $\small{p_{k}}$ ,那么数据集的基尼指数可以通过下面的公式进行计算:
$$
G(D) = 1 - \sum_{k=1}^{n}{p_{k}}^{2}
$$
@ -144,7 +144,7 @@ $$
$$
G(D) = 1 - [(\frac{14}{15})^{2} + (\frac{1}{30})^{2} + (\frac{1}{30})^{2}] = \frac{19}{150}
$$
可以看出,随着数据集纯度越来越高,基尼指数的值越来越小。如果数据集$\small{D}$根据特征$\small{A}$划分为$\small{k}$个部分,那么在给定特征$\small{A}$的前提条件下,数据集的基尼指数可以定义为:
可以看出,随着数据集纯度越来越高,基尼指数的值越来越小。如果数据集 $\small{D}$ 根据特征 $\small{A}$ 划分为 $\small{k}$ 个部分,那么在给定特征 $\small{A}$ 的前提条件下,数据集的基尼指数可以定义为:
$$
G(D, A) = \sum_{i=1}^{k}\frac{|D_{i}|}{|D|}G(D_{i})
$$
@ -203,7 +203,7 @@ G(D,A3) = 0.06249999999999998
> **说明**如果大家有编写树结构的经验上面的过程应该很容易理解。当然对递归recursion、二叉树binary tree、多叉树multi-way tree不熟悉的小伙伴也可以随便找本讲数据结构的书来看看相关的知识并不复杂我们这里就不进行赘述了。
在数据分裂的过程中,还有一个值得关注的问题就是特征连续值和缺失值的处理。对于连续值,可以通过遍历特征所有可能的取值,找到切分点$\small{x}$让切分后的子集在信息增益比或基尼指数方面达到最优,在数据分裂时以$\small{x}$将数据划分为$\small{D_{1}}$和$\small{D_{2}}$两个子集,其中$\small{D_{1}}$包含特征值小于等于$\small{x}$的样本,$\small{D_{2}}$包含特征值大于$\small{x}$的样本。对于缺失值C4.5 算法采用了加权分配的方式进行处理当选择一个特征进行分裂时该特征存在缺失值的样本会被分配到每个子集但是不同的子集中该样本被赋予的权重是不一样的这个权重会根据该特征在各个类别中的比例进行计算。CART 算法在处理缺失值时通常会为每个特征创建一个默认分支。对于存在缺失值的样本CART 算法会将它们引导到默认分支进行处理在计算基尼指数时CART 算法可以选择是否将缺失值的样本纳入计算。
在数据分裂的过程中,还有一个值得关注的问题就是特征连续值和缺失值的处理。对于连续值,可以通过遍历特征所有可能的取值,找到切分点 $\small{x}$ 让切分后的子集在信息增益比或基尼指数方面达到最优,在数据分裂时以 $\small{x}$ 将数据划分为 $\small{D_{1}}$ $\small{D_{2}}$ 两个子集,其中 $\small{D_{1}}$ 包含特征值小于等于 $\small{x}$ 的样本, $\small{D_{2}}$ 包含特征值大于 $\small{x}$ 的样本。对于缺失值C4.5 算法采用了加权分配的方式进行处理当选择一个特征进行分裂时该特征存在缺失值的样本会被分配到每个子集但是不同的子集中该样本被赋予的权重是不一样的这个权重会根据该特征在各个类别中的比例进行计算。CART 算法在处理缺失值时通常会为每个特征创建一个默认分支。对于存在缺失值的样本CART 算法会将它们引导到默认分支进行处理在计算基尼指数时CART 算法可以选择是否将缺失值的样本纳入计算。
#### 树的剪枝