主要内容

分类

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

费雪虹膜数据

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

负载fisheririsF =数字;Gscatter (meas(:,1), meas(:,2), species,“rgb”osd的);包含(“花萼长度”);ylabel (萼片宽的);

图中包含一个轴对象。axis对象包含3个line类型的对象。这些物品代表了setosa, versicolica, virgica。

N = size(meas,1);

假设您测量了虹膜的萼片和花瓣,并需要根据这些测量结果确定其种类。解决这个问题的一种方法被称为判别分析。

线性与二次判别分析

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

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

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

ldaResubErr = resubLoss(lda)
ldaResubErr = 0.2000

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

图ldaResubCM =混淆图(物种,ldaClass);

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

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

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

图中包含一个轴对象。axis对象包含4个line类型的对象。这些物品代表了setosa, versicolica, virgica。

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

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

图中包含一个轴对象。axis对象包含3个line类型的对象。这些物品代表了彩绘、彩绘、维吉尼亚。

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

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

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

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

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

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

rng (0,“旋风”);

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

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

crossval而且kfoldLoss方法可以利用给定的数据分区估计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),种);nbGauResubErr = nbGau
nbGauResubErr = 0.2200
nbGauCV = crossval(nbGau,“CVPartition”, cp);nbGauCVErr = kfoldLoss(nbGauCV)
nbGauCVErr = 0.2200
标签=预测(nbGau, [x y]);gscatter (x, y,标签,“伽马线暴”‘草地’

图中包含一个轴对象。axis对象包含3个line类型的对象。这些物品代表了彩绘、彩绘、维吉尼亚。

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

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

图中包含一个轴对象。axis对象包含3个line类型的对象。这些物品代表了setosa, versicolica, virgica。

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

决策树

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

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

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

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

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

图中包含一个轴对象。axis对象包含3个line类型的对象。这些物品代表了彩绘、彩绘、维吉尼亚。

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

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

{

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

计算决策树的再替换误差和交叉验证误差。

dtResubErr = resubLoss(t)
dtResubErr = 0.1333
CVT =交叉val(t,“CVPartition”, cp);dtCVErr = kfoldLoss(cvt)
dtCVErr = 0.3000

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

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

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

图中包含一个轴对象。axis对象包含2个line类型的对象。这些对象表示交叉验证、替换。

你应该选择哪棵树?一个简单的规则是选择交叉验证错误最小的树。虽然这可能是令人满意的,但如果简单的树大致与更复杂的树一样好,您可能更喜欢使用简单的树。在这个例子中,取一个与最小值有一个标准误差的最简单的树。类使用的默认规则cvloss的方法ClassificationTree

你可以通过计算一个临界值来显示这一点,这个临界值等于最小成本加上一个标准误差。方法计算的“最佳”级别cvloss方法是该界限下最小的树。(注意,bestlevel=0对应于未修剪的树,所以您必须添加1来使用它作为从的向量输出的索引cvloss.)

[mincost,minloc] = min(成本);Cutoff = mincost + secost(minloc);持有Plot ([0 20], [cutoff cutoff],凯西:”(ntermnodes(bestlevel+1), cost(bestlevel+1),“莫”)传说(交叉验证的“Resubstitution”'Min + 1标准。err。'“最好的选择”)举行

图中包含一个轴对象。axis对象包含4个line类型的对象。这些对象表示交叉验证,重新替换,最小值+ 1标准。,最好的选择。

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

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

{

成本(bestlevel + 1)
Ans = 0.2467

结论

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

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