在上一篇博客,咱们介绍了决策树的一些知识。若是对决策树还不是很了解的话,建议先阅读上一篇博客,在来学习这一篇。html
本次实验基于scikit-learn中的Iris数据。说了很久的Iris,从OneR到决策树,那么Iris到底长啥样呢?node
首先咱们仍是须要先加载数据集,数据集来自scikit自带的iris数据集,数据集的内容能够参考之前的博客,这里就不在赘述。python
首先让咱们从scikit-learn中加载数据集。git
from sklearn.datasets import load_iris
dataset = load_iris()
data = dataset.data
target = dataset.target
而后咱们再使用pandas将数据进行格式化如下,添加Iris的属性到数据集中。github
import numpy as np
import pandas as pd
data = pd.DataFrame(data,columns=["sepal_length","sepal_width","petal_length","petal_width"])
data["class"] = target
data的数据以下所示:算法
class表明类别。其余的就是Iris的属性了。markdown
这里咱们主要是用画图来看一看Iris数据集的特征。原本觉得画图就matpotlib就好了,可是没想到有seaborn这个好使用的库,来自B站up主的提示。使用的库以下:dom
首先咱们画散点图:ide
import matplotlib.pyplot as plt
import seaborn as sb
# data.dropna()去除里面的none元素
sb.pairplot(data.dropna(),hue="class")
图像以下所示:svg
上面的这幅图展现了在四个属性中的类别的分别状况。
同时咱们还能够画小提琴图:
plt.figure(figsize=(20, 20))
for column_index, column in enumerate(data.columns):
if column == 'class':
continue
plt.subplot(2, 2, column_index + 1)
sb.violinplot(x='class', y=column, data=data)
画出的图以下:
经过上面的这幅图咱们能够直观的比较出哪个变量更具备表明性。好比说petal_width 对类别0更加的友好。
接下来就是进行训练了。
首先的首先,咱们仍是须要从数据集中抽出训练集和测试集。这个内容在前面讲过了,就很少讲了。
from sklearn.model_selection import train_test_split
input_data = data[["sepal_length","sepal_width","petal_length","petal_width"]]
input_class = data["class"]
train_data,test_data,train_class,test_class = train_test_split(input_data,input_class,random_state = 14)
then,让咱们来开始进行训练吧,在scikit-learn中实现了决策树,和前面的K近邻算法同样咱们直接引用就行,调用fit(训练)和predict(预测)函数。使用以下所示:
from sklearn.tree import DecisionTreeClassifier
decision_tree = DecisionTreeClassifier(random_state=14)
decision_tree.fit(train_data,train_class)
predict_class = decision_tree.predict(test_data)
predict_score = np.mean(predict_class == test_class)
print("预测的准确度为{}".format(predict_score))
DecisionTreeClassifier其余的参数在后面说,这里主要说一下random_state
参数。为何决策树还须要random_state这个参数,如下知乎上面的两位博主的说法。
至于哪一个说法是正确的,我暂时也不知道,若是有知道的,能够在评论区留言哦!
最后获得的预测结果以下所示:
这里值得注意的是DecisionTreeClassifier()
函数,里面能够添加不少参数。官方文档在这里: https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html 。
这里仍是稍微的说一下参数。
# criterion gini(默认)/tropy:这里对应的就是以前的熵增益和Gini系数
# splitter best(默认)/random 每一个结点选择的拆分策略
# max_depth 树的最大深度。
# min_samples_split int类型或者float(默认2) 若是某节点的样本数少于min_samples_split,则不会进行拆分了。浮点值表示分数,表明所占比例
# min_samples_leaf 默认=1 这个值限制了叶子节点最少的样本数,若是某叶子节点数目小于样本数,则会和兄弟节点一块儿被剪枝。
# min_weight_fraction_leaf float(默认0.0) 这个值限制了叶子节点全部样本权重,若是小于这个值,则会和兄弟节点一块儿被剪枝。通常来讲,若是咱们有较多样本有缺失值,或者分类树样本的分布类别误差很大,就会引入样本权重,这时咱们就要注意这个值了。
# max_features int, float or {“auto”, “sqrt”, “log2”}(默认0.0)
# max_leaf_nodes 经过限制最大叶子节点数,能够防止过拟合,默认是"None”,即不限制最大的叶子节点数。若是加了限制,算法会创建在最大叶子节点数内最优的决策树。
# class_weight dict/balanced 指定样本各种别的的权重,主要是为了防止训练集某些类别的样本过多致使训练的决策树过于偏向这些类别。这里能够本身指定各个样本的权重。“balanced”,则算法会本身计算权重,样本量少的类别所对应的样本权重会高。
# min_impurity_split 这个值限制了决策树的增加,若是某节点的不纯度(基尼系数,信息增益,均方差,绝对差)小于这个阈值则该节点再也不生成子节点。即为叶子节点 。
更多的能够去看官网细节。
而后咱们能够将这个树的结构可视化,将文件保存在“tree.dot”中:
from sklearn.tree import export_graphviz
with open("tree.dot",'w') as f:
export_graphviz(decision_tree, feature_names =['sepal_length', 'sepal_width', 'petal_length', 'petal_width'], out_file = f)
这个是决策树的图:
一样,咱们还可使用交叉验证,具体的使用能够参考别人的博客,或者看个人这一篇博客:
from sklearn.model_selection import cross_val_score
decision_tree = DecisionTreeClassifier()
scores = cross_val_score(decision_tree,input_data,input_class,scoring='accuracy')
print("交叉验证结果: {0:.2f}%".format(np.mean(scores) * 100))
经过交叉验证获得的准确度以下:
比上面的结果略低,不过这个是正常的。
前面的博客介绍了随机树,这里很少作介绍,直接看使用吧。咱们经过导入RandomForestClassifier
模块,并指令森林中树的个数为30,具体的参数看官网
from sklearn.ensemble import RandomForestClassifier
rft = RandomForestClassifier(n_estimators=20,random_state=14)
rft.fit(train_data,train_class)
predict_class = rft.predict(test_data)
predict_score = np.mean(predict_class == test_class)
print("随机森林预测的准确度为{}".format(predict_score))
最后的结果以下图
而后进行交叉验证:
scores = cross_val_score(rft,input_data,input_class,scoring='accuracy')
print("Accuracy: {0:.2f}%".format(np.mean(scores) * 100))
结果以下:
emm,好像和上面的结果同样,由于这个数据集很小,可能会有这种状况。
首先,咱们能够对决策树的max_feature和max_depth进行调参,改变其值,最终的结果以下:
在随机森林中,咱们能够对树的个数进行调参,结果以下图:
此次并无使用《 Python数据挖掘入门与实践 》书上的例子,实在是它打篮球的数据找不到,emm。相比较与oneR算法的70%左右的正确率,决策树95%正确率已经算足够优秀了。
尽管代码写起来很简单,也很容易实现获得结果,可是咱们真正应该了解的是里面的内涵:决策树是什么?里面是怎样工做的?以及所蕴含的含义……
项目地址:GitHub