朴素贝叶斯分类器,判别分析的准确性尚待完善

问题描述 投票:8回答:5

所以我有两种分类方法,判别分析diaglinear分类(朴素贝叶斯)和在matlab中实现的纯朴素贝叶斯分类器,整个数据集中有23个类。第一种方法判别分析:

%% Classify Clusters using Naive Bayes Classifier and classify
training_data = Testdata; 
target_class = TestDataLabels;

[class, err]  = classify(UnseenTestdata, training_data, target_class,'diaglinear')

cmat1 = confusionmat(UnseenTestDataLabels, class);
acc1 = 100*sum(diag(cmat1))./sum(cmat1(:));
fprintf('Classifier1:\naccuracy = %.2f%%\n', acc1);
fprintf('Confusion Matrix:\n'), disp(cmat1)

81.49%的混淆矩阵中获得准确性,错误率(err)为0.5040(不确定如何解释)。

第二种方法朴素贝叶斯分类器:

%% Classify Clusters using Naive Bayes Classifier
training_data = Testdata; 
target_class = TestDataLabels;
%# train model
nb = NaiveBayes.fit(training_data, target_class, 'Distribution', 'mn');

%# prediction
class1 = nb.predict(UnseenTestdata); 

%# performance
cmat1 = confusionmat(UnseenTestDataLabels, class1);
acc1 = 100*sum(diag(cmat1))./sum(cmat1(:));
fprintf('Classifier1:\naccuracy = %.2f%%\n', acc1);
fprintf('Confusion Matrix:\n'), disp(cmat1)

精度为81.89%

我只做过一轮交叉验证,我是matlab的新手,并且是有监督/无监督算法,所以我自己进行了交叉验证。我基本上只是拿走10%的数据,并留作测试之用,因为每次都是随机设置的。我可以经过几次测试并获得平均准确度,但是结果只是出于解释目的。

所以是我的问题。

在我对当前方法的文献综述中,许多研究人员发现,将单个分类算法与聚类算法混合使用会产生更好的准确性结果。他们通过找到适合其数据的最佳簇数,然后使用分区簇(应该比不相似)通过分类算法来运行每个单独的簇,从而做到这一点。您可以在其中结合使用无监督算法的最佳部分和有监督分类算法的过程。

现在,我正在使用一个在文献中已被多次使用的数据集,而我正在尝试一种与其他人不太相似的方法。

我首先使用简单的K-Means聚类,这令人惊讶地具有很好的聚类数据的能力。输出看起来像这样:

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9HUEN6Ui5qcGcifQ==” alt =“在此处输入图像描述”>

查看每个群集(K1,K2 ... K12)的类标签:

%% output the class labels of each cluster
K1 = UnseenTestDataLabels(indX(clustIDX==1),:)

我发现,每个集群在9个集群中主要都有一个类别标签,而3个集群则包含多个类别标签。表明K均值非常适合数据。

问题但是一旦我有了每个群集数据(cluster1,cluster2 ... cluster12):

%% output the real data of each cluster
cluster1 = UnseenTestdata(clustIDX==1,:)

而且我将每个聚类都通过朴素的贝叶斯或判别分析,例如:

class1  = classify(cluster1, training_data, target_class, 'diaglinear');
class2  = classify(cluster2, training_data, target_class, 'diaglinear');
class3  = classify(cluster3, training_data, target_class, 'diaglinear');
class4  = classify(cluster4, training_data, target_class, 'diaglinear');
class5  = classify(cluster5, training_data, target_class, 'diaglinear');
class6  = classify(cluster6, training_data, target_class, 'diaglinear');
class7  = classify(cluster7, training_data, target_class, 'diaglinear');
class8  = classify(cluster8, training_data, target_class, 'diaglinear');
class9  = classify(cluster9, training_data, target_class, 'diaglinear');
class10  = classify(cluster10, training_data, target_class, 'diaglinear'); 
class11  = classify(cluster11, training_data, target_class, 'diaglinear');
class12  = classify(cluster12, training_data, target_class, 'diaglinear');

精度变得令人震惊,将50%的聚类分类为0%准确性,每个分类的聚类(acc1,acc2,... acc12)都有自己对应的混淆矩阵,您可以在此处查看每个聚类的准确性:

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9BTnRYMi5qcGcifQ==” alt =“在此处输入图像描述”>“ >>

所以我的问题/问题是:我哪里出问题了?我首先想到也许我混合了群集的数据/标签,但是上面发布的内容看起来是正确的,我看不到任何问题。

