课程地址:《菜菜的机器学习sklearn课堂》_哔哩哔哩_bilibili
目录
sklearn入门
决策树(Decision Tree,DT)
(一)决策树是如何工作的
(二)sklearn中的决策树
分类树DecisionTreeClassifier与红酒数据集
重要参数
(一)criterion:用来决定不纯度的计算方法
(二)random_state & splitter:控制随机性
(三)剪枝参数(5个)
(四)目标权重参数(完成样本标签平衡的参数,不常用)
重要属性和接口
总结
回归树DecisionTreeRegressor与波士顿房价数据集
重要参数、属性及接口
(一)criterion(回归树衡量分枝质量的指标)
(二)属性
(三)接口
(四)交叉验证
实例:一维回归的图像绘制
决策树的优缺点
scikit-learn是一个开源的基于Python的机器学习工具包
分析采集到的数据,根据数据特征选择适合的算法,在工具包中调用算法,调整算法的参数,获取需要的信息,从而实现算法效率和效果之间的平衡
解析sklearn的全面应用,了解不同机器学习算法有哪些可调参数、有哪些可用接口,这些接口和参数对算法来说有什么含义,又会对算法的性能及准确性有什么影响 —— 讲解sklearn中对算法的说明、调参、属性、接口,以及实例应用
sklearn官网:scikit-learn: machine learning in Python — scikit-learn 1.2.0 documentation
- 分类、回归、聚类、降维、模型选择、数据预处理
是一种非参数(不限制数据的结构和类型,几乎可以用它来处理各种各样的数据)的有监督学习(要给标签)方法,能够从一系列有特征和标签的数据中总结出决策规则,并用树状图的结构来呈现这些规则,以解决分类和回归问题
决策树算法的核心是要解决两个问题:
模块sklearn.tree,包含五个类(还有两个类分别是高随机版本的分类树和回归树,不常用):
sklearn的基本建模流程:
在这个流程下,分类树对应的代码是:
from sklearn import tree
clf = tree.DecisionTreeClassifier() # 实例化
clf = clf.fit(X_train,y_train) # 用训练集数据训练模型
result = clf.score(X_test,y_test) # 导入测试集,从接口中调用需要的信息(对分类模型来说就是accuracy)
为了要将表格转化成一棵树,决策树需要找出最佳节点和最佳分枝方法。对分类树来说,衡量这个最佳的指标是不纯度
- 不纯度越低,决策树对训练集的拟合越好
- 基于节点来计算,子节点的不纯度一定低于父节点
- 在同一棵决策树上,叶子节点的不纯度一定最低
sklearn提供了两种选择:
对比:
决策树的基本流程可以简单概括为:
计算全部特征的不纯度指标 ——> 选取不纯度指标最优的特征来分枝 ——> 在第一个特征的分枝下,计算全部特征的不纯度指标 ——> 选取不纯度指标最优的特征继续分枝... ——> 直到没有更多的特征可用,或整体的不纯度指标已经最优,决策树就会停止生长
from sklearn import tree
from sklearn.datasets import load_wine # datasets是sklearn自带的含有各种各样数据的库,包含波士顿房价、鸢尾花、红酒数据等
from sklearn.model_selection import train_test_split
wine = load_wine() # 数据实例化
# wine是一个字典,wine.data取数据,wine.target取标签
wine.data.shape # 13个特征
wine.target # 三分类
# 将wine变成一张表
import pandas as pd
pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)
wine.feature_names
wine.target_names
# 分训练集和测试集
Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data,wine.target,test_size=0.3)
# 建立模型
clf = tree.DecisionTreeClassifier(criterion="entropy") # 实例化,criterion默认为gini
clf = clf.fit(Xtrain, Ytrain) # 把数据带进去训练
score = clf.score(Xtest, Ytest) # 返回预测的准确度accuracy
score
# 画树
feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸']
import graphviz
dot_data = tree.export_graphviz(clf # 已经训练好的模型
,feature_names = feature_name
,class_names=["琴酒","雪莉","贝尔摩德"]
,filled=True # 填充颜色(不纯度越低,颜色越深)
,rounded=True # 框的形状
)
graph = graphviz.Source(dot_data) # 越往下,不纯度entropy越低。不纯度为0时,就可以选出标签类别了
graph
# 特征重要性(没有使用的特征,为0)
clf.feature_importances_ # 对决策树贡献越大的,重要性越高(根节点对特征重要性的贡献一定是最大的)
[*zip(feature_name,clf.feature_importances_)]
上述代码每次运行得到的结果都不一样,这是为什么?
树一旦建成,使用剪枝参数来防止过拟合
sklearn为我们提供了不同的剪枝策略:
确定最优的剪枝参数:超参数学习曲线,是一条以超参数的取值为横坐标,模型的度量指标为纵坐标的曲线,它是用来衡量不同超参数取值下模型的表现的线
import matplotlib.pyplot as plt
test = []
for i in range(10):
clf = tree.DecisionTreeClassifier(max_depth=i+1 # 1-10
,criterion="entropy"
,random_state=30
,splitter="random"
)
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)
test.append(score)
plt.plot(range(1,11),test,color="red",label="max_depth")
plt.legend()
plt.show()
属性:在模型训练之后,能够调用查看的模型的各种性质。对决策树来说,属性feature_importances_能够查看各个特征对模型的重要性
接口:
所有接口中要求输入 X_train 和 X_test 的部分,输入的特征矩阵必须至少是一个二维矩阵(sklearn不接受任何一维矩阵作为特征矩阵被输入)
分类树的八个参数、一个属性(feature_importances_)、四个接口(fit,score,apply,predict)
八个参数:
在回归树中,没有标签分布是否均衡的问题,故没有class_weight这样的参数
在回归树中,MSE不只是分枝质量衡量指标,也是最常用的衡量回归树回归质量的指标
在使用交叉验证获取回归树的结果时,往往选择MSE作为评估(在分类树中是score代表的accuracy)
feature_importances_
score返回的是R²(默认),不是MSE
u是残差平方和,v是总平方和将数据划分为n份,依次使用其中一份作为测试集,其他n-1份作为训练集,多次计算模型的精确性来评估模型的平均准确程度
训练集和测试集的划分会干扰模型的结果,因此用交叉验证n次的结果求出的平均值,是对模型效果的一个更好的度量
交叉验证的过程包含了fit
from sklearn.datasets import load_boston
from sklearn.model_selection import cross_val_score
from sklearn.tree import DecisionTreeRegressor
boston = load_boston() # 字典
# boston.data取数据,boston.target取标签(连续型变量)
regressor = DecisionTreeRegressor(random_state=0) #实例化
# 交叉验证传入的是完整数据,不需要划分训练集和测试集
# cv=10意味着十折,1份测试,9份训练。默认为5
cross_val_score(regressor, boston.data, boston.target, cv=10, scoring="neg_mean_squared_error").mean()
用回归树来拟合正弦曲线,并添加一些噪声来观察回归树
.rand(x):随机生成x个0-1之间的随机数
.rand(x,y):x行y列的数组
np.random.rand(数组结构):生成随机数组
np.sort(axis=0):从小到大排序(按行)
.ravel():降维函数,n维降维n-1维,多次运行可以一直降到1维
np.newaxis:增维切片
- l = np.array([1,2,3,4]) # (4,)
- l[: , np.newaxis] # (4,1)
- l[np.newaxis, :] # (1,4)
import numpy as np # 生成数据点,即正弦曲线
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt
# 创建一条含有噪声的正弦曲线
'''
基本思路:
先创建一组随机的、分布在0-5上的横坐标轴的取值(x),
然后将这一组值放到sin函数中去生成纵坐标的值(y),
接着再到y上去添加噪声
'''
rng = np.random.RandomState(1) #随机数种子(一种固定的随机)
'''
接口不允许导入一维数组,故X生成的是二维的
'''
X = np.sort(5 * rng.rand(80,1), axis=0) #生成0~5之间随机的x的取值
'''
输入的X是二维的,故np.sin(X)生成的结果也一定是二维的。
但是导入回归树的标签必须是一维的,否则会报错
故使用.ravel()降维
'''
y = np.sin(X).ravel() #生成正弦曲线
'''
y[::5]中的5为步长,故取出16个数
'''
y[::5] += 3 * (0.5 - rng.rand(16)) #在正弦曲线上加噪声
plt.figure() # 画布
plt.scatter(X, y, s=20, edgecolor="black",c="darkorange", label="data") # s为点的大小
# 实例化&训练模型
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_1.fit(X, y)
regr_2.fit(X, y)
# 测试集导入模型,预测结果
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)
# 绘制图像
plt.figure()
plt.scatter(X, y, s=20, edgecolor="black",c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue",label="max_depth=2", linewidth=2)
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2) # 过拟合了
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()
如果树的最大深度(由max_depth控制)设置的太高,则决策树学习的太精细,它从训练数据中学了很多细节(包括噪声的呈现),从而使模型偏离真实的正弦曲线,过拟合