朴素贝叶斯分类器和判别分析的准确性是远离的

G G*_* Gr 8 statistics matlab cluster-analysis bayesian naivebayes

所以我有两种分类方法,判别分析双线性分类(朴素贝叶斯)和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)
Run Code Online (Sandbox Code Playgroud)

从混淆矩阵中得出准确度为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)
Run Code Online (Sandbox Code Playgroud)

准确率为81.89%.

我只进行了一轮交叉验证,我在matlab和监督/无监督算法上都是新的,所以我自己做了交叉验证我基本上只拿了10%的数据并将它放在一边用于测试目的,因为它是一个随机集时间我可以多次通过它并取平均准确度,但结果将用于解释目的.

所以对我的问题.

在我对当前方法的文献综述中,许多研究人员发现,将单一分类算法与聚类算法相结合,可以获得更好的准确度结果.他们通过为他们的数据找到最佳聚类数量并使用分配的聚类(应该更相似)通过分类算法运行每个单独的聚类来实现这一点.一个过程,您可以将无监督算法的最佳部分与监督分类算法结合使用.

现在我正在使用一个在文献中多次使用的数据集,并且在我的任务中尝试与其他人不同的方法.

我首先使用简单的K-Means聚类,它具有很好的聚类数据的能力.输出看起来像这样:

在此输入图像描述

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

%% output the class labels of each cluster
     K1 = UnseenTestDataLabels(indX(clustIDX==1),:)
Run Code Online (Sandbox Code Playgroud)

我发现主要是每个集群在9个集群中有一个类标签,而3个集群包含多个类标签.表明K-means与数据非常吻合.

问题不过是,一旦我有每个群集数据(cluster1中,Cluster2中... cluster12):

 %% output the real data of each cluster
     cluster1 = UnseenTestdata(clustIDX==1,:)
Run Code Online (Sandbox Code Playgroud)

我把每个群集都放在朴素的贝叶斯或判别分析中,如下所示:

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');
Run Code Online (Sandbox Code Playgroud)

精确度变得可怕,50%的聚类被分类为0%准确度,每个分类聚类(acc1,acc2,... acc12)都有自己相应的混淆矩阵,您可以在这里看到每个聚类的准确性:

在此输入图像描述

所以我的问题/问题是我哪里出错了,我首先想到的可能是我的数据/标签混合了群集,但我上面发布的内容看起来是正确的我无法看到它的问题.

为什么第一个实验中使用的数据完全相同,看不见的10%数据对于相同的看不见的聚类数据会产生如此奇怪的结果?我的意思是应该注意到NB是一个稳定的分类器,并且不应该容易过度拟合并且看到训练数据是巨大的而被分类的簇是并发过度拟合不应该发生?

编辑:

根据评论的要求,我已经包含了第一个测试示例的cmat文件,其精度为81.49%,错误为0.5040:

在此输入图像描述

还要求的是一个K,类和相关的cmat片段在这个例子中(cluster4)的准确度是3.03%:

在此输入图像描述

看到有大量的课程(总共23个)我决定减少1999年KDD杯中所列的课程,这只是应用领域知识的提升,因为一些攻击比其他攻击更相似,并且在一个伞下术语.

然后我训练分类器有444,000条记录,同时阻止10%用于测试目的.

准确率更差73.39%,错误率也更差0.4261

在此输入图像描述

unseendata分解为其类:

DoS: 39149
Probe: 405
R2L: 121
U2R: 6
normal.: 9721
Run Code Online (Sandbox Code Playgroud)

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

DoS: 28135
Probe: 10776
R2L: 1102
U2R: 1140
normal.: 8249
Run Code Online (Sandbox Code Playgroud)

培训数据由以下部分组成:

DoS: 352452
Probe: 3717
R2L: 1006
U2R: 49
normal.: 87395
Run Code Online (Sandbox Code Playgroud)

我担心如果我将训练数据降低到具有相似的恶意活动感,那么分类器就没有足够的预测能力来区分类别,但是看一些其他文献我注意到一些研究人员删除了U2R因为没有足够的数据成功分类.

我到目前为止尝试过的方法是一个类分类器,我训练分类器只预测一个类(无效),对单个集群进行分类(精度更差),减少类标签(第二最佳)并保留完整的23类标签(最好的准确性).

Pet*_*ete 1

正如其他人正确指出的那样,这里至少有一个问题是这样的:

class1  = classify(cluster1, training_data, target_class, 'diaglinear');
...
Run Code Online (Sandbox Code Playgroud)

您正在使用所有训练数据来训练分类器,但仅在子集群上对其进行评估。为了使数据聚类产生任何效果,您需要在每个子聚类中训练不同的分类器。有时这可能非常困难 - 例如,来自 Y 类的聚类 C 中可能只有很少(或没有!)的示例。这是尝试进行联合聚类和学习所固有的。

您的问题的总体框架如下:

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)
Run Code Online (Sandbox Code Playgroud)

class1  = classify(cluster1, training_data, target_class, 'diaglinear');
Run Code Online (Sandbox Code Playgroud)

不这样做。