8

したがって、判別分析diaglinear分類 (単純ベイズ) と matlab で実装された純粋な単純ベイズ分類器の 2 つの分類方法があり、データセット全体に 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 です(解釈方法がわからない)。

2 番目の方法の単純ベイズ分類器:

%% 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%の精度が得られます。

私はクロス検証を1ラウンドしか行っていません。私はmatlabと教師あり/教師なしアルゴリズムが初めてなので、自分でクロス検証を行いました。私は基本的にデータの 10% を取得し、テスト目的のために取っておきます。これは毎回ランダムなセットであるためです。私はそれを数回行って平均精度を取ることができましたが、結果は説明目的で行います.

だから私の問題の質問に。

現在の方法に関する私の文献レビューでは、多くの研究者が、単一の分類アルゴリズムとクラスタリング アルゴリズムを組み合わせた方が精度の高い結果が得られることを発見しています。これを行うには、データに最適なクラスター数を見つけ、分割されたクラスター (類似している必要があります) を使用して、個々のクラスターを分類アルゴリズムで実行します。教師なしアルゴリズムの最良の部分を教師あり分類アルゴリズムと組み合わせて使用​​できるプロセス。

現在、私は文献で何度も使用されているデータセットを使用しており、私の探求において他の人とあまり似ていないアプローチを試みています.

最初に単純な K-Means クラスタリングを使用しますが、これは驚くほどデータをクラスタリングする優れた機能を備えています。出力は次のようになります。

ここに画像の説明を入力

各クラスター (K1、K2...K12) のクラス ラベルを見ると、次のようになります。

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

主に各クラスターには 9 つのクラスターに 1 つのクラス ラベルがあり、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) には、対応する独自の混同行列があり、各クラスターの精度をここで確認できます。

ここに画像の説明を入力

だから私の問題/質問は: どこが間違っているのですか? 最初は、クラスターのデータ/ラベルが混同されているのではないかと考えましたが、上に投稿したものは正しいように見えますが、問題は見られません。

最初の実験で使用されたまったく同じ見えない 10% のデータであるデータが、同じ見えないクラスター化されたデータに対してこのような奇妙な結果をもたらすのはなぜですか? つまり、NB は安定した分類器であり、簡単に過剰適合してはならないことに注意する必要があります。また、分類対象のクラスターが同時に過剰適合している間、トレーニング データが膨大であるため、過剰適合が発生してはならないことに注意してください。

編集:

コメントから要求されたように、 81.49%の精度と0.5040のエラーを与えるテストの最初の例の cmat ファイルを含めました。

ここに画像の説明を入力

この例 (cluster4) では、K、クラス、および関連する cmat のスニペットも要求され、精度は3.03%です。

ここに画像の説明を入力

多数のクラス (合計 23) があったため、1999 KDD カップで概説されているようにクラスを減らすことにしました。これは、一部の攻撃が他の攻撃よりも類似しており、1 つに分類されるため、ドメインの知識を少し適用するだけです。傘用語。

次に、テスト目的で 10% を抑えながら、444,000 レコードで分類子をトレーニングしました。

精度が悪かった73.39%エラー率も悪かった0.4261

ここに画像の説明を入力

クラスに分類された目に見えないデータ:

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 を削除していることに気付きました。 t 分類を成功させるのに十分なデータ。

私がこれまでに試した方法は、1 つのクラスのみを予測するように分類器をトレーニングする 1 つのクラス分類器 (効果的ではありません)、個々のクラスターを分類する (精度はさらに悪い)、クラス ラベルを減らす (2 番目に良い)、完全な 23 クラス ラベルを保持する (最高の精度)。

4

5 に答える 5

1

他の人が正しく指摘しているように、少なくとも 1 つの問題は次の行にあります。

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

すべての training_data を使用して分類器をトレーニングしていますが、サブクラスターのみで評価しています。データをクラスター化して効果を得るには、各サブクラスターで異なる分類器をトレーニングする必要があります。場合によっては、これが非常に難しい場合があります。たとえば、クラス 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)

これ

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

そうしません。

于 2012-11-21T17:00:41.003 に答える
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)
于 2012-11-21T17:26:40.370 に答える
-1

最初の例のデータ(81.49%の精度)を見cmat1てください。高精度が得られる主な理由は、分類器が大量に正しく取得されることclass 1ですclass 4。他のほとんどすべてのクラスのパフォーマンスが悪い(正しい予測がゼロになる)。そして、これは最後の例(k-meansを最初に使用)と一致しています。ここで、cluster7の場合は56.9698のacc7を取得します。

編集cmat1では、クラスの半分以上のテストデータがないようです(すべてゼロの行を見てください)。1したがって、とのようなクラスの一般的なパフォーマンスしか知ることができず、4最初にクラスタリングを行うと同様のパフォーマンスが得られます。しかし、他のクラスの場合、これは問題なく機能するという証拠ではありません。

于 2012-11-20T12:28:59.207 に答える
-1

次の関数呼び出しを検討してください。

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

training_data特徴空間全体のサンプルです。それはどういう意味ですか?トレーニングしている分類モデルは、特徴空間全体の分類精度を最大化しようとします。つまり、トレーニング データと同じ動作をするテスト サンプルを表示すると、分類結果が得られます。

ポイントは、トレーニング データと同じ動作をするテスト サンプルを表示していないことです。実際、cluster1 は特徴空間のパーティションのみのサンプルです。より具体的には、cluster1 のインスタンスは、残りの重心よりも cluster1 の重心に近い特徴空間のサンプルに対応しており、これが分類器のパフォーマンスを低下させる可能性があります。

そこで、次のことをお勧めします。

  1. トレーニング セットをクラスター化し、重心を維持する
  2. トレーニング データを使用して、クラスターごとに分類器をトレーニングします。つまり、そのクラスターに属するインスタンスのみを使用して分類器をトレーニングします。
  3. 分類フェーズでは、分類するオブジェクトの最も近い重心を見つけ、対応する分類器を使用します。
于 2012-11-20T18:59:05.417 に答える
-1

データをクラスタ化した後、クラスタごとに分類子をトレーニングしていますか? これを行っていない場合は、これが問題である可能性があります。

これをやってみてください。まず、データをクラスター化し、重心を維持します。次に、トレーニング データを使用して、クラスターごとに分類器をトレーニングします。分類フェーズでは、分類するオブジェクトの最も近い重心を見つけ、対応する分類器を使用します。

データセット全体のパターンを学習するため、単一の分類器はお勧めできません。ただし、クラスター化するときに必要なのは、各クラスターを説明するローカル パターンを学習することです。

于 2012-11-20T15:44:19.483 に答える