决策树可视化及模型评估 SE SP AUC

目录
2.1 决策树
2.1.1 样本数据集
2.1.2 决策树可视化
2.2 模型分类性能预测
2.2.1 模型稳定性
2.2.2 SE、SP、ACC分类性能预测
# 代码实现
2.1 决策树 2.1.1 样本数据集
本次决策树的构建使用总为样本数据351,其中男生样本数量为283,女生样本数量为68;训练集样本数量为245,测试集样本数量为106;其中测试集约占样本总数的30% 。
2.1.2 决策树可视化
2.2 模型分类性能预测 2.2.1 模型稳定性
性能度量是衡量模型泛化能力的评价标准,反映了任务需求;使用不同的性能度量往往会导致不同的评判结果 。
首先,利用score(),输入测试样本的数据和标签,返回经过测试样本预测后模型的分类score;

决策树可视化及模型评估 SE SP AUC

文章插图
第二步:得到分数后,再做十次交叉验证,看模型的稳定性 。利用 中的函数进行交叉验证,输入数据特征与数据标签,这里cv设置为10,进行十次交叉验证,返回测试分数也是0.8019,由此可知模型稳定性良好;
list
Score
测试集
0.8019
十次交叉验证
0.8019
调整树深
0.8063
第三步:调整参数,这里主要针对决策树的深度,为了看看到底是过拟合还是欠拟合,这里我们把训练集和测试集的表现都比较一下 。由表2.2.1得知结果为0.8063,从图2.2.1 可以看到是有过拟合的倾向 。
2.2.2 SE、SP、ACC分类性能预测
本次预测任务,使用决策树中的函数(),对测试集的106个样本进行预测,返回样本的预测标签 。根据测试集的真实标记与预测结果计算样本的评价指标TP、TN、FP、FN,然后在算出SE、SP、ACC等评价指标 。
列表如下,其中1代表正类,0代表负类:
其中,TP 表示预测正确的正样本;TN 表示预测正确的负样本;FP 表示预测错误的负样本 ;FN表示预测错误的正样本 。
敏感性(SE)=TP/(TP+FN) #tpr
特异性(SP)=TN/(TN+FP) # tnr=1-fpr
准确率(ACC)=(TP+TN)/(TP+FP+TN+FN)
【决策树可视化及模型评估 SE SP AUC】模型预测性能如表4
敏感性SE
特异性SP
准确率ACC
0.942
0.300
0.821
表 4 决策树分类性能评估
从表中可知,由ACC准确率可知,能够被正确预测的样本高达总数的82.1%;由敏感性SE可知,该模型对男生(正样本)的预测正确率高达94.2%;而由特异性SP可知,该模型对女生(负样本)的分类正确率只有30%,这可能是在模型训练的过程中,女生(负样本)数量过少,导致训练的模型不够准确,因而正确率不高 。
# 代码实现
from sklearn.tree import DecisionTreeClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.model_selection import GridSearchCVfrom sklearn.model_selection import cross_val_scoreimport matplotlib.pyplot as pltimport math'''/**************************task1**************************/2. 实现基于信息增益率进行划分选择的决策树算法,对男女生样本数据中的(喜欢颜色,喜欢运动,喜欢文学)3 个特征进行分类,计算模型预测性能(包含 SE敏感性=TP/(TP+FN)、SP特异性=TN/(TN+FP)、ACC=right/all=(TP+TN)/(TP+FP+TN+FN),并以友好的方式图示化结果1.构建树步骤(数据处理 。。知乎) 分类图 2.预测性能/**************************task1**************************/'''import pandas as pdimport numpy as npdata = http://www.kingceram.com/post/pd.read_csv('data_favorite.txt', header=0, sep=' ')# data.dropna(how='any', inplace=True)# type(data)--pandas.core.frame.DataFrame# 处理非数字data["color"] = pd.factorize(data["color"])[0].astype(np.uint16)# print(data)# 拆分数据# 先把数据和标签拆分,X = data.iloc[:, data.columns != "sex"]y = data.iloc[:, data.columns == "sex"]# 首先将pandas读取的数据转化为arrayX = np.array(X)y = np.array(y)# 然后按经典的三七分,把数据拆分 。由于是随机抽取的,所以索引是乱的 。from sklearn.model_selection import train_test_splitXtrain, Xtest, Ytrain, Ytest = train_test_split(X, y, test_size=0.3)# print('Xtrain:',Xtrain)# print('Xtest:', Xtest)# print('Ytrain:',Ytrain)# print('Ytest:', Ytest)print(len(Xtrain))print(len(Xtest))# 修正测试集和训练集的索引'''for i in [Xtrain, Xtest, Ytrain, Ytest]:i.index = range(i.shape[0])'''# 训练模型 。得到分数后,再做十次交叉验证,看看模型的稳定性clf = DecisionTreeClassifier(random_state=25)clf = clf.fit(Xtrain, Ytrain)#根据真实值和预测值计算评价指标def performance(labelArr, predictArr):# 样本一定要是数组narray类型 类标签为1,0 # labelArr[i]真实的类别,predictArr[i]预测的类别# labelArr[i] is actual value,predictArr[i] is predict valueTP = 0.; TN = 0.; FP = 0.; FN = 0.for i in range(len(labelArr)):if labelArr[i] == 1 and predictArr[i] == 1:TP += 1.elif labelArr[i] == 1 and predictArr[i] == 0:FN += 1.elif labelArr[i] == 0 and predictArr[i] == 1:FP += 1.elif labelArr[i] == 0 and predictArr[i] == 0:TN += 1.SE = TP / (TP + FN)# Sensitivity = TP/Pand P = TP + FNSP = TN / (FP + TN) # Specificity = TN/Nand N = TN + FP# MCC = (TP * TN - FP * FN) / math.sqrt((TP + FP) * (TP + FN) * (TN + FP) * (TN + FN))ACC = (TP + TN) / (TP + TN + FP + FN)return SE, SP, ACCpredict_label = clf.predict(Xtest)print(predict_label)# print(type(predict_label))print('Ytest:', Ytest)# print(type(Ytest))print(performance(Ytest, predict_label))# 测试集特征经过决策树判断出的标签与测试集实际标签输入performancescore_ = clf.score(Xtest, Ytest)print('训练测试的分数:', score_)# 进行十次交叉验证# 进行十次交叉验证score = cross_val_score(clf, X, y, cv=10).mean()print('进行十次交叉验证:', score_)# 调整参数# 先从max_depth开始调,为了看看到底是过拟合还是欠拟合,最好还是把训练集和测试集的表现都比较一下 。tr = []te = []for i in range(10):clf = DecisionTreeClassifier(random_state=25, max_depth=i+1,criterion="entropy")clf = clf.fit(Xtrain, Ytrain)score_tr = clf.score(Xtrain,Ytrain)score_te = cross_val_score(clf,X,y,cv=10).mean()tr.append(score_tr)te.append(score_te)print(max(te))plt.plot(range(1,11),tr,color="red",label="train")plt.plot(range(1,11),te,color="blue",label="test")plt.xticks(range(1,11))plt.legend()plt.title('Train-Test Accuracy')plt.savefig(" Decision Tree Train-test Accuracy")plt.show()''''''from sklearn import treetree.plot_tree(clf)plt.show()# 可视化决策树import graphvizclf = DecisionTreeClassifier(random_state=25, max_depth=i+1, criterion="entropy")clf = clf.fit(Xtrain, Ytrain)tree.export_graphviz(clf, out_file='tree.dot')data_feature_names = ['color', 'sports', 'literature']# Visualize datadot_data = http://www.kingceram.com/post/tree.export_graphviz(clf,out_file=None,feature_names=data_feature_names,class_names=['girl', 'boy'],filled=True,rounded=True,special_characters=True)import pydotplusgraph = pydotplus.graph_from_dot_data(dot_data)colors = ('turquoise', 'orange')import collectionsedges = collections.defaultdict(list)for edge in graph.get_edge_list():edges[edge.get_source()].append(int(edge.get_destination()))for edge in edges:edges[edge].sort()for i in range(2):dest = graph.get_node(str(edges[edge][i]))[0]dest.set_fillcolor(colors[i])graph.write_png('tree.png')