数据挖掘-实验二笔记(分类 Classification, 6.1 脊椎动物(Vertebrate)数据集,决策树/SVM)

import pandas as pd
data = pd.read_csv('vertebrate.csv',header='infer')
data

header='infer':此参数指示pandas应该从CSV文件的第一行推断列名。换句话说,CSV文件的第一行被视为包含列名的标题。        

data['Class'] = data['Class'].replace(['fishes','birds','amphibians','reptiles'],'non-mammals')
data

这段代码对data中的'Class'列进行了替换操作。具体来说,它使用replace方法将'fishes'、'birds'、'amphibians'和'reptiles'这些值替换为'non-mammals'。这意味着将这些类别中的动物都重新分类为非哺乳动物。

pd.crosstab([data['Warm-blooded'],data['Gives Birth']],data['Class'])

使用 Pandas交叉表 来检查“Warm-blooded”和“Gives Birth”属性与类别标签(是否为哺乳动物)之间的关系。

使用这两个属性就可以将哺乳动物与非哺乳动物区分开,因为它们的属性值的每种组合只会产生属于同一类的实例。 例如,哺乳动物可以被识别为温血且胎生的脊椎动物

  • Name(名称): 动物的名称
  • Warm-blooded(恒温): 是否是温血动物
  • Gives Birth(胎生): 是否是胎生动物
  • Aquatic Creature(水生生物): 是否是水生生物
  • Aerial Creature(空中生物): 是否是空中生物
  • Has Legs(有腿): 是否有腿
  • Hibernates(冬眠): 是否冬眠

这种关系也可以使用决策树分类器来推导,如下小节中的示例所示。

决策树分类器 Decision Tree Classifier

使用不同的“不纯度度量”策略训练决策树,并进行测试;使用不同的“最大深度”训练决策树,并进行测试

数据(iris.data)训练决策树并进行测试;可以将该数据的80%作为训练集,20%作为测试集

思考:

 1.观察使用不同配置的决策树的运行结果并进行分析。

 2.观察决策树在鸢尾花数据上的表现并进行分析。

from sklearn import tree

Y = data['Class']
# 从data中去掉Name和Class作为输入特征X
X = data.drop(['Name','Class'],axis=1)

clf = tree.DecisionTreeClassifier(criterion='entropy',max_depth=3)
clf = clf.fit(X, Y)

前面的命令将从脊椎动物数据集中提取预测变量(X)和目标类别(Y)属性,并使用熵作为分裂标准的不纯度度量(impurity measure)来创建决策树分类器。 Python sklearn库中的决策树类还支持使用 “gini” 作为不纯度度量。 上面的决策树分类器的最大深度被限制为3。接下来,使用fit()函数在标记的数据上训练分类器。我们可以绘制训练分类器后获得的结果决策树。

import pydotplus 
from IPython.display import Image

dot_data = tree.export_graphviz(clf, feature_names=X.columns, class_names=['mammals','non-mammals'], filled=True, 
                                out_file=None) 
graph = pydotplus.graph_from_dot_data(dot_data) 
Image(graph.create_png())

        

这段代码使用pydotplusIPython.display库,结合scikit-learntree模块,来可视化决策树模型。

  1. tree.export_graphviz: 这个函数用于生成决策树的可视化描述,它接受多个参数,包括:

    • clf: 这是你的决策树分类器(DecisionTreeClassifier)的实例。
    • feature_names: 特征的名称列表,用于标识决策树上的每个节点。
    • class_names: 目标类别的名称列表,用于标识每个类别。
    • filled=True: 这个参数表示是否要用颜色填充决策树节点,颜色的深浅表示类别的纯度或不纯度。
    • out_file=None: 这个参数表示不将可视化描述写入文件,而是返回该描述。
  2. pydotplus.graph_from_dot_data: 这个函数将export_graphviz生成的DOT格式的数据转换为图形,它接受一个DOT格式的字符串并返回一个pydotplus.graphviz.Dot对象。

  3. 最后,通过Image(graph.create_png())将图形显示在Jupyter Notebook中。graph.create_png()将返回图形的PNG格式的二进制数据,Image则将其显示在Notebook中。

要使这段代码工作,确保你已经正确安装了pydotplusIPythonscikit-learn。在运行代码之前,确保你已经拟合了一个决策树分类器(clf)并且你的特征矩阵(X)和目标向量是正确的。

