我是靠谱客的博主 调皮镜子,最近开发中收集的这篇文章主要介绍【Python人工智能】Python全栈体系(十七)人工智能,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

人工智能

第五章 车辆评级分类与cart分类树

一、决策树分类

1. 算法核心原理

  • 决策树的核心思想:相似的输入产生相似的输出。

2. 决策树的关键问题

  • 这么多特征,使用哪个特征先进行子表划分?

3. CART 分类树

  • CART 分类树算法对每个特征进行二分,寻找分割点时使用基尼系数来表达数据集的不纯度,基尼系数越小,不纯度越低,数据集划分的效果越好。
  • CART 分类树划分子表的过程:
    • 针对每个特征,基于基尼系数计算最优分割值。在计算出来的各个特征的每个分割值对数据集 D D D的基尼系数中,选择基尼系数最小的特征A和对应的分割值a。根据这个最优特征和最优分割值,把数据集划分成两部分 D 1 D_1 D1 D 2 D_2 D2,同时建立当前节点的左右节点,左节点的数据集 D D D D 1 D_1 D1,右节点的数据集 D D D D 2 D_2 D2.对左右节点的子节点递归调用这个过程,生成决策树。
  • 而 CART 分类树也基于基尼系数来决定子表划分所选特征的次序

4. 基尼系数

  • 对于样本D,个数为|D|,假设K个类别,第k个类别的数量为 C k C_k Ck,则样本D的基尼系数表达式:
    G i n i ( D ) = 1 − ∑ i = 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 Gini(D) = 1 - sum_{i=1}^K left(frac{|C_k|}{|D|}right)^2 Gini(D)=1i=1K(DCk)2
  • 有100个样本( D 1 D_1 D1)包含A与B两个类别,数量分别为40与60,Gini( D 1 D_1 D1) = ?
    1 − ( ( ∣ 40 ∣ ∣ 100 ∣ ) 2 + ( ∣ 60 ∣ ∣ 100 ∣ ) 2 ) = 1 − ( 0.16 + 0.36 ) = 0.48 1 - left( left(frac{|40|}{|100|}right)^2 + left( frac{|60|}{|100|}right)^2 right) = 1 - (0.16 + 0.36) = 0.48 1((10040)2+(10060)2)=1(0.16+0.36)=0.48
  • 有100个样本( D 2 D_2 D2)包含A与B两个类别,数量分别为10与90,Gini( D 2 D_2 D2) = ?
    1 − ( ( ∣ 10 ∣ ∣ 100 ∣ ) 2 + ( ∣ 90 ∣ ∣ 100 ∣ ) 2 ) = 1 − ( 0.01 + 0.81 ) = 0.18 1 - left( left( frac{|10|}{|100|}right)^2 + left( frac{|90|}{|100|}right)^2 right) = 1 - (0.01 + 0.81) = 0.18 1((10010)2+(10090)2)=1(0.01+0.81)=0.18
  • 对于样本D,个数为|D|,根据特征A的某个值a,把D分成 D 1 D_1 D1 D 2 D_2 D2,则在特征A的条件下,样本D的基尼系数表达式为:
    G i n i ( D , A ) = ∣ D 1 ∣ ∣ D ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) Gini(D,A) = frac{|D_1|}{|D|} Gini(D_1) + frac{|D_2|}{|D|} Gini(D_2) Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)

5. 决策树的生成过程

  • 算法输入训练集D,基尼系数的阈值,样本个数阈值。输出决策树T。
    • 对于当前节点的数据集为D,如果样本个数小于阈值,则返回决策子树,当前节点停止递归。
    • 计算样本集D的基尼系数,如果基尼系数小于阈值,则返回决策树子树,当前节点停止递归。
    • 计算当前节点现有的各个特征的各个特征值对数据集D的基尼系数。
    • 在计算出来的各个特征的各个特征值对数据集D的基尼系数中,选择基尼系数最小的特征A和对应的特征值a。根据这个最优特征和最优特征值,把数据集划分成两部分 D 1 D_1 D1 D 2 D_2 D2,同时建立当前节点的左右节点,左节点的数据集D为 D 1 D_1 D1,右节点的数据集D为 D 2 D_2 D2
    • 对左右的子节点递归的调用1-4步,生成决策树。
  • 预测过程:对生成的决策树做预测的时候,假如测试集里的样本A落到了某个叶子节点,而节点里有多个训练样本。则对于A的类别预测采用的是这个叶子节点里概率最大的类别

6. 决策树分类实现

  • 决策树分类器模型相关 API:
