はじめてのweka勉強会 −修正版−

ゼミ用資料です。

今回は、GUIで遊ぶ70%、プログラムを書いて理解する30%です。おきらくに、楽しんでやっていきましょう。

00.wekaを楽しむ前に

wekaはJavaで作られています。それを動かすために、JRE(Java Runtime Environment)が必要となります。
(jre1.4以上必須)
パスを通すなどの作業がいるので、詳しくは周りのJavaに強い方か、Google先生に聞いてみましょう。

0.wekaって何?

Wekaとはオープンソースデータマイニングツールで、世界中の研究者に愛用されているツールだ。
(中略)
Wekaにはデータマイニングのために必要なアルゴリズムが多数収録されており、データに対する前処理、アルゴリズムの適用、結果の視覚化といった作業をGUI上から行うことができる。*1

Javaデータマイニングツール
→ライブラリの他、強力なGUIツールがある。(日本では、ほとんどGUIのエントリが多い?)


1.ダウンロード→インストール

http://www.cs.waikato.ac.nz/~ml/weka/index.html へアクセス → 左の「download」

下の図のようにして、

  • ダウンロードします。

(exeでも、zipでもどちらでも構いません。*2レジストリに書き込みたくない方はzipで)

  • インストールします。

(exeなら、規定どおりの設定で構いません。zipなら、解凍をします)

  • 立ち上げます。

(zipで落としたならば、weka.jarをクリック)

こんなのが立ち上がれば、OK

2.GUIを使ってみよう!

社会人MBA-技術者編http://tech-d.blogspot.com/search/label/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%9E%E3%82%A4%E3%83%8B%E3%83%B3%E3%82%B0
の下から2つから5つ目までのエントリ
・Wekaを起動する。
・Wekaを起動する(補足)。
・Wekaを起動する(決定木分析?)
・Wekaを起動する(決定木分析?-2)。

を参考に、wekaに触れてみましょう。

  • これって、なにやってんの?

ゴルフ場の客が、天候状況によって来るかどうかのデータをとって、そこから法則(相関ルール)を見つけようとしています。
それを、人間がわかりやすいよう、ひとめでわかるように木構造であらわしています。

ネタ元、詳しくは、決定木 - Wikipediaの実際の例を見て、感覚的につかんでください。

*3

3.arffデータを作ってみる

できそこないpptから流用

  • arffファイルってなんだ?

人が入力したデータを読み込むために、weka独自のルールで記述したデータのファイルです。
データをwekaで扱うときは、基本、arff形式のファイルで入(出)力を行います。

  • arff形式の説明


  • エクセルのデータから、arffを作ってみよう

テキストエディタでarffは開けます

#「身長と体重のデータ」→「配布したzipにある、height_weight.csv
# 答えは、【答え】フォルダに、arff形式のデータがあります。
# arff形式のデータができたら、2.と同じ要領で、wekaで決定木を作ってみてください。

-

-

-

-

  • お疲れ様でした。

実は、csv形式でも、wekaのGUIツールの方なら使えます...

また、wekaのExplorer「Open File...」でcsv形式のデータを読み込んで、「Save...」のときに、ファイル形式を選んで、保存すれば、勝手にarffファイルに変換してくれます。逆もまた然り(arff→csvに変換)

無駄骨だったようですね*4
かしこいですね!

4.Pure Javaで使ってみる 〜 wekaのライブラリを使ったクラスタリング

#実際にJavaのソースから、ライブラリとしてwekaを使います。
#筆者は、Javaの開発はいつもEclipseを使っているので、Eclipseでの使い方が前提になると思います。
#他のやりかたは、ネットにありますので、そちらでお願いします。

  • てけとーなプログラムの流れ

I.引数にarffデータを渡す
II.arffのデータを読み込み、Instancesに一行ずつ読み込んでいく
III.関数のパラメータを調整(種の乱数、クラスタの数など)
IV.クラスタリングする
V.結果表示

  • 書く前の準備

wekaをインストールしたディレクトリの直下にある、weka.jarのパスを通す必要があります。

Eclipseを使っている場合は、
#当該プロジェクトのプロパティ→【Javaのビルド・パス】→【ライブラリー】→【外部JARの追加】→weka.jarを開く

  • それでは、書いてみよう!*5(ゼミの人は、ここからハイパープログラミングタイムです。資料の中の雛形【EMClusteringDemo.java】を使ってください)

#今回は、データをEM法でクラスタリングするプログラムを書きます。*6*7

import weka.core.Instances;
import weka.classifiers.Evaluation;
import weka.clusterers.DensityBasedClusterer;
import weka.clusterers.EM;
import weka.clusterers.ClusterEvaluation;

import java.io.BufferedReader;
import java.io.FileReader;

/**
 * An example class that shows the use of Weka clusterers from Java.
 *
 * @author  FracPete
 */