创建了一个包含测试数据的DataFrame testData,其中列的顺序与原始数据的列相同。这个DataFrame 包含了一些动物的特征,如 Warm-bloodedGives BirthAquatic CreatureAerial CreatureHas LegsHibernates,以及它们的类别 (Class)。

 我还把之前鸢尾花的数据训练了一下。

import pydotplus 
from sklearn.tree import DecisionTreeClassifier, export_graphviz
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score, classification_report
from IPython.display import Image

# 加载数据
iris_data = pd.read_csv('iris.csv')

# 将特征和标签分开
X = iris_data.drop('species', axis=1)
y = iris_data['species']

# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 初始化并训练决策树模型
clf = DecisionTreeClassifier()
clf.fit(X_train, y_train)

# 可视化决策树
dot_data = export_graphviz(clf, out_file=None, 
                           feature_names=iris_data.columns[:-1].tolist(),  
                           class_names=iris_data['species'].unique(),  
                           filled=True, rounded=True, special_characters=True)  

graph = pydotplus.graph_from_dot_data(dot_data)  

# 保存决策树图像
graph.write_png('decision_tree.png')

# 在Notebook中显示决策树图像
Image(graph.create_png())

接下来,我们使用决策树对以下测试示例进行分类。 

testData = [['gila monster',0,0,0,0,1,1,'non-mammals'],
           ['platypus',1,0,0,0,1,1,'mammals'],
           ['owl',1,0,0,1,1,0,'non-mammals'],
           ['dolphin',1,1,1,0,0,0,'mammals']]
testData = pd.DataFrame(testData, columns=data.columns)
testData

显示如下:

这些数据与我们的原始数据类似,但是是用于测试模型的新数据。可以使用训练好的模型(例如 clf)对这些数据进行预测,然后评估模型在测试数据上的性能。

testY = testData['Class']
testX = testData.drop(['Name','Class'],axis=1)

predY = clf.predict(testX)
predictions = pd.concat([testData['Name'],pd.Series(predY,name='Predicted Class')], axis=1)
predictions

创建了一个 testY Series,其中包含测试数据的实际类别(ground truth),而 testX DataFrame 包含了测试数据的特征。接着,使用训练好的决策树模型 clftestX 进行预测,得到了预测的类别 predY

最后,将测试数据的名称('Name' 列)和模型的预测类别('Predicted Class' 列)合并成一个DataFrame predictions。这个DataFrame显示了每个动物的名称以及模型对其类别的预测。

这个DataFrame显示了每个动物的真实类别和模型的预测类别,可以用来评估模型在测试数据上的性能。如果真实类别和预测类别匹配,说明模型对这些样本的预测是正确的。

除了鸭嘴兽(platypus)是卵生哺乳动物外,分类器可以正确预测测试示例的类别标签。 我们可以根据测试数据的结果计算分类器的准确性,如下例所示。

from sklearn.metrics import accuracy_score

print('Accuracy on test data is %.2f' % (accuracy_score(testY, predY)))

Accuracy on test data is 0.75

模型过拟合 Model Overfitting

为了说明模型过度拟合的问题,我们考虑一个二维数据集,其中包含1500个带类别标签(class label)的实例,每个实例被分配给两个类别(0或1)中的一个。每个类别的实例生成如下:      

1. 来自类别1的实例是由3个高斯分布的混合生成的,其中,这三个高斯分布分别以[6,14],[10,6]和[14 14]为中心。

2. 来自类别0的实例由正方形区域中的均匀分布生成,该正方形区域的边长等于20。

import numpy as np
import matplotlib.pyplot as plt
from numpy.random import random

%matplotlib inline

N = 1500
mean1 = [6, 14]
mean2 = [10, 6]
mean3 = [14, 14]
cov = [[3.5, 0], [0, 3.5]]  # diagonal covariance

np.random.seed(50)
X = np.random.multivariate_normal(mean1, cov, int(N/6))
X = np.concatenate((X, np.random.multivariate_normal(mean2, cov, int(N/6))))
X = np.concatenate((X, np.random.multivariate_normal(mean3, cov, int(N/6))))
X = np.concatenate((X, 20*np.random.rand(int(N/2),2)))
Y = np.concatenate((np.ones(int(N/2)),np.zeros(int(N/2))))

plt.plot(X[:int(N/2),0],X[:int(N/2),1],'r+',X[int(N/2):,0],X[int(N/2):,1],'k.',ms=4)