import sklearn.tree as st
# 决策树分类器
model = st.DecisionTreeClassifier(
max_depth=6, min_samples_split=3, random_state=7)
model.fit(train_x, train_y)

7. 鸢尾花案例

import sklearn.tree as st
model = st.DecisionTreeClassifier(max_depth=4, min_samples_split=3)
model.fit(train_x, train_y)
# 评估 模型准确率
pred_test_y = model.predict(test_x)
print((pred_test_y==test_y).sum() / test_y.size)
print(test_y.values)
"""
0.8666666666666667
[2 0 0 1 0 2 2 2 1 1 2 1 1 0 0]
"""

8. 集合模型分类实现

  • 集合模型提供的常用分类器
import sklearn.ensemble as se
model = se.RandomForestClassifier(...) # 随机森林分类器
model = se.AdaBoostClassifier(...) # AdaBoost分类器
model = se.GridientBoostingClassifier(...) # GBDT分类器

二、预测小汽车等级

  • car.txt 样本文件中统计了小汽车的常见特征信息及小汽车的分类,使用这些数据基于决策树分类算法训练模型预测小汽车等级。
  • 汽车价格 维修费用 车门数量 载客数 后备箱 安全性 汽车级别
  • 分析实现思路:
    • 加载数据。
    • 特征分析与特征工程。
    • 数据预处理(标签编码)。
    • 训练模型。
    • 模型测试。
import numpy as np
import pandas as pd
data = pd.read_csv('car.txt', header=None) # 不想把第一行当做表头
data.head()

请添加图片描述

data[0].value_counts() # 汽车价格分成4类,按类别划分每个类别有432个样本
"""
vhigh
432
low
432
med
432
high
432
Name: 0, dtype: int64
"""
  • 确定:是分类问题,还是回归问题?答:分类
  • 选哪一个分类模型:逻辑回归、决策树、RF、GBDT、AdaBoost?答:RF(当然也可以尝试其他模型)
# 针对当前这组数据完成标签编码预处理
import sklearn.preprocessing as sp
# 遍历每一列数据
train_data = pd.DataFrame([])
encoders = {}
for col_ind, col_val in data.items():
encoder = sp.LabelEncoder()
train_data[col_ind] = encoder.fit_transform(col_val)
encoders[col_ind] = encoder
train_data

请添加图片描述

# 整理输入集与输出集
x, y = train_data.iloc[:, :-1], train_data[6]
x.shape, y.shape
"""
((1728, 6), (1728,))
"""
# 创建分类模型
model = se.RandomForestClassifier(max_depth=6, n_estimators=400, random_state=7)
# 做5次交叉验证,验证一下这个模型是否可用
scores = ms.cross_val_score(model, x, y, cv=5, scoring='f1_weighted')
# 如果分数还可以,再正儿八经的训练模型
print(scores.mean())
"""
0.7537201013972693
"""
# 模型评估(先用训练样本进行模型评估)
model.fit(x, y)
pred_y = model.predict(x)
print(sm.classification_report(y, pred_y))
print(sm.confusion_matrix(y,pred_y)) # 把1类别的全归到0类别里了
"""
precision
recall
f1-score
support
0
0.77
0.82
0.79
384
1
0.00
0.00
0.00
69
2
0.95
0.99
0.97
1210
3
1.00
0.77
0.87
65
accuracy
0.91
1728
macro avg
0.68
0.65
0.66
1728
weighted avg
0.87
0.91
0.89
1728
[[ 315
0
69
0]
[
69
0
0
0]
[
11
0 1199
0]
[
15
0
0
50]]
"""
data = [
['high', 'med', '5more', '4', 'big', 'low', 'unacc'],
['high', 'high', '4', '4', 'med', 'med', 'acc'],
['low', 'low', '2', '4', 'small', 'high', 'good'],
['low', 'med', '3', '4', 'med', 'high', 'vgood']
]
test_data = pd.DataFrame(data)
for col_ind, col_val in test_data.items():
encoder = encoders[col_ind]
encoded_col = encoder.transform(col_val)
test_data[col_ind] = encoded_col
# 整理输入集与输出集
test_x, test_y = test_data.iloc[:,:-1], test_data[6]
pred_test_y = model.predict(test_x)
pred_test_y
"""
array([2, 0, 0, 0])
"""
encoders[6].inverse_transform(pred_test_y)
"""
array(['unacc', 'acc', 'acc', 'acc'], dtype=object)
"""

三、验证曲线与学习曲线

1. 验证曲线

  • 验证曲线描述的关系即是模型性能关于模型超参数的函数关系:
    • 模型性能 = f(超参数)

