1. 程式人生 > >Java通過weka介面建立RF和SVM分類器

Java通過weka介面建立RF和SVM分類器

</pre>一、Instance 例項類<p></p><p>該類是用於處理一個有序的權重例項</p><p>典型的使用方法:</p><p></p><pre name="code" class="java">import weka.core.converters.ConverterUtils.DataSource;
 ...
 
 // Read all the instances in the file (<strong><span style="color:#ff0000;">ARFF</span></strong>, CSV, XRFF, ...)
 DataSource source = new DataSource(filename);
 Instances instances = source.getDataSet();
 
 // Make the last attribute be the class
 instances.setClassIndex(instances.numAttributes() - 1);
 
 // Print header and instances.
 System.out.println("\nDataset:\n");
 System.out.println(instances);
上面的例項初始化用到了DataSource類:

DataSource是一個介面,能過成為資料來源的介面。

還有一種常用的方法:

<span style="white-space:pre">		</span>Instances  insTrain = null;
		File trainfile = new File(
				"F:\\情感分析\\實驗資料和程式\\classification code\\test.arff");
		ArffLoader loader = new ArffLoader();
		loader.setFile(trainfile); // 讀取訓練文字樣例並訓練
		insTrain = loader.getDataSet();
		insTrain.setClassIndex(insTrain.numAttributes() - 1);

在上面的例項中,用到了File,ArffLoader兩個class

ArffLoader類是用於讀取儲存在arff中的源資料

二、RF  : randomforest 類

下面的例項是通過訓練資料建立了一個RF分類器,並且載入測試資料,對測試資料進行分類:

<span style="white-space:pre">		</span>RandomForest rf = new RandomForest();
		rf.buildClassifier(insTrain);// 訓練出隨機森林分類器
<span style="white-space:pre">		</span><strong><span style="color:#ff0000;">//載入訓練資料</span></strong>
		loader.setFile(testfile);
		insTest = loader.getDataSet();
		insTest.setClassIndex(insTest.numAttributes() - 1);
		int sum = insTest.numInstances();

		FileOutputStream fos = new FileOutputStream("F:\\情感分析\\實驗資料和程式\\classification code\\result.txt"); // 把結果寫到檔案裡面
		OutputStreamWriter osw = new OutputStreamWriter(fos);
		BufferedWriter bw = new BufferedWriter(osw);

		for (int i = 0; i < sum; i++) {
			a = insTest.instance(i).<strong><span style="color:#ff0000;">classValue</span></strong>();// 測試值的類標
			<strong><span style="color:#ff0000;">b = rf.classifyInstance(insTest.instance(i));// 用分類器進行的分類</span></strong>
			distribute = rf.<strong><span style="color:#ff0000;">distributionForInstance</span></strong>(insTest.instance(i));
			// System.out.print("原類標號:"+a+",新分到的類別:"+b+"  ");
			System.out.print(b + " ");
			if (a == b)
				right++;
			if (distribute != null) {
				distribute = rf.<strong><span style="color:#ff0000;">distributionForInstance</span></strong>((insTest.instance(i)));
				float dis0 = (float) (Math.round(distribute[0] * 10000)) / 10000; // 都四捨五入保留到小數點後四位數字
				float dis1 = (float) (Math.round(distribute[1] * 10000)) / 10000;
				float dis2 = (float) (Math.round(distribute[2] * 10000)) / 10000;
				// System.out.print("分類概率分佈是:");
				System.out.print(dis0 + " ");
				System.out.print(dis1 + " ");
				System.out.print(dis2 + " \n");
				String str = a + " " + b + " " + dis0 + " " + dis1 + " " + dis2
						+ "\n";
				bw.write(str);
			}
		}
在上面的例項中,用到了RandomForest,FileOutputStream,OutputStreamWriter,BufferedWriter四個class

RandomForest類的method:

classifyInstance():用訓練好的分類器進行分類

public double[] distributionForInstance(Instance instance):返回對於一個例項的類概率分佈

三、SVM :LibSVM

其實weka中構造和使用分類器的方式都是一樣的,使用上面構造RF的方法同樣適用於構造SVM。但是import的jar包不同:import weka.classifiers.functions.LibSVM;

這裡我簡單的做了一個測試,總是報錯,我也不知道為什麼。然後就在網上下了一個libsvm的jar載入到程式中,然後再做測試就行了。測試結果不是很理想,libsvm的準確率好像才90%左右,而RF的準確率可以到達97%