因此,整体上这行代码绘制了一个散点图,其中红色加号表示第一类别的数据,黑色点表示第二类别的数据。这种表示方式是为了在散点图中区分不同的类别。

  • N 是生成的数据点总数。
  • mean1mean2mean3 是三个正态分布的均值。
  • cov 是一个对角协方差矩阵,用于生成正态分布的数据
  • 使用 np.random.multivariate_normal 生成带有不同均值的正态分布数据。
  • np.concatenate 用于将生成的数据合并成一个数组
  • 有三个均值 mean1mean2mean3,每个均值生成 250 个数据点,总共生成 750 个数据点。
  • plt.plot(X[:int(N/2), 0], X[:int(N/2), 1], 'r+', ...)

    • 绘制红色加号 ('r+') 的点,表示第一类别的数据。
    • X[:int(N/2), 0] 表示取前半部分数据的第一列,即 x 坐标。
    • X[:int(N/2), 1] 表示取前半部分数据的第二列,即 y 坐标。
  • plt.plot(..., X[int(N/2):, 0], X[int(N/2):, 1], 'k.', ms=4)

    • 绘制黑色点 ('k.'),表示第二类别的数据。
    • X[int(N/2):, 0] 表示取后半部分数据的第一列,即 x 坐标。
    • X[int(N/2):, 1] 表示取后半部分数据的第二列,即 y 坐标。
  • ms=4 表示设置点的大小(marker size)为 4

在此示例中,我们保留了80%的数据用于训练,其余20%的数据用于测试。 然后,我们将使用具有不同最大深度(从2到50)的决策树拟合训练集,并将其在测试集上的精度绘制出来。

#########################################
# Training and Test set creation
#########################################

from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.8, random_state=1)

from sklearn import tree
from sklearn.metrics import accuracy_score

#########################################
# Model fitting and evaluation
#########################################

maxdepths = [2,3,4,5,6,7,8,9,10,15,20,25,30,35,40,45,50]

trainAcc = np.zeros(len(maxdepths))
testAcc = np.zeros(len(maxdepths))

index = 0
for depth in maxdepths:
    clf = tree.DecisionTreeClassifier(max_depth=depth)
    clf = clf.fit(X_train, Y_train)
    Y_predTrain = clf.predict(X_train)
    Y_predTest = clf.predict(X_test)
    trainAcc[index] = accuracy_score(Y_train, Y_predTrain)
    testAcc[index] = accuracy_score(Y_test, Y_predTest)
    index += 1
    
#########################################
# Plot of training and test accuracies
#########################################
    
plt.plot(maxdepths,trainAcc,'ro-',maxdepths,testAcc,'bv--')
plt.legend(['Training Accuracy','Test Accuracy'])
plt.xlabel('Max depth')
plt.ylabel('Accuracy')

 

其他分类技术 Alternative Classification Techniques

除决策树分类器外,Python sklearn库还支持其他分类技术。 在本节中,我们提供示例来说明如何将k最近邻分类器、线性分类器(逻辑回归和支持向量机)以及集成方法(增强boosting,装袋bagging和随机森林random forest)应用于上一节的二维数据上。

3.4.1 K最近邻分类器 K-Nearest neighbor classifier

在这种方法中,将基于与测试实例最接近的 *k* 个训练实例的多数类来预测其实例标签。 最近邻居的数量 *k* 以及距离度量策略是用户必须提供的超参数。默认情况下,我们可以使用欧几里得距离(它等价于指数因子p=2的Minkowski距离):

from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
%matplotlib inline

numNeighbors = [1, 5, 10, 15, 20, 25, 30]
trainAcc = []
testAcc = []

for k in numNeighbors:
    clf = KNeighborsClassifier(n_neighbors=k, metric='minkowski', p=2)
    clf.fit(X_train, Y_train)
    Y_predTrain = clf.predict(X_train)
    Y_predTest = clf.predict(X_test)
    trainAcc.append(accuracy_score(Y_train, Y_predTrain))
    testAcc.append(accuracy_score(Y_test, Y_predTest))

plt.plot(numNeighbors, trainAcc, 'ro-', numNeighbors, testAcc,'bv--')
plt.legend(['Training Accuracy','Test Accuracy'])
plt.xlabel('Number of neighbors')
plt.ylabel('Accuracy')

3.4.2 线性分类器 Linear Classifiers

from sklearn import linear_model
from sklearn.svm import SVC

C = [0.01, 0.1, 0.2, 0.5, 0.8, 1, 5, 10, 20, 50]
LRtrainAcc = []
LRtestAcc = []
SVMtrainAcc = []
SVMtestAcc = []

for param in C:
    clf = linear_model.LogisticRegression(C=param)
    clf.fit(X_train, Y_train)
    Y_predTrain = clf.predict(X_train)
    Y_predTest = clf.predict(X_test)
    LRtrainAcc.append(accuracy_score(Y_train, Y_predTrain))
    LRtestAcc.append(accuracy_score(Y_test, Y_predTest))

    clf = SVC(C=param,kernel='linear')
    clf.fit(X_train, Y_train)
    Y_predTrain = clf.predict(X_train)
    Y_predTest = clf.predict(X_test)
    SVMtrainAcc.append(accuracy_score(Y_train, Y_predTrain))
    SVMtestAcc.append(accuracy_score(Y_test, Y_predTest))

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12,6))
ax1.plot(C, LRtrainAcc, 'ro-', C, LRtestAcc,'bv--')
ax1.legend(['Training Accuracy','Test Accuracy'])
ax1.set_xlabel('C')
ax1.set_xscale('log')
ax1.set_ylabel('Accuracy')

ax2.plot(C, SVMtrainAcc, 'ro-', C, SVMtestAcc,'bv--')
ax2.legend(['Training Accuracy','Test Accuracy'])
ax2.set_xlabel('C')
ax2.set_xscale('log')
ax2.set_ylabel('Accuracy')

 3.4.3 非线性支持向量机 Nonlinear Support Vector Machine

from sklearn.svm import SVC

C = [0.01, 0.1, 0.2, 0.5, 0.8, 1, 5, 10, 20, 50]
SVMtrainAcc = []
SVMtestAcc = []

for param in C:
    clf = SVC(C=param,kernel='rbf',gamma='auto')
    clf.fit(X_train, Y_train)
    Y_predTrain = clf.predict(X_train)
    Y_predTest = clf.predict(X_test)
    SVMtrainAcc.append(accuracy_score(Y_train, Y_predTrain))
    SVMtestAcc.append(accuracy_score(Y_test, Y_predTest))

plt.plot(C, SVMtrainAcc, 'ro-', C, SVMtestAcc,'bv--')
plt.legend(['Training Accuracy','Test Accuracy'])
plt.xlabel('C')
plt.xscale('log')
plt.ylabel('Accuracy')

 3.4.4 集成方法 Ensemble Methods

集成分类器根据训练数据构建一组基础分类器,并通过对每个基础分类器做出的预测进行投票来执行分类。 在此示例中,我们考虑了三种集成分类器:装袋(bagging)、增强(boosting)和随机森林(random forest)。

在下面的示例中,我们使用每种集成方法将500个基本分类器拟合到二维数据集。 基本分类器是一个最大深度为10的决策树。

from sklearn import ensemble
from sklearn.tree import DecisionTreeClassifier

numBaseClassifiers = 500
maxdepth = 10
trainAcc = []
testAcc = []

clf = ensemble.RandomForestClassifier(n_estimators=numBaseClassifiers)
clf.fit(X_train, Y_train)
Y_predTrain = clf.predict(X_train)
Y_predTest = clf.predict(X_test)
trainAcc.append(accuracy_score(Y_train, Y_predTrain))
testAcc.append(accuracy_score(Y_test, Y_predTest))

clf = ensemble.BaggingClassifier(DecisionTreeClassifier(max_depth=maxdepth),n_estimators=numBaseClassifiers)
clf.fit(X_train, Y_train)
Y_predTrain = clf.predict(X_train)
Y_predTest = clf.predict(X_test)
trainAcc.append(accuracy_score(Y_train, Y_predTrain))
testAcc.append(accuracy_score(Y_test, Y_predTest))

clf = ensemble.AdaBoostClassifier(DecisionTreeClassifier(max_depth=maxdepth),n_estimators=numBaseClassifiers)
clf.fit(X_train, Y_train)
Y_predTrain = clf.predict(X_train)
Y_predTest = clf.predict(X_test)
trainAcc.append(accuracy_score(Y_train, Y_predTrain))
testAcc.append(accuracy_score(Y_test, Y_predTest))

methods = ['Random Forest', 'Bagging', 'AdaBoost']
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12,6))
ax1.bar([1.5,2.5,3.5], trainAcc)
ax1.set_xticks([1.5,2.5,3.5])
ax1.set_xticklabels(methods)
ax2.bar([1.5,2.5,3.5], testAcc)
ax2.set_xticks([1.5,2.5,3.5])
ax2.set_xticklabels(methods)

  • 29
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值