2. 验证曲线实现

  • sklearn 提供的验证曲线 API:
train_scores, test_scores = ms.validation_curve(
model,
# 模型
输入集, 输出集,
'n_estimators',
# 超参数名
np.arange(50, 550, 50),	# 超参数序列
cv=5	# 折叠数
)
  • 返回train_scores与test_scores为每个超参数取值下的每次交叉验证结果组成的得分矩阵。

3. 案例:预测小汽车等级调整参数

import numpy as np
import pandas as pd
data = pd.read_csv('car.txt', header=None) # 不想把第一行当做表头
# 针对当前这组数据完成标签编码预处理
import sklearn.preprocessing as sp
import sklearn.ensemble as se
import sklearn.model_selection as ms
import sklearn.metrics as sm
# 遍历每一列数据
train_data = pd.DataFrame([])
encoders = {}
for col_ind, col_val in data.items():
encoder = sp.LabelEncoder()
train_data[col_ind] = encoder.fit_transform(col_val)
encoders[col_ind] = encoder
# 整理输入集与输出集
x, y = train_data.iloc[:, :-1], train_data[6]
# 创建分类模型(调参之后设定的参数值)
model = se.RandomForestClassifier(max_depth=9, n_estimators=140, random_state=7)
# 验证曲线,选取最优超参数
import matplotlib.pyplot as plt
# params =
np.arange(50, 550, 50)
params = np.arange(100, 200, 10)
train_scores, test_scores = ms.validation_curve(model, x, y, param_name='n_estimators', param_range=params, cv=5)
scores = test_scores.mean(axis=1)
# 验证曲线可视化
plt.grid(linestyle=':')
plt.plot(params, scores, 'o-', color='dodgerblue', label='n_estimators VC')
plt.legend()

请添加图片描述

# 调整max_depth
params = np.arange(1, 12)
train_scores, test_scores = ms.validation_curve(model, x, y, param_name='max_depth', param_range=params, cv=5)
scores = test_scores.mean(axis=1)
# 验证曲线可视化
plt.grid(linestyle=':')
plt.plot(params, scores, 'o-', color='orangered', label='max_depth VC')
plt.legend()

请添加图片描述

model.fit(x, y)
pred_y = model.predict(x)
print(sm.classification_report(y, pred_y))
print(sm.confusion_matrix(y,pred_y))
"""
precision
recall
f1-score
support
0
0.96
1.00
0.98
384
1
1.00
0.75
0.86
69
2
1.00
1.00
1.00
1210
3
0.94
1.00
0.97
65
accuracy
0.99
1728
macro avg
0.97
0.94
0.95
1728
weighted avg
0.99
0.99
0.99
1728
[[ 383
0
0
1]
[
14
52
0
3]
[
3
0 1207
0]
[
0
0
0
65]]
"""
data = [
['high', 'med', '5more', '4', 'big', 'low', 'unacc'],
['high', 'high', '4', '4', 'med', 'med', 'acc'],
['low', 'low', '2', '4', 'small', 'high', 'good'],
['low', 'med', '3', '4', 'med', 'high', 'vgood']
]
test_data = pd.DataFrame(data)
for col_ind, col_val in test_data.items():
encoder = encoders[col_ind]
encoded_col = encoder.transform(col_val)
test_data[col_ind] = encoded_col
# 整理输入集与输出集
test_x, test_y = test_data.iloc[:,:-1], test_data[6]
pred_test_y = model.predict(test_x)
encoders[6].inverse_transform(pred_test_y)
"""
array(['unacc', 'acc', 'good', 'vgood'], dtype=object)
"""

4. 学习曲线

  • 学习曲线描述的关系即是模型性能关于训练样本量大小的函数关系:
    • 模型性能 = f(训练集大小)

5. 学习曲线实现

  • sklearn 提供的学习曲线 API:
train_scores, test_scores = ms.learning_curve(
model,
# 模型
输入集, 输出集,
train_sizes=[0.9, 0.8, 0.7],	# 训练集大小序列
cv=5	# 折叠数
)
  • 返回train_scores与test_scores为每个超参数取值下的每次交叉验证结果组成的得分矩阵。

6. 案例:预测小汽车等级调整参数

params = np.arange(0.1, 1.1, 0.1)
_, train_scores, test_scores = ms.learning_curve(model, x, y, train_sizes=params, cv=5)
scores = test_scores.mean(axis = 1)
# 学习曲线可视化
plt.grid(linestyle=':')
plt.plot(params, scores, 'o-', color='green', label='Learning Curve')
plt.legend()

