机器学习快速入门
这是机器学习小白在csdn更新的第一篇文,课程学习资料来源于黑马程序员的3天快速入门python机器学习课程。由于本小白在学完特征工程后转去看吴恩达在coursera的机器学习课程 且 markdown编辑是在学吴恩达的机器学习课程时才掌握的技能,因此黑马程序员的前半部分课程暂时没有做笔记。如果你只希望能够应用一些机器学习算法以及处理数据的方法,可以参考我文章中涉及到的完整代码(代码结构基本保持一致),或者时间充足的前提下,最好去黑马程序员的速成课程看一看。老师人美不美不清楚,但声音真的很甜。关弹幕食用更佳。
你必须了解的机器学习最通用流程:
获取数据
划分数据集(可选)
特征工程
标准化
降维(可选)
选择模型并训练
模型评估
1. 特征工程
由于作者太懒,之前已经看过的黑马程序员python机器学习课程(截止到主成分分析之前)不再做笔记,详细内容可参考这篇文章。
1.1 主成分分析(PCA)
主成分分析是高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据,创造新的变量。其作用是压缩数据维数,在损失少量信息的代价下尽可能降低原数据的维数/特征数量/复杂度。常应用于回归分析/聚类分析。
在python中,可以通过sklearn简单地使用PCA。首先调包:
from sklearn.decomposition import PCA
接下来实例化PCA类
transfer_PCA = PCA(n_components = value)
n_components是调用PCA类时的关键参数,value为保留信息的多少。若为小数(如0.95),则保留95%的信息。若为整数(如10),则保留10个特征。最后进行PCA降维:
data_simplified = transfer_PCA.fit_transform(data)
非常easy。
2. 分类算法
2.1 sklearn转换器和估计器
2.1.1 转换器
请回想一下之前进行特征工程时常用步骤,先实例化某个转换器类,再调用.fit_transform方法。 通常而言,我们将特征工程的接口称为转换器。
2.1.2 估计器
在sklearn中,估计器(estimator)是一类实现了算法的API,至关重要。
其中,用于分类的估计器包括:
- sklearn.neighbours:k-临近算法
- sklearn.naive_bayes:贝叶斯
- sklearn.linear_model.LogisticRegression:逻辑回归
- sklearn.tree:决策树与随机森林
用于回归的估计器包括:
- sklearn.linear_model.LinearRegression:线性回归
- sklearn.linear_model.Ridge:岭回归(?这个不是正则化参数可以搞定的吗)
用于无监督学习的估计器包括:
- sklearn.cluster.KMeans:聚类
在使用sklearn选择模型时,通常先实例化一个estimator类,再调用fit方法并传入x_train和y_train:
# 先调包,如:from sklearn.linear_model import LogisticRegression
model_name = estimator_name
# 如:logistic_regression_model = LogisticRegression(penalty='l2')
model_name.fit(x_train, y_train)
# 如:logistic_regression_model.fit(X_train, y_train)
为了检验模型预测效果/输出模型预测结果,可使用predict方法:
y_pred = model_name.predict(x_test)
# 如:y_pred = logistic_regression_model.predict(X_train)
输出结果精度可使用score方法:
print("Accuracy on training set:", model_name.score(x_train, y_train))
2.2 K-近邻算法(KNN:K-NearestNeighbor)
学习目标:
- 说明KNN的距离公式
- 说明KNN的超参数K值以及取值问题
- 说明KNN的优缺点
- 应用KNeighborsClassifier实现分类
- 了解分类算法的评估标准准确率
应用:
- 鸢尾花数据集预测
- Facebook签到位置预测
内容预览:
- 2.2.1 什么是KNN
- 2.2.2 KNN的API
- 2.2.3 案例:鸢尾花种类预测
- 2.2.4 总结
2.2.1 KNN原理
KNN是机器学习中较为经典的算法。如果一个样本在特征空间的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。其中,两个样本间距离计算可以利用欧式距离计算法则:
∣
d
∣
=
(
a
2
−
a
1
)
2
+
(
b
2
−
b
1
)
2
+
(
c
2
−
c
1
)
2
+
.
.
.
|d|=\sqrt{(a_2-a_1)^2+(b_2-b_1)^2+(c_2-c_1)^2+...}
∣d∣=(a2−a1)2+(b2−b1)2+(c2−c1)2+...
其他距离计算法则还包括曼哈顿距离(绝对值距离)、明可夫斯基距离等等。计算出样本A与其他样本之间的距离后,k可取许多值,如当k=1时,A与离其最近的样本同属于一个类别。当k=2时,A与其最近的两个样本同属于一个类别。
然而,k的取值也存在一定约束:
- 当k过小,容易受到异常点的影响
- 当k过大,会受到样本不均衡的影响
下面,我们来介绍如何简单地调用KNN。
2.2.2 KNN API
作为在sklearn中已经被预先定义好的函数,KNN的API是这样的:
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, algorithm='auto')
- n_neighbors:int类型,默认=5,是k_neighbors查询默认使用的邻居数
- algorithm:{‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’},可选用于计算最近邻居的算法:如使用BallTree,KDTree。'auto’将尝试根据传递给fit方法的值来决定最合适的算法。不同实现方式影响效率。
2.2.3 案例:鸢尾花数据集
我们不妨使用sklearn的典中典—鸢尾花数据集来练练手。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
def knn_iris():
"""
使用KNN对鸢尾花数据集进行分类
:returns:
"""
# 1. 获取数据
iris_data = load_iris()
# 2. 划分数据集,注意接收的顺序
x_train, x_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, random_state=100)
# 先传特征值,再传目标值,可选划分比率、随机种子等。随机种子不同,模型准确率不同,但确定了随机种子后每次程序运行结果相同。
# 特征值的合法类别详情请见函数描述。
# 3. 特征工程:标准化
transfer_std = StandardScaler()
x_train = transfer_std.fit_transform(x_train)
x_test = transfer_std.transform(x_test) # 这里不再fit,使用x_train fit出来的平均值和标准差即可,直接transform数据。
# 4. 使用KNN
estimator_knn = KNeighborsClassifier(n_neighbors=5)
estimator_knn.fit(x_train, y_train)
# 5. 模型评估
# 方法1:直接对比真实值和预测值
y_pred = estimator_knn.predict(x_test)
print("y_pred:\n", y_pred)
print("直接比对全部真实值和预测值:\n", y_test == y_pred)
# 方法2:计算准确率(个人喜欢这种 上面的方法对于大量数据太麻烦)
model_score = estimator_knn.score(x_test, y_test)
print("准确率为:\n", model_score)
return None
if __name__ == "__main__":
knn_iris()
2.3 模型选择与调优
通常在建模过程中(特别是分类模型),我们会面临两个问题:
- 如何让被评估的模型更加准确可信?
- 有一些参数是手动选择的,我们称之为超参数。如何确定超参数选取得当?
针对这两个问题,分别有两种对应的解决方式。
2.3.1 交叉验证
交叉验证即将拿到的训练数据分为训练集和验证集。以下图为例:将数据分成4份,其中一份作为验证集。经过4组测试,每次都更换不同的验证集,即得到四组模型的结果,取平均值作为最终结果,又称4折交叉验证。
2.3.2 网格搜索
作为一种超参数搜索方法,网格搜索(Grid Search)能够较为高效地确定最合适的超参数。通常,我们会选定几个超参数,然后传入模型选择与调优的API,并且确定交叉验证的折数(n等份就是n折交叉验证)。每组超参数都采用交叉验证进行评估,最后选出最优参数组合建立模型。
2.3.3 模型选择与调优API
这个API善良之处在于同时支持进行网格搜索与API。正如2.3.2所说,魅族超参数都会采用交叉验证进行评估。这个API长这样:
sklearn.model_selection.GridSearchCV(estimator, param_grid=None, cv=None)
- estimator:估计器对象
- param_grid:估计其参数,字典类型,如 {“n_neighbors”: [1, 3, 5, 7]}
- cv:指定几折交叉验证
- .fit()方法:输入训练数据
- 结果分析:
- 最佳参数:best_params_
- 最佳结果:best_score_
- 最佳估计器:best_estimator_
- 交叉验证结果:cv_results_
2.3.4 案例:鸢尾花数据集
我们只需在实例化estimator类之后**利用GridSearchCV类为estimator进行一些"修饰"**即可。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
def knn_iris_gscv():
"""
使用KNN对鸢尾花数据集进行分类,并利用交叉验证和网格搜索挑选最优超参数
:returns:
"""
# 1. 获取数据
iris_data = load_iris()
# 2. 划分数据集,注意接收的顺序
x_train, x_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, random_state=100)
# 先传特征值,再传目标值,可选划分比率、随机种子等。随机种子不同,模型准确率不同,但确定了随机种子后每次程序运行结果相同。
# 特征值的合法类别详情请见函数描述。
# 3. 特征工程:标准化
transfer_std = StandardScaler()
x_train = transfer_std.fit_transform(x_train)
x_test = transfer_std.transform(x_test) # 这里不再fit,使用x_train fit出来的平均值和标准差即可,直接transform数据。
# 4. 使用KNN
estimator_knn = KNeighborsClassifier()
# 挑选超参数,类型为字典
param_dict = {"n_neighbors": [1, 3, 5, 7, 9, 11]}
# ※※※※※※ 加入网格搜索与交叉验证 ※※※※※※
estimator_knn = GridSearchCV(estimator_knn, param_grid=param_dict, cv=10) # 数据少,多来几折
estimator_knn.fit(x_train, y_train)
# 5. 模型评估
# 方法1:直接对比真实值和预测值
y_pred = estimator_knn.predict(x_test)
print("y_pred:\n", y_pred)
print("直接比对全部真实值和预测值:\n", y_test == y_pred)
# 方法2:计算准确率(个人喜欢这种 上面的方法对于大量数据太麻烦)
model_score = estimator_knn.score(x_test, y_test)
print("准确率为:\n", model_score)
# 最佳参数:
print("最佳参数:\n", estimator_knn.best_params_)
# 最佳结果:
print("最佳结果:\n", estimator_knn.best_score_)
# 最佳估计器:
print("最佳估计器:\n", estimator_knn.best_estimator_)
# 交叉验证结果:
print("交叉验证结果:\n", estimator_knn.cv_results_)
return None
if __name__ == "__main__":
knn_iris_gscv()
2.3.5 (选) pandas复杂数据筛选
详情见这里(黑马程序员-案例-facebook)
2.4 朴素贝叶斯算法
- 学习目标:
- 说明条件概率与联合概率
- 说明贝叶斯公式、以及特征独立的关系
- 记忆贝叶斯公式
- 知道拉普拉斯平滑系数
- 应用贝叶斯公式实现概率的计算
- 应用
- 20类新闻文章分类预测
- 内容预览
- 2.4.1 什么是朴素贝叶斯分类方法
- 2.4.2 联合概率、条件概率与相互独立
- 2.4.3 贝叶斯公式
- 2.4.4 API
- 2.4.5 案例:20类新闻分类
- 2.4.6 总结
2.4.1 朴素贝叶斯算法简介
说来也十分简单,朴素贝叶斯算法对于单一样本输出的结果可以看成一个概率分布。该算法倾向于将该样本分类至概率最大的类别,如下图所示。不妨将朴素贝叶斯的名字改成"简单的概率算法"。
该垃圾邮件有38%的概率为产品类邮件,故算法将该邮件分类至产品类垃圾邮件。
2.4.2 联合概率、条件概率、相互独立
以防屏幕前的你已经忘记了一些小学二年级的数学知识,这里简单复习一下朴素贝叶斯算法可能涉及到的一些简单数学概念:
-
联合概率:包含多个条件,且所有条件同时成立的概率。记作: P ( A , B ) P(A, B) P(A,B)
- 例如: P ( 程序员 , 匀称 ) P(程序员, 匀称) P(程序员,匀称) 表示某人是程序员的同时身材匀称的概率
-
条件概率:事件A在另一个事件B已经发生下的发生概率。记作: P ( A ∣ B ) P(A|B) P(A∣B)
- 例如: P ( 程序员 ∣ 喜欢 ) P(程序员|喜欢) P(程序员∣喜欢) 表示路人甲喜欢在喜欢某人的前提下某人是程序员的概率
-
相互独立:没半毛钱关系, P ( A , B ) = P ( A ) P ( B ) ⟺ P(A,B)=P(A)P(B)\Longleftrightarrow P(A,B)=P(A)P(B)⟺ 事件A与事件B相互独立
2.4.3 贝叶斯公式
贝叶斯公式长这样:
P
(
C
∣
W
)
=
P
(
W
∣
C
)
P
(
C
)
P
(
W
)
P(C|W)=\frac{P(W|C)P(C)}{P(W)}
P(C∣W)=P(W)P(W∣C)P(C)
那么对于朴素贝叶斯,朴素二字何在?很简单,“朴素” 即一个前提:所有事件之间相互独立。因此满足这种条件的前提下,一个成分复杂的联合概率在朴素贝叶斯中被拆解为所有条件单独成立的概率之乘积。即:
P
(
A
,
B
,
C
,
D
,
.
.
.
)
=
P
(
A
)
P
(
B
)
P
(
C
)
P
(
D
)
.
.
.
P(A,B,C,D,...)=P(A)P(B)P(C)P(D)...
P(A,B,C,D,...)=P(A)P(B)P(C)P(D)...
朴素贝叶斯常用于文本分类任务中,以单词为特征。这也是因其前提条件的苛刻性,所以无法用于一些更为暧昧、复杂的分类任务。
应用在文章分类的场景中,我们可以这么理解贝叶斯公式:
P
(
C
∣
F
1
,
F
2
,
.
.
.
)
=
P
(
F
1
,
F
2
,
.
.
.
∣
C
)
P
(
C
)
P
(
F
1
,
F
2
,
.
.
.
)
=
P
(
F
1
∣
C
)
P
(
F
2
∣
C
)
.
.
.
×
P
(
C
)
P
(
F
1
,
F
2
,
.
.
.
)
P(C|F_1,F_2,...)=\frac{P(F_1,F_2,...|C)P(C)}{P(F_1,F_2,...)}=\frac{P(F_1|C)P(F_2|C)...×P(C)}{P(F_1,F_2,...)}
P(C∣F1,F2,...)=P(F1,F2,...)P(F1,F2,...∣C)P(C)=P(F1,F2,...)P(F1∣C)P(F2∣C)...×P(C)
其中,C可以是不同类别。公式中:
-
P ( C ) P(C) P(C):每个文档类别的概率(某文档类别数 / 总文档数量)
-
P ( W ∣ C ) P(W|C) P(W∣C):给定类别下特征(被预测文档中出现的词)的概率
- 计算方法:
P
(
F
i
∣
C
)
=
N
i
/
N
P(F_i|C)=Ni/N
P(Fi∣C)=Ni/N(训练文档中去计算)
- Ni为该 F i F_i Fi词在C类别所有文档中出现的次数
- N为所属类别C下的文档 “所有词出现的次数和”(或许可以理解为C类别下所有文档总字数)
- 计算方法:
P
(
F
i
∣
C
)
=
N
i
/
N
P(F_i|C)=Ni/N
P(Fi∣C)=Ni/N(训练文档中去计算)
-
P ( F 1 , F 2 , . . . ) P(F_1,F_2,...) P(F1,F2,...)预测文档中每个词的概率
如果计算两个类别概率比较:
因此我们只要比较前面的大小即可得出谁的概率大
然而,实际计算中, P ( F i ∣ C ) = N i / N P(F_i|C)=Ni/N P(Fi∣C)=Ni/N这样的计算方法可能导致 P ( F i ∣ C ) = 0 P(F_i|C)=0 P(Fi∣C)=0,这是不合理的。因此为了处理这种 “0” 的问题,我们引入一个概念:拉普拉斯平滑系数。
拉普拉斯平滑系数
这个系数存在的目的即防止计算出的分类概率为0。因此,
P
(
F
i
∣
C
)
=
N
i
/
N
P(F_i|C)=Ni/N
P(Fi∣C)=Ni/N可以被改进为
P
(
F
i
∣
C
)
=
N
i
+
α
N
+
α
m
P(F_i|C)=\frac{Ni+α}{N+αm}
P(Fi∣C)=N+αmNi+α
其中,
α
α
α为指定的系数,一般取1,
m
m
m为训练文档中统计出的特征词个数。为了更好理解贝叶斯公式以及拉普拉斯平滑系数,我们举一个小栗子:
小栗子
任务: 确定测试集是否属于c=China,
即求 P ( C ∣ C h i n e s e , C h i n e s e , C h i n e s e , T o k y o , J a p a n ) P(C|Chinese,Chinese,Chinese,Tokyo,Japan) P(C∣Chinese,Chinese,Chinese,Tokyo,Japan)
与 P ( C ‾ ∣ C h i n e s e , C h i n e s e , C h i n e s e , T o k y o , J a p a n ) P(\overline{C}|Chinese,Chinese,Chinese,Tokyo,Japan) P(C∣Chinese,Chinese,Chinese,Tokyo,Japan)的大小关系。
解:
根据(朴素)贝叶斯公式
P
(
C
∣
C
h
i
n
e
s
e
,
C
h
i
n
e
s
e
,
C
h
i
n
e
s
e
,
T
o
k
y
o
,
J
a
p
a
n
)
=
P
(
C
h
i
n
e
s
e
,
C
h
i
n
e
s
e
,
C
h
i
n
e
s
e
,
T
o
k
y
o
,
J
a
p
a
n
∣
C
)
×
P
(
C
)
P
(
C
h
i
n
e
s
e
,
C
h
i
n
e
s
e
,
C
h
i
n
e
s
e
,
T
o
k
y
o
,
J
a
p
a
n
)
=
P
(
C
h
i
n
e
s
e
∣
C
)
3
×
P
(
T
o
k
y
o
∣
C
)
×
P
(
J
a
p
a
n
∣
C
)
×
P
(
C
)
P
(
C
h
i
n
e
s
e
∣
C
)
3
×
P
(
T
o
k
y
o
∣
C
)
×
P
(
J
a
p
a
n
∣
C
)
\begin{split} &P(C|Chinese,Chinese,Chinese,Tokyo,Japan) \\&= \frac{P(Chinese,Chinese,Chinese,Tokyo,Japan|C)×P(C)}{P(Chinese,Chinese,Chinese,Tokyo,Japan)} \\&=\frac{P(Chinese|C)^3×P(Tokyo|C)×P(Japan|C)×P(C)}{P(Chinese|C)^3×P(Tokyo|C)×P(Japan|C)} \end{split}
P(C∣Chinese,Chinese,Chinese,Tokyo,Japan)=P(Chinese,Chinese,Chinese,Tokyo,Japan)P(Chinese,Chinese,Chinese,Tokyo,Japan∣C)×P(C)=P(Chinese∣C)3×P(Tokyo∣C)×P(Japan∣C)P(Chinese∣C)3×P(Tokyo∣C)×P(Japan∣C)×P(C)
设置拉普拉斯平滑系数
α
=
1
α=1
α=1,则其中
P
(
C
h
i
n
e
s
e
∣
C
)
=
N
C
h
i
n
e
s
e
+
α
N
+
α
m
=
5
+
1
8
+
1
×
6
=
3
7
P(Chinese|C)=\frac{N_{Chinese}+α}{N+αm}=\frac{5+1}{8+1×6}=\frac37
P(Chinese∣C)=N+αmNChinese+α=8+1×65+1=73
同理,
P
(
T
o
k
y
o
∣
C
)
=
1
14
,
P
(
J
a
p
a
n
∣
C
)
=
1
14
P(Tokyo|C)=\frac{1}{14}, P(Japan|C)=\frac{1}{14}
P(Tokyo∣C)=141,P(Japan∣C)=141,且
P
(
C
)
=
3
4
P(C)=\frac34
P(C)=43
而 P ( C h i n e s e ∣ C ‾ ) = 2 9 = P ( T o k y o ∣ C ‾ ) = P ( J a p a n ∣ C ‾ ) , P ( C ‾ ) = 1 4 P(Chinese|\overline{C})=\frac29=P(Tokyo|\overline{C})=P(Japan|\overline{C}), P(\overline{C})=\frac14 P(Chinese∣C)=92=P(Tokyo∣C)=P(Japan∣C),P(C)=41
∴ ( 3 7 ) 3 × ( 1 14 ) 2 × 3 4 > ( 2 9 ) 5 × 1 4 \therefore(\frac37)^3×(\frac{1}{14})^2×\frac34>(\frac29)^5×\frac14 ∴(73)3×(141)2×43>(92)5×41,测试集属于c=China类。
2.4.4 朴素贝叶斯API
终于来到了喜闻乐见的API环节。
sklearn.naive_bayes.MultinomialNB(alpha=1.0)
- 算法:朴素贝叶斯分类
- alpha:拉普拉斯平滑系数,默认为1。实际项目中可使用网格搜索调试参数。(0.01, 0.1, 1, …)
2.4.5 案例:新闻分类
本来手懒了,不想敲了,但想到可以结合一下网格搜索进行自动化调参,还是想试一试的。毕竟不想亲自成为调参侠,就要让电脑懂得自己成为调参侠。
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
def n_bayes_gscv(xtrain, ytrain, xtest, ytest):
"""
朴素贝叶斯算法+网格搜索调优alpha
:param xtrain: 训练集数据
:param ytrain: 训练集标签
:param xtest: 测试集数据
:param ytest: 测试集标签
:return: 调参完毕的估计器类
"""
estimator_nb = MultinomialNB()
param_dict = {"alpha": [0.01, 0.03, 0.1, 0.3, 1]}
# 用网格搜索与交叉验证修饰模型
estimator_nb = GridSearchCV(estimator_nb, param_grid=param_dict, cv=4)
estimator_nb.fit(xtrain, ytrain)
# 模型评估
print("accuracy:", estimator_nb.score(xtest, ytest))
print("best alpha:", estimator_nb.best_params_)
print("best result:", estimator_nb.best_score_)
return None
if __name__ == "__main__":
# 1. 获取数据
data_news = fetch_20newsgroups(subset="all")
# 2. 划分数据集
x_train, x_test, y_train, y_test = train_test_split(data_news.data, data_news.target)
# 3. 特征工程-文本特征抽取
transfer_tfidf = TfidfVectorizer()
x_train = transfer_tfidf.fit_transform(x_train)
x_test = transfer_tfidf.transform(x_test)
# 4. 训练模型+评估
n_bayes_gscv(x_train, y_train, x_test, y_test)
这个函数是作者自己写的,独立性更强,适合场景丰富,比参考课程的要好些。
2.4.6 总结
朴素贝叶斯算法优点:
- 发源于古典数学理论,又稳定的分类效率
- 对缺失数据不太敏感,算法较简单,常用于文本分类
- 分类准确度高,速度快
缺点:
- 由于使用了样本属性独立性的加色和,所以如果特征属性有关联时,模型效果不好。
2.5 决策树
- 学习目标
- 说明信息熵的公式及作用
- 说明信息增益的公式及作用
- 应用信息增益实现计算特征的不确定性减少程度
- 了解决策树的三种算法实现
- 应用
- 泰坦尼克号乘客生存预测
- 内容预览
- 2.5.1 认识决策树
- 2.5.2 决策树分类原理详解
- 2.5.3 决策树API
- 2.5.4 案例:泰坦尼克号乘客生存预测
- 2.5.5 决策树可视化
- 2.5.6 决策树总结
2.5.1 认识决策树
决策树是较简单的算法,其本质思想即通过一系列的if-else条件语句对一个多性质事物进行分类。影响决策树分类效果的最重要因素是具体特征与具体类别之间的关联程度与该特征在决策过程中的上下游位置(人话:如果一个特征的值能够高度决定其所属的类别,那么这个特征越靠决策的上游越好,因为判断完这个特征后很可能无需进行后续决策)。一般而言,最重要的特征(关联程度最高的特征)是根节点 / 源头特征。因此,决策树最终效果好坏与特征顺序直接相关。
那么,有没有一种数学方法能够帮助我们快速进行特征的排序呢?显然是有的,答案隐藏在一个你大概率听过但也许不是很了解的两个概念中:信息熵与信息增益。
2.5.2 决策树分类原理详解
通过2.5.1的介绍,想必你已经了解到,我们需要将更能够区分不同类别的特征放置于决策树的上游,即需要将能够消除更多未知信息的特征放置于决策树的上游,这样有助于更高效地区分数据。为什么这么下结论呢?
假设有一个事物,它有A、B、C、D四个特征,每个特征取值都为是 / 否。我们的最终决策是这个事物好/不好。于是,我们需要按顺序确认某个事物应该归属于什么类别。不妨做如下假设:
特征 | 确认特征取值后,能够直接进行最终决策的“概率” |
---|---|
A | 45% |
B | 20% |
C | 80% |
D | 30% |
为了最终模型的效率,我们应该将C的取值作为最先进行决策的依据,之后是A、D、B。然而,实际操作中我们并不会涉及到确认特征取值后,能够直接进行最终决策的“概率”
这个复杂的概念。我们使用信息熵这个概念作为一种更数学化的代替。
信息熵
信息熵,单位比特。信息熵是衡量一条信息模糊程度的概念,信息熵越高,信息越模糊。决策的过程就是不断减少信息熵、让信息越来越透明的过程。我们的目的,就是找出更有利于减少信息熵的特征,作为更靠近上游的特征,并对所有特征进行排序。信息熵的计算公式为
H
(
X
)
=
−
∑
i
=
1
n
P
(
x
i
)
log
b
P
(
x
i
)
H(X)=-\sum_{i=1}^{n}P(x_i)\log_bP(x_i)
H(X)=−i=1∑nP(xi)logbP(xi)
- H ( X ) H(X) H(X)表示特征X的信息熵
- P ( x i ) P(x_i) P(xi)为某特征取特定值的概率。为了得到某个特征的信息熵,我们必须先求出特征取每个值的概率,之后代入公式 ( 7 ) (7) (7)进行加和。
不过,信息熵并不是决策树的直接划分依据。决策树的划分依据之一,是信息增益。
信息增益
特征A对训练数据集D的信息增益
g
(
D
,
A
)
g(D,A)
g(D,A),定义为集合D的信息熵
H
(
D
)
H(D)
H(D)与特征A在给定条件D下的信息条件熵之差,数学上表示为:
g
(
D
,
A
)
=
H
(
D
)
−
H
(
D
∣
A
)
g(D,A)=H(D)-H(D|A)
g(D,A)=H(D)−H(D∣A)
为了最终模型的效率,我们应该将C的取值作为最先进行决策的依据,之后是A、D、B。然而,实际操作中我们并不会涉及到确认特征取值后,能够直接进行最终决策的“概率”
这个复杂的概念。我们使用信息熵这个概念作为一种更数学化的代替。
最后编辑于:2022/07/24 23:17