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("
Dataset:
");
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 + "
");
String str = a + " " + b + " " + dis0 + " " + dis1 + " " + dis2
+ "
";
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%