public class EMClusteringDemo {
	/**
	 * Run clusterers
	 *
	 * @param filename      the name of the ARFF file to run on
	 */
	public EMClusteringDemo(String filename) throws Exception {
		ClusterEvaluation eval;
		Instances               data;
		String[]                options;
		DensityBasedClusterer   cl;    

		data = new Instances(new BufferedReader(new FileReader(filename)));

		// normal
		// GUIで使う場合は、こっちの方法でやってるっぽい?→簡単な書き方
		System.out.println("\n--> normal");
		options    = new String[2];
		options[0] = "-t";
		options[1] = filename;
		System.out.println(
				ClusterEvaluation.evaluateClusterer(new EM(), options));

		// manual call
		// Javaで使う場合、パラメータや設定をいろいろ変えることができる。
		
		System.out.println("\n--> manual");
		EM emcl   = new EM();
		emcl.buildClusterer(data);

		//System.out.println("class:" + cl.getClass());

		eval = new ClusterEvaluation();
		eval.setClusterer(emcl);
		eval.evaluateClusterer(new Instances(data));
		System.out.println("# of clusters: " + eval.getNumClusters());

		System.out.println("# of clusters Results: " + eval.clusterResultsToString());
		
		
		printClustering(eval, data);


		/*
    // density based
    System.out.println("\n--> density (CV)");
    cl   = new EM();
    eval = new ClusterEvaluation();
    eval.setClusterer(cl);
    eval.crossValidateModel(
           cl, data, 10, data.getRandomNumberGenerator(1));
    System.out.println("# of clusters: " + eval.getNumClusters());
		 */
	}
	
	private void printClustering(ClusterEvaluation eval, Instances data){
		double[] a = new double[eval.getNumClusters()];
		a = eval.getClusterAssignments();
				
		System.out.println("\n\nClustring Results1...");

		for(int i = 0; i < a.length; i++){
			System.out.println("# Data:"+ data.instance(i).attribute(0).value(i) 
+ ": -> Cluster " + (int)a[i]   +"  " +  data.instance(i).value(1) );
		}
		//System.out.println("#text:" + eval.toString());
		
		System.out.println("\n\nClustring Results2...");

		for(int j = 0; j < eval.getNumClusters(); j++){

			System.out.println("\n# Cluster " + j);
			for(int i = 0; i < a.length; i++){

				if(j == (int)a[i]){
					System.out.println(" "+ data.instance(i).attribute(0).value(i) 
+"  " +  data.instance(i).value(1));
				}
			}

		}
	}

	/**
	 * usage:
	 *   ClusteringDemo arff-file
	 */
	public static void main(String[] args) throws Exception {
		if (args.length != 1) {
			System.out.println("usage: " + EMClusteringDemo.class.getName() + " <arff-file>");
			System.exit(1);
		}
		new EMClusteringDemo(args[0]);
	}
}
  • 実行のしかた

上のプログラムは、必ず、第1引数にarff形式のデータのパスを指定する必要があります。

java EMClusteringDemo hoge.arff

Eclipseなら
#【実行】→【構成および実行】→引数タブ→プログラムの引数にて
hoge.arff


#などと書きます。

##演習として、配布したzipファイルにある、twit_data2.arff(ある会議で、誰がどれくらい発言したかなどを集めたデータと想定)を使って動かしてみてください。
##(《注意》wether.arffでは、うごきません。)

##うまくプログラムが動けば、

##のように、クラスタリングされた結果が表示されます。*8

もちろん、GUIツール(Explorer)からも使えますが、表示結果において、処理の過程ばかり書いてあり、クラスタの中身がわからないので、上記のソースでは、自分で表示用のプログラムを書いてみました。(printClusteringメソッド)
Explorerからでも、結果表示後にvisiualizeをいろいろ試してみれば、それなりにわかるようです

#wekaが便利なの(これに限らずライブラリ全般ですね、今更ですが)は、他の手法でクラスタリングをしたいときに、数行を変えるだけで、できてしまいます。

さっきのソースの40行目あたりの「// manual call」から、以下のように変えます。*9

                  // manual call

		System.out.println("\n--> manual");
		//EM emcl   = new EM(); //削除
		SimpleKMeans kmcl = new SimpleKMeans(); //追加
		
		//emcl.buildClusterer(data); //削除
		kmcl.buildClusterer(data); //追加
		kmcl.setNumClusters(5);    //追加・・・クラスタの数を指定する(デフォルトは2)

		//System.out.println("class:" + cl.getClass());

		eval = new ClusterEvaluation();
		//eval.setClusterer(emcl); //削除
		eval.setClusterer(kmcl); //追加
		eval.evaluateClusterer(new Instances(data));
		

できたら、さっき動かしたtwit_data2.arffを読み込んでみてどんなふうに、クラスタリングの結果が変わるか見てみましょう。





以上で終わりです。おつかれさまでした。*10
上で説明した以外にも様々なライブラリが用意されています。いろいろ試してみてください。

参考先

自分のブックマークの「weka」タグ → http://b.hatena.ne.jp/stick23rd/weka/

および、この本の13、14章のあたり

Data Mining, Second Edition: Practical Machine Learning Tools and Techniques, Second Edition (The Morgan Kaufmann Series in Data Management Systems)

Data Mining, Second Edition: Practical Machine Learning Tools and Techniques, Second Edition (The Morgan Kaufmann Series in Data Management Systems)

*1:nextwise.jpより

*2:使い倒すなら、weka-jp プロジェクト日本語トップページ - OSDNへ。javaのソースがついています。

*3:id:Kishi先輩、助言ありがとございます。

*4:arff形式に慣れていただきたかったので・・・

*5:主なロジック・ソースは、http://weka.sourceforge.net/wiki/index.php/Use_Weka_in_your_Java_code から

*6:EMって何っ?な方は、こちら→http://omt.med.gunma-u.ac.jp/~tgaku/trivia/jEmalgo.htm

*7:EMのドキュメントは、clusterers.EM - weka wiki - Seesaa Wiki(ウィキ)

*8:でてきた結果は、仮想ですので、もちろん、ええ・・・

*9:SimpleKMeansのドキュメント→clusterers.SimpleKMeans - weka wiki - Seesaa Wiki(ウィキ)

*10:ゼミの皆様、ほんとお疲れ様でした。いろいろ助けていただいてありがとうございます。命拾いしました。