为什么在第一个实验中使用的数据与完全看不见的10%数据完全相同,而对于相同的看不见的聚类数据却产生了如此奇怪的结果?我的意思是应该注意的是,NB是一个稳定的分类器,不应该轻易过度拟合,并且鉴于训练数据庞大,而要分类的集群却是并发过度拟合,这是不应该的?

编辑:

根据评论的请求,我包括第一个测试示例的cmat文件,该文件的准确性为81.49%

,而err为[[0.5040:]]“在此处输入图像描述”

还要求提供此示例中的K,class和相关cmat的摘要,精度为

3.03%

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9EcHZqTC5qcGcifQ==” alt =“在此处输入图像描述”>

[好像有很多类(总共23个),我决定减少1999 KDD Cup中概述的类,这只是应用了一些领域知识,因为某些攻击比其他攻击更相似,并且在一个总括条款下。

然后,我用44.4万条记录训练了分类器,同时保留了10%的数据用于测试。

准确度更差

73.39%

错误率也更差0.4261<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9BS2I5Ny5qcGcifQ==” alt =“在此处输入图像描述”>

看不见的数据分为几类:

DoS: 39149 Probe: 405 R2L: 121 U2R: 6 normal.: 9721

分类或分类标签(判别分析的结果):

DoS: 28135 Probe: 10776 R2L: 1102 U2R: 1140 normal.: 8249

培训数据由以下组成:

DoS: 352452 Probe: 3717 R2L: 1006 U2R: 49 normal.: 87395

[我担心如果我降低训练数据以具有相似百分比的恶意活动,那么分类器将没有足够的预测能力来区分类别,但是在查看其他一些文献时,我注意到一些研究人员在此删除了U2R数据不足,无法成功分类。 

到目前为止,我尝试过的方法是一类分类器,在该方法中,我训练分类器以仅预测一个类(无效),对各个类进行分类(准确性较差),减少类标签(第二好)并保持完整的23个类标签(最佳准确性)。

因此,我有两种分类方法,判别分析对数分类法(朴素贝叶斯(Naive Bayes))和在Matlab中实现的纯朴素贝叶斯(Naive Bayes)分类器,整个类共有23个类。]

正如其他人正确指出的那样,这些行中至少存在一个问题:

class1 = classify(cluster1, training_data, target_class, 'diaglinear'); ...

您正在使用所有training_data训练分类器,但仅在子分类上对其进行评估。为了使数据聚类产生效果,您需要训练每个子聚类不同的分类器

within

。有时这可能非常困难-例如,类C中来自类Y的示例可能很少(或没有!)。这是尝试进行联合聚类和学习所固有的。 您问题的一般框架如下:

Training data: Cluster into C clusters Within each cluster, develop a classifier Testing data: Assign observation into one of the C clusters (either "hard", or "soft") Run the correct classifier (corresponding to that cluster)

class1 = classify(cluster1, training_data, target_class, 'diaglinear');

不这样做。

这是一个非常简单的示例,准确显示了它应该如何工作以及出了什么问题

%% Generate data and labels for each class x11 = bsxfun(@plus,randn(100,2),[2 2]); x10 = bsxfun(@plus,randn(100,2),[0 2]); x21 = bsxfun(@plus,randn(100,2),[-2 -2]); x20 = bsxfun(@plus,randn(100,2),[0 -2]); %If you have the PRT (shameless plug), this looks nice: %http://www.mathworks.com/matlabcentral/linkexchange/links/2947-pattern-recognition-toolbox % ds = prtDataSetClass(cat(1,x11,x21,x10,x20),prtUtilY(200,200)); x = cat(1,x11,x21,x10,x20); y = cat(1,ones(200,1),zeros(200,1)); clusterIdx = kmeans(x,2); %make 2 clusters xCluster1 = x(clusterIdx == 1,:); yCluster1 = y(clusterIdx == 1); xCluster2 = x(clusterIdx == 2,:); yCluster2 = y(clusterIdx == 2); %Performance is terrible: yOut1 = classify(xCluster1, x, y, 'diaglinear'); yOut2 = classify(xCluster2, x, y, 'diaglinear'); pcCluster = length(find(cat(1,yOut1,yOut2) == cat(1,yCluster1,yCluster2)))/size(y,1) %Performance is Good: yOutCluster1 = classify(xCluster1, xCluster1, yCluster1, 'diaglinear'); yOutCluster2 = classify(xCluster2, xCluster2, yCluster2, 'diaglinear'); pcWithinCluster = length(find(cat(1,yOutCluster1,yOutCluster2) == cat(1,yCluster1,yCluster2)))/size(y,1) %Performance is Bad (using all data): yOutFull = classify(x, x, y, 'diaglinear'); pcFull = length(find(yOutFull == y))/size(y,1)

查看第一个示例的cmat1数据(精度为81.49%),获得高精度的主要原因是您的分类器获得了大量的class 1class 4正确的值。几乎所有其他类的表现都很差(获得零正确的预测)。这与您的最后一个示例(首先使用k均值)一致,对于cluster7,您的acc7为56.9698。

EDIT

:似乎在cmat1中,我们没有超过一半类的测试数据(查看全零行)。因此,您只能知道14之类的常规性能良好,并且如果首先进行聚类,将获得相似的性能。但是对于其他类,这没有证据表明它可以正常工作。
对数据进行聚类后,是否要为每个聚类转换分类器?如果您不这样做,则可能是您的问题。

尝试这样做。首先,对数据进行聚类并保留质心。然后,使用训练数据,按聚类训练分类器。对于分类阶段,找到要分类的对象的最近的质心,然后使用相应的分类器。

单个分类器不是一个好主意,因为它学习整个数据集的模式。但是,在群集时,您想要的是学习描述每个群集的本地模式。

考虑此函数调用:

classify(cluster1, training_data, target_class, 'diaglinear');

training_data是整个特征空间的样本。那意味着什么?您正在训练的分类模型将尝试使整个要素空间的分类精度最大化。这意味着,如果您显示与训练数据具有相同行为的测试样本,您将获得分类结果。

关键是您没有显示行为与训练数据相同的测试样本。实际上,cluster1仅是要素空间分区的一个样本。更具体地说,cluster1中的实例对应于特征空间的样本,该样本比其余质心更接近cluster1的质心,这可能会降低分类器的性能。

所以我建议您以下:

    聚集您的训练集并保留质心
  1. 使用训练数据,对每个聚类训练分类器。也就是说,仅使用属于该集群的实例来训练分类器。
  2. 对于分类阶段,找到要分类的对象的最近的质心,并使用相应的分类器。
matlab statistics cluster-analysis bayesian naivebayes
5个回答
1
投票
正如其他人正确指出的那样,这些行中至少存在一个问题:

1
投票
这是一个非常简单的示例,准确显示了它应该如何工作以及出了什么问题

%% Generate data and labels for each class x11 = bsxfun(@plus,randn(100,2),[2 2]); x10 = bsxfun(@plus,randn(100,2),[0 2]); x21 = bsxfun(@plus,randn(100,2),[-2 -2]); x20 = bsxfun(@plus,randn(100,2),[0 -2]); %If you have the PRT (shameless plug), this looks nice: %http://www.mathworks.com/matlabcentral/linkexchange/links/2947-pattern-recognition-toolbox % ds = prtDataSetClass(cat(1,x11,x21,x10,x20),prtUtilY(200,200)); x = cat(1,x11,x21,x10,x20); y = cat(1,ones(200,1),zeros(200,1)); clusterIdx = kmeans(x,2); %make 2 clusters xCluster1 = x(clusterIdx == 1,:); yCluster1 = y(clusterIdx == 1); xCluster2 = x(clusterIdx == 2,:); yCluster2 = y(clusterIdx == 2); %Performance is terrible: yOut1 = classify(xCluster1, x, y, 'diaglinear'); yOut2 = classify(xCluster2, x, y, 'diaglinear'); pcCluster = length(find(cat(1,yOut1,yOut2) == cat(1,yCluster1,yCluster2)))/size(y,1) %Performance is Good: yOutCluster1 = classify(xCluster1, xCluster1, yCluster1, 'diaglinear'); yOutCluster2 = classify(xCluster2, xCluster2, yCluster2, 'diaglinear'); pcWithinCluster = length(find(cat(1,yOutCluster1,yOutCluster2) == cat(1,yCluster1,yCluster2)))/size(y,1) %Performance is Bad (using all data): yOutFull = classify(x, x, y, 'diaglinear'); pcFull = length(find(yOutFull == y))/size(y,1)


-1
投票
查看第一个示例的cmat1数据(精度为81.49%),获得高精度的主要原因是您的分类器获得了大量的class 1class 4正确的值。几乎所有其他类的表现都很差(获得零正确的预测)。这与您的最后一个示例(首先使用k均值)一致,对于cluster7,您的acc7为56.9698。

EDIT


-1
投票
对数据进行聚类后,是否要为每个聚类转换分类器?如果您不这样做,则可能是您的问题。

尝试这样做。首先,对数据进行聚类并保留质心。然后,使用训练数据,按聚类训练分类器。对于分类阶段,找到要分类的对象的最近的质心,然后使用相应的分类器。


-1
投票
考虑此函数调用:

classify(cluster1, training_data, target_class, 'diaglinear');

© www.soinside.com 2019 - 2024. All rights reserved.