分かりやすいデータに X-means を適用した結果
下記のプログラムに示すように,4クラスから成るデータに対して,クラスタ数の下限を2,上限を5として X-means 法によるクラスタリングを行った.
(参考:下限・上限を指定しない場合のデフォルト値は「下限 2,上限 4」である)
// 配列データを Weka のインスタンスとして x-means 法を適用する. /* test.txt の内容は以下のとおり.2次元空間において,4クラスから成ると想定する. ---------------------------- 1.0,1.0,label 1.1,1.0,label 1.0,1.1,label 4.0,1.0,label 4.1,1.0,label 4.1,1.1,label 1.0,4.0,label 1.0,4.1,label 1.1,4.1,label 4.0,4.0,label 4.1,4.0,label 4.1,4.1,label ---------------------------- */ // [コンパイル&実行] // javac -cp weka.jar WekaXmeans.java // java -cp weka.jar:. WekaXmeans import java.io.*; import weka.core.*; import weka.clusterers.*; import weka.core.neighboursearch.KDTree; public class WekaXmeans { public static void main(String[] args) throws Exception { //属性名の設定 FastVector attributes = new FastVector(); attributes.addElement(new Attribute("attribute1")); attributes.addElement(new Attribute("attribute2")); //インスタンス集合の定義 Instances dataClusterer = new Instances("test", attributes, 0); /// iris.txt からのデータ読み込み & インスタンス集合の生成(ここから) /// try { BufferedReader fin = new BufferedReader( new FileReader("test.txt")); String s; while((s = fin.readLine()) != null){ String[] ss = s.split(","); //インスタンス1個分のデータを配列に入れておいて・・・ int dimension = 2; double[] data = new double[dimension]; for(int i = 0; i < dimension; i++) data[i] = Double.parseDouble(ss[i]); //インスタンスを作り・・・ Instance instance = new Instance(1.0, data); //インスタンス集合に追加(登録)する dataClusterer.add(instance); } fin.close(); } catch(Exception e){ System.err.println("データ読み込み中にエラー"); System.exit(1); } /// iris.txt からのデータ読み込み & インスタンス集合の生成(ここまで) /// ////////// clusterer(クラスタリングモデル)を作る ////////// // クラスタリング手法として x-means 法を用いる XMeans clusterer = new XMeans(); clusterer.setMinNumClusters(2); clusterer.setMaxNumClusters(5); //setOptions メソッドを用いてオプションを設定する場合,以下のようにする. /* String[] options = {"-L", "2", "-H", "7", "-use-kdtree", "-K", "weka.core.neighboursearch.KDTree -P"}; clusterer.setOptions(options); */ clusterer.buildClusterer(dataClusterer); //学習データを与えて clusterer を構築 ////////// clusterer(クラスタリングモデル)の評価 ////////// ClusterEvaluation eval = new ClusterEvaluation(); eval.setClusterer(clusterer); // 評価したい clusterer を設定 eval.evaluateClusterer(dataClusterer); // テストデータとして元データを与える ////////// clusterer の評価結果(サマリ)を出力 ////////// System.out.println(eval.clusterResultsToString()); // クラスタリングの結果として割り当てられたクラス番号を得る double[] assignment = eval.getClusterAssignments(); for(int i = 0; i < assignment.length; i++){ System.out.print((int)assignment[i] + " "); } } }
実行結果は以下のとおりで,4個のクラスタを検出できた.
XMeans ====== Requested iterations : 1 Iterations performed : 1 Splits prepared : 2 Splits performed : 2 Cutoff factor : 0.5 Percentage of splits accepted by cutoff factor : 0 % ------ Cutoff factor : 0.5 ------ Cluster centers : 4 centers Cluster 0 4.066666666666666 4.033333333333333 Cluster 1 4.066666666666666 1.0333333333333334 Cluster 2 1.0333333333333334 4.066666666666666 Cluster 3 1.0333333333333334 1.0333333333333334 Distortion: 5.841547 BIC-Value : -8.862267 Clustered Instances 0 3 ( 25%) 1 3 ( 25%) 2 3 ( 25%) 3 3 ( 25%) 3 3 3 1 1 1 2 2 2 0 0 0
ちなみに,Iris データでも試してみたが,(相変わらず)2個のクラスタしか得られなかった.