请添加图片描述

四、完整案例

import numpy as np
import pandas as pd
data = pd.read_csv('car.txt', header=None) # 不想把第一行当做表头
data.head()
"""
0
1
2	3	4
5
6
0	vhigh	vhigh	2	2	small	low
unacc
1	vhigh	vhigh	2	2	small	med
unacc
2	vhigh	vhigh	2	2	small	high	unacc
3	vhigh	vhigh	2	2	med
low
unacc
4	vhigh	vhigh	2	2	med
med
unacc
"""
# 确定:是分类问题,还是回归问题? 分类
#
选哪一个分类模型:逻辑回归、决策树、RF、GBDT、AdaBoost? RF
# 针对当前这组数据完成标签编码预处理
import sklearn.preprocessing as sp
import sklearn.ensemble as se
import sklearn.model_selection as ms
import sklearn.metrics as sm
# 遍历每一列数据
train_data = pd.DataFrame([])
encoders = {}
for col_ind, col_val in data.items():
encoder = sp.LabelEncoder()
train_data[col_ind] = encoder.fit_transform(col_val)
encoders[col_ind] = encoder
# 整理输入集与输出集
x, y = train_data.iloc[:, :-1], train_data[6]
# 创建分类模型
model = se.RandomForestClassifier(max_depth=9, n_estimators=140, random_state=7)
# 验证曲线,选取最优超参数
import matplotlib.pyplot as plt
# params =
np.arange(50, 550, 50)
params = np.arange(100, 200, 10)
train_scores, test_scores = ms.validation_curve(model, x, y, param_name='n_estimators', param_range=params, cv=5)
scores = test_scores.mean(axis=1)
# 验证曲线可视化
plt.grid(linestyle=':')
plt.plot(params, scores, 'o-', color='dodgerblue', label='n_estimators VC')
plt.legend()

请添加图片描述

# 调整max_depth
params = np.arange(1, 12)
train_scores, test_scores = ms.validation_curve(model, x, y, param_name='max_depth', param_range=params, cv=5)
scores = test_scores.mean(axis=1)
# 验证曲线可视化
plt.grid(linestyle=':')
plt.plot(params, scores, 'o-', color='orangered', label='max_depth VC')
plt.legend()

请添加图片描述

# 学习曲线,选取最优训练集大小
params = np.arange(0.1, 1.1, 0.1)
_, train_scores, test_scores = ms.learning_curve(model, x, y, train_sizes=params, cv=5)
scores = test_scores.mean(axis = 1)
# 学习曲线可视化
plt.grid(linestyle=':')
plt.plot(params, scores, 'o-', color='green', label='Learning Curve')
plt.legend()

请添加图片描述

# 模型评估(先用训练样本进行模型评估)
model.fit(x, y)
pred_y = model.predict(x)
print(sm.classification_report(y, pred_y))
print(sm.confusion_matrix(y,pred_y)) # 把1类别的全归到0类别里了
"""
precision
recall
f1-score
support
0
0.96
1.00
0.98
384
1
1.00
0.75
0.86
69
2
1.00
1.00
1.00
1210
3
0.94
1.00
0.97
65
accuracy
0.99
1728
macro avg
0.97
0.94
0.95
1728
weighted avg
0.99
0.99
0.99
1728
[[ 383
0
0
1]
[
14
52
0
3]
[
3
0 1207
0]
[
0
0
0
65]]
"""
data = [
['high', 'med', '5more', '4', 'big', 'low', 'unacc'],
['high', 'high', '4', '4', 'med', 'med', 'acc'],
['low', 'low', '2', '4', 'small', 'high', 'good'],
['low', 'med', '3', '4', 'med', 'high', 'vgood']
]
test_data = pd.DataFrame(data)
for col_ind, col_val in test_data.items():
encoder = encoders[col_ind]
encoded_col = encoder.transform(col_val)
test_data[col_ind] = encoded_col
# 整理输入集与输出集
test_x, test_y = test_data.iloc[:,:-1], test_data[6]
pred_test_y = model.predict(test_x)
encoders[6].inverse_transform(pred_test_y)
"""
array(['unacc', 'acc', 'good', 'vgood'], dtype=object)
"""

最后

以上就是调皮镜子为你收集整理的【Python人工智能】Python全栈体系(十七)人工智能的全部内容,希望文章能够帮你解决【Python人工智能】Python全栈体系(十七)人工智能所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(30)

评论列表共有 0 条评论

立即
投稿
返回
顶部