Hatena::ブログ(Diary)

sleeping vote このページをアンテナに追加 RSSフィード

2007-11-14

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

ゼミ用資料です。

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

勉強会の資料

http://groups.google.com/group/cica25th/files


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」

下の図のようにして、

f:id:stick23rd:20071114145649j:image

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

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

  • 立ち上げます。

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

f:id:stick23rd:20071114145954j:image

こんなのが立ち上がれば、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形式の説明

f:id:stick23rd:20071114195908g:image

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

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

f:id:stick23rd:20071114195923g:image

#「身長と体重のデータ」→「配布したzipにある、height_weight.csv

# 答えは、【答え】フォルダに、arff形式のデータがあります。

# arff形式のデータができたら、2.と同じ要領で、wekaで決定木を作ってみてください。

-

-

-

-


  • お疲れ様でした。

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

f:id:stick23rd:20071114201837g:image

また、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((EMのドキュメントは、clusterers.EM - weka wiki - Seesaa Wiki(ウィキ)へ))

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

f:id:stick23rd:20071114210854g:image

#などと書きます。

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

##(《注意》wether.arffでは、うごきません。)

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

f:id:stick23rd:20071114213159g:image

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

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

Explorerからでも、結果表示後にvisiualizeをいろいろ試してみれば、それなりにわかるようです


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

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


                  // 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を読み込んでみてどんなふうに、クラスタリングの結果が変わるか見てみましょう。





以上で終わりです。おつかれさまでした。*9

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

参考先

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

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

*1nextwise.jpより

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

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

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

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

*6:EMって何っ?な方は、こちら→no title

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

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

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

しましましましま 2007/11/15 12:05 朱鷺の杜Wiki をリンクいただいてありがとうございます

Weka関係のエントリーにもカテゴリーを設定していただけるとうれしいです.よろしくお願いします.

stick23rdstick23rd 2007/11/15 14:34 こちらこそ、朱鷺の杜Wikiのリンク集に加えていただき、ありがとうございます。
wekaのカテゴリーを追加しましたが、weka関係のエントリは、この1エントリのみなんですよ。
(まだ、勉強し始めたばかりなので、間違っているところがあるかもしれません・・・)
これから、wekaを研究で使っていくので、そのときに気がついたことを書いていこうと思います。

SASA 2008/01/09 17:56 参考にさせて貰っています。
質問ですが以下のようなエラーが出てしまうのですがどのようにしたらいいのでしょうか?

--> manual
Exception in thread ”main” java.lang.ArrayIndexOutOfBoundsException: 2
at weka.core.FastVector.elementAt(Unknown Source)
at weka.core.Instances.instance(Unknown Source)
at weka.clusterers.SimpleKMeans.toString(Unknown Source)
at weka.clusterers.ClusterEvaluation.evaluateClusterer(Unknown Source)
at KmeansClusteringDemo.<init>(KmeansClusteringDemo.java:45)
at KmeansClusteringDemo.main(KmeansClusteringDemo.java:103)

stick23rdstick23rd 2008/01/14 18:57 反応おくれてすいません。

なんでしょうね〜。配列がおかしいって言っているようですが・・・。
調査してみます。なんかわかったらコメに追記しますね。

kyushu.skyushu.s 2016/12/31 20:51 SAさんから言ったエラーの原因は以下のソース順は間違えったと思います。
kmcl.buildClusterer(data); //追加
kmcl.setNumClusters(5); //追加
==>
kmcl.setNumClusters(5); //追加
kmcl.buildClusterer(data); //追加

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

リンク元