主要内容

分类

这个例子展示了如何使用判别分析、朴素贝叶斯分类器和决策树进行分类。假设您有一个数据集,其中包含对不同变量(称为预测器)及其已知类标签的测量结果。如果你获得了新观测值的预测值,你能确定这些观测值可能属于哪一类吗?这就是分类的问题。

费雪的虹膜数据

Fisher的虹膜数据包括对150个虹膜标本的萼片长度、萼片宽度、花瓣长度和花瓣宽度的测量。三个物种各有50个样本。载入数据,看看不同物种间萼片的测量值有何不同。您可以使用包含萼片测量值的两列。

负载fisheririsf =图;gscatter(量(:1)量(:,2),物种,“rgb”osd的);包含(“花萼长度”);ylabel (萼片宽的);

图中包含一个轴对象。轴对象包含3个类型为line的对象。这些物品代表着维珍卡。

1) N =大小(量;

假设你测量了一朵鸢尾的萼片和花瓣,你需要根据这些测量来确定它的种类。解决这个问题的一种方法是判别分析。

线性和二次判别分析

fitcdiscr函数可以使用不同类型的判别分析进行分类。首先使用默认的线性判别分析(LDA)对数据进行分类。

lda = fitcdiscr(量(:,1:2),物种);ldaClass = resubPredict (lda);

具有已知类标签的观察结果通常称为训练数据。现在计算再替换误差,即训练集上的误分类误差(误分类观测值的比例)。

ldaResubErr = resubLoss (lda)
ldaResubErr = 0.2000

您还可以在训练集中计算混淆矩阵。混淆矩阵包含关于已知类标签和预测类标签的信息。一般来说,混淆矩阵中的(i,j)元素是已知类标为i类,预测类为j类的样本个数。对角线元素表示正确分类的观测值。

图ldaResubCM = confusionchart(species,ldaClass);

Figure包含一个confusimatrixchart类型的对象。

在150个训练观测值中,20%或30个观测值被线性判别函数误分类。你可以通过在错误分类的点上画X来看出它们是哪些。

图(f) bad = ~strcmp(ldaClass,species);持有;情节(量(坏,1),量(坏,2),“kx”);持有

图中包含一个轴对象。轴对象包含4个类型为line的对象。这些物品代表着维珍卡。

该功能将平面划分为以线划分的区域,并将不同的区域分配给不同的物种。可视化这些区域的一种方法是创建一个网格(x, y)值,并将分类功能应用于该网格。

(x, y) = meshgrid (4: .1:8, 2: .1:4.5);x = x (:);y = y (:);J = classify([x y],meas(:,1:2),species);gscatter (x, y, j,“伽马线暴”‘草地’

图中包含一个轴对象。轴对象包含3个类型为line的对象。这些物品代表着花斑,塞托萨,维吉尼亚。

对于一些数据集,不同类的区域没有很好地用行分隔。在这种情况下,线性判别分析是不合适的。相反,您可以尝试对数据进行二次判别分析(QDA)。

计算二次判别分析的再代换误差。

qda = fitcdiscr(量(:,1:2),物种,“DiscrimType”“二次”);qdaResubErr = resubLoss (qda)
qdaResubErr = 0.2000

您已经计算出了重新替换错误。通常人们更感兴趣的是测试误差(也称为泛化误差),即独立集上的预期预测误差。事实上,重新替换错误可能会低估测试错误。

在本例中,您没有另一个标记数据集,但是您可以通过进行交叉验证来模拟一个标记数据集。分层十倍交叉验证是估计分类算法测试误差的常用方法。它将训练集随机分成10个不相交的子集。每个子集的大小和类的比例与训练集中大致相同。删除一个子集,使用其他9个子集训练分类模型,并使用训练的模型对删除的子集进行分类。您可以通过每次删除一个子集来重复此操作。

由于交叉验证对数据进行随机划分,其结果取决于初始的随机种子。要在本例中重现准确的结果,执行以下命令:

rng (0,“旋风”);

第一次使用cvpartition生成10个不相交的分层子集。

cp = cvpartition(物种,“KFold”, 10)
cp = K-fold交叉验证分区nummobations: 150 NumTestSets: 10 TrainSize: 135 135 135 135 135 135 TestSize: 15 15 15 15 15 15 15 15

crossvalkfoldLoss方法可以利用给定的数据分区估计LDA和QDA的误分类误差cp

使用10倍分层交叉验证估计LDA的真检验误差。

cvlda = crossval (lda,“CVPartition”, cp);ldaCVErr = kfoldLoss (cvlda)
ldaCVErr = 0.2000

LDA交叉验证错误与此数据上的LDA重新替换错误具有相同的值。

使用10倍分层交叉验证估计QDA的真检验误差。

cvqda = crossval (qda,“CVPartition”, cp);qdaCVErr = kfoldLoss (cvqda)
qdaCVErr = 0.2200

QDA的交叉验证错误略大于LDA。这表明一个简单的模型可能比一个更复杂的模型具有可比性或更好的性能。

朴素贝叶斯分类器

fitcdiscr函数还有另外两种类型,“DiagLinear”“DiagQuadratic”。它们类似于“线性”“二次”,但用对角协方差矩阵估计。这些对角线选择是朴素贝叶斯分类器的具体例子,因为它们假定给定类标签的变量是有条件独立的。朴素贝叶斯分类器是最流行的分类器之一。虽然变量之间的类条件独立的假设在一般情况下是不正确的,但朴素贝叶斯分类器在许多数据集的实践中工作得很好。

fitcnb函数可用于创建更一般的朴素贝叶斯分类器类型。

首先使用高斯分布对每个类中的每个变量进行建模。您可以计算重新替换错误和交叉验证错误。

nbGau = fitcnb(meas(:,1:2), species);nbGauResubErr = resubLoss (nbGau)
nbGauResubErr = 0.2200
nbGauCV = crossval (nbGau,“CVPartition”, cp);nbGauCVErr = kfoldLoss (nbGauCV)
nbGauCVErr = 0.2200
标签= predict(nbGau, [x y]);gscatter (x, y,标签,“伽马线暴”‘草地’

图中包含一个轴对象。轴对象包含3个类型为line的对象。这些物品代表着花斑,塞托萨,维吉尼亚。

到目前为止,你已经假设每个类中的变量都是多元正态分布。通常这是一个合理的假设,但有时你可能不愿意做出这样的假设,或者你可能清楚地看到它不是有效的。现在尝试用核密度估计对每个类中的每个变量建模,这是一种更灵活的非参数技术。这里我们将内核设置为盒子

nbKD = fitcnb(meas(:,1:2),种,“DistributionNames”“内核”“内核”“盒子”);nbKDResubErr = resubLoss (nbKD)
nbKDResubErr = 0.2067
nbKDCV = crossval (nbKD,“CVPartition”, cp);nbKDCVErr = kfoldLoss (nbKDCV)
nbKDCVErr = 0.2133
标签=预测(nbKD, [x y]);gscatter (x, y,标签,“rgb”osd的

图中包含一个轴对象。轴对象包含3个类型为line的对象。这些物品代表着维珍卡。

对于该数据集,核密度估计的朴素贝叶斯分类器比高斯分布的朴素贝叶斯分类器得到更小的再替代误差和交叉验证误差。

决策树

另一种分类算法是基于决策树。决策树是一组简单的规则,比如“如果萼片长度小于5.45,则将样本分类为簇状。”决策树也是非参数的,因为它们不需要任何关于变量在每个类中的分布的假设。

fitctree函数创建决策树。为虹膜数据创建一个决策树,看看它如何很好地将虹膜分类为不同的物种。

T = fitctree(meas(:,1:2), species,“PredictorNames”, {“SL”“西南”});

看看决策树方法如何划分平面是很有趣的。使用上述相同的技术来可视化分配给每个物种的区域。

[grpname,node] = predict(t,[x y]);grpname gscatter (x, y,“伽马线暴”‘草地’

图中包含一个轴对象。轴对象包含3个类型为line的对象。这些物品代表着花斑,塞托萨,维吉尼亚。

另一种可视化决策树的方法是绘制决策规则和类分配的图。

视图(t)“模式”“图”);

图分类树查看器包含一个轴对象和其他类型的uimenu, uicontrol对象。axis对象包含60个类型为line, text的对象。

这个杂乱的树使用“SL < 5.45”形式的一系列规则将每个样本分类为19个终端节点中的一个。要确定观察的物种分配,从顶部节点开始并应用该规则。如果点满足规则,你就走左边的路,如果不满足,你就走右边的路。最终,您到达一个终端节点,该节点将观察分配给三种物种中的一种。

计算决策树的重新替换错误和交叉验证错误。

dtResubErr = resubLoss (t)
dtResubErr = 0.1333
cvt = crossval (t)“CVPartition”, cp);dtCVErr = kfoldLoss (cvt)
dtCVErr = 0.3000

对于决策树算法,交叉验证误差估计明显大于再替换误差。这表明生成的树过拟合了训练集。换句话说,这是一棵能够很好地分类原始训练集的树,但是树的结构对这个特定的训练集很敏感,所以它在新数据上的性能很可能会下降。在新数据上,通常可以找到比复杂的树执行得更好的更简单的树。

试着把树修剪一下。首先计算原始树的各个子集的重新替换错误。然后计算这些子树的交叉验证错误。图表显示,再替换错误过于乐观。它总是随着树的大小增长而减小,但超过某一点,增加树的大小会增加交叉验证的错误率。

resubcost = resubLoss (t)“子树”“所有”);(成本、secost ntermnodes bestlevel] = cvloss (t)“子树”“所有”);情节(ntermnodes、成本“b -”ntermnodes resubcost,“r——”)图(gcf);包含('终端节点数');ylabel (“成本(误分类错误)”)传说(交叉验证的“Resubstitution”

图中包含一个轴对象。轴对象包含两个类型为line的对象。这些对象表示交叉验证,重新替换。

你应该选择哪棵树?一个简单的规则是选择交叉验证错误最小的树。虽然这可能令人满意,但如果简单的树和复杂的树差不多,您可能更喜欢使用简单的树。对于本例,取最简单的树,它在最小值的一个标准误差范围内。的默认规则cvloss的方法ClassificationTree

你可以通过计算一个截止值来显示这一点,这个截止值等于最小成本加上一个标准误差。“最佳”水平的计算cvloss方法是这个截断下最小的树。(注意,bestlevel=0对应的是未修剪的树,因此必须添加1才能将其作为从向量输出的索引cvloss。)

[mincost, minloc] = min(成本);Cutoff = mincost + secost(minloc);持有地块([0 20],[截止点],凯西:”)情节(ntermnodes (bestlevel + 1)、成本(bestlevel + 1),“莫”)传说(交叉验证的“Resubstitution”'Min + 1 st. err '“最好的选择”)举行

图中包含一个轴对象。轴对象包含4个类型为line的对象。这些对象表示交叉验证、重新替换、Min + 1 st. err。,最好的选择。

最后,您可以查看修剪过的树,并计算它的估计误分类误差。

pt =修剪(t)“水平”, bestlevel);视图(pt,“模式”“图”

图分类树查看器包含一个轴对象和其他类型的uimenu, uicontrol对象。axis对象包含18个类型为line, text的对象。

成本(bestlevel + 1)
ans = 0.2467

结论

这个例子展示了如何在MATLAB®中使用统计学和机器学习工具箱™函数进行分类。

这个例子并不是对Fisher虹膜数据的理想分析,事实上,使用花瓣测量代替,或在萼片测量的基础上,可能会导致更好的分类。此外,本示例并不是要比较不同分类算法的优缺点。您可能会发现,对其他数据集进行分析并比较不同的算法具有指导意义。还有实现其他分类算法的工具箱函数。例如,你可以用TreeBagger执行决策树集合的引导聚合,如示例中所述使用TreeBagger分类树的Bootstrap聚集(Bagging)