1. 导入库import os.path
import os.path
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn import tree
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_moons, make_circles, make_classification
2. 生成或者加载数据集
- 使用sklearn.datasets中的make_classification,make_moons, make_circles,分别生成三组数据集 :1)二分型数据,2)月亮型数据3)环形数据
# 生成二分型数据: make_classification
x, y = make_classification(
n_samples=100, # 生成100个样本
n_features=2, # 包含2个特征,即生成二维数据
n_redundant=0, # 添加冗余特征0个
n_informative=2, # 包含信息的特征是2个
random_state=1, # 随机模式1
n_clusters_per_class=1 #每个簇内包含的标签类别有1个
)
# plt.scatter(x[:,0],x[:,1],label="原始数据",color='r')
# 散点图发现x中的特征 ,发现两个簇相距很远,数据集简单,测试分类器能力的效果不好,因此在数据集上加噪声。
rd = np.random.randn(x.shape[0],2)
x +=rd
# plt.scatter(x[:,0],x[:,1],label="加噪声数据",color='b')
dataset1 = (x,y)
dataset2 = make_moons(n_samples=100,noise=0.2,random_state=1)
dataset3 = make_circles(n_samples=100,noise=0.3,factor=0.5,random_state=1)
# 合并成dataSet
dataSet = [dataset1,dataset2,dataset3]
figure = plt.figure(num=1,figsize =(6, 9))
figTree= plt.figure(num=2,figsize =(12, 9))
i,j=1,1
3. 训练三组数据,并绘制树状图和三组模型的性能指标
画图初始化
# 创建画布句柄
figure = plt.figure(num=1,figsize =(6, 9))
figTree = plt.figure(num=2,figsize =(12, 9))
# 画图在subplot中的index
i,j=1,1
开始训练以及性能测试
for ds_index,ds in enumerate(dataSet):
x,y= ds
# 数据标准化处理 : (数据值-均值)/ 方差
# StandardScaler():
x = StandardScaler().fit_transform(x)
x_train,x_test,y_train,y_test = train_test_split(x,y,train_size=0.7,random_state=42)
"""
训练 【核心】
"""
DTree = tree.DecisionTreeClassifier(max_depth=5)
DTree.fit(x_train,y_train)
score = DTree.score(x_test,y_test)
"""
绘制树状图以及数据可视化
"""
# 计算 x1 x2 的边界 :在最大最小的值基础上加一个数
x1_min, x1_max = x[:, 0].min() - .2, x[:, 0].max() + .2
x2_min, x2_max = x[:, 1].min() - .2, x[:, 1].max() + .2
# meshgrid(x,y):将x中数据与y中的数据进行排列组合【x(1,2,3);y(2,3,4) --> (1,2)(1,3)(1,4)(2,2)...(3,4)】
array1, array2 = np.meshgrid(np.arange(x1_min, x1_max, 0.2),np.arange(x2_min, x2_max, 0.2))
'''
绘制树
'''
tr = figTree.add_subplot(len(dataSet),1,j)
tree.plot_tree(DTree,filled=True,rounded=True)
j+=1
'''
画数据集本身的图像
'''
ax = figure.add_subplot(len(dataSet), 2, i)
cm = plt.cm.RdBu
cm_bright = ListedColormap(['#FF0000', '#0000FF'])
if ds_index == 0:
ax.set_title("Input data")
ax.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=cm_bright, edgecolors='k')
ax.scatter(x_test [:, 0], x_test[:, 1], c=y_test , cmap=cm_bright, edgecolors='k', alpha=0.6)
# 需要设置坐标轴和绘制边界嘛?
# 绘制边界
i += 1
'''
画训练后的效果图
'''
ax = figure.add_subplot(len(dataSet),2,i)
# array1.ravel() : 将array1展开为一维
# np.c_(a,b) : 将a,b 中的所有元素进行点对点的组合【a(1,2,3)b(1,2,3)-->(1,1)(2,2)(3,3)】
# predict_proba(xdata) --> 返回此数据下每组数据对应每个类别的类概率【若xdata(i,j) 就代表xdata中第i组数据为j类别的概率为xx】
Z = DTree.predict_proba(np.c_[array1.ravel(), array2.ravel()])
# 将Z转成一维数组,与array1维数一致
Z = Z[:, 1].reshape(array1.shape)
cm = plt.cm.RdBu
# cm 是什么意思 cm = plt.cm.RdBu
# contourf(x,y,z)代表的是在(x,y)位置的值为 Z
ax.contourf(array1, array2, Z, cmap=cm, alpha=0.8)
cm_bright = ListedColormap(['#FF0000', '#0000FF'])
if ds_index == 0:
ax.set_title("Output data")
ax.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=cm, edgecolors='k')
ax.scatter(x_test [:, 0], x_test[:, 1], c=y_test, cmap=cm, edgecolors='k', alpha=0.6)
i+=1
# 得分显示
ax.text(array1.max()-.3,array2.min()+.3,("{:.2f}%".format(score*100)),size=15,horizontalalignment='right')
由于本人还是python小白这里整理一下demo中出现numpy或者matplot库中的函数,巩固一下:
- StandardScaler():数据标准化处理 : (数据值-均值)/ 方差
- meshgrid(x,y):将x中数据与y中的数据进行排列组合【x(1,2,3) ; y(2,3,4) --> (1,2)(1,3)(1,4)(2,2)…(3,4)】
- array1.ravel() : 将array1展开为一维
- np.c_(a,b) : 将a,b 中的所有元素进行点对点的组合【a(1,2,3) b(1,2,3) --> (1,1)(2,2)(3,3)】
- predict_proba(xdata) --> 返回此数据下每组数据对应每个类别的类概率【若xdata(i,j) 就代表xdata中第i组数据为j类别的概率为xx】
结果如下图所示:
可以看得出来:决策树在二维面(两个属性)分割策略是以线为依据进行划分分类的,所以对有重叠的二分数据以及在坐标系上以环行分布的数据的分类效果是不好的。