Java通過weka介面建立RF和SVM分類器
阿新 • • 發佈:2019-01-29
上面的例項初始化用到了DataSource類:</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是一個介面,能過成為資料來源的介面。
還有一種常用的方法:
<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四個classRandomForest類的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%