无意间在网上看到了:http://weka.wiki.sourceforge.net/Use+Weka+in+your+Java+code,相对我写的代码,它的当然更有权威性。翻译完了,第一次翻译,术语的汉语很多不清楚。还没有校对,有什么错误请告诉我。
你可能要用的最常用的组件(components)是:
l Instances 你的数据
l Filter 对数据的预处理
l Classifiers/Clusterer 被建立在预处理的数据上,分类/聚类
l Evaluating 评价classifier/clusterer
l Attribute selection 去除数据中不相关的属性
下面将介绍如果在你自己的代码中使用WEKA,其中的代码可以在上面网址的尾部找到。
Instances
ARFF文件
3.5.5和3.4.X版本
从ARFF文件中读取是一个很直接的
import weka.core.Instances;
import java.io.BufferedReader;
import java.io.FileReader;
...
Instances data = new Instances(
new BufferedReader(
new FileReader("/some/where/data.arff")));
// setting class attribute
data.setClassIndex(data.numAttributes() - 1);
Class Index是指示用于分类的目标属性的下标。在ARFF文件中,它被默认为是最后一个属性,这也就是为什么它被设置成numAttributes-1.
你必需在使用一个Weka函数(ex: weka.classifiers.Classifier.buildClassifier(data))之前设置Class Index。
3.5.5和更新的版本
DataSource类不仅限于读取ARFF文件,它同样可以读取CSV文件和其它格式的文件(基本上Weka可以通过它的转换器(converters)导入所有的文件格式)。
import weka.core.converters.ConverterUtils.DataSource;
...
DataSource source = new DataSource("/some/where/data.arff");
Instances data = source.getDataSet();
// setting class attribute if the data format does not provide this
//information
// E.g., the XRFF format saves the class attribute information as well
if (data.classIndex() == -1)
data.setClassIndex(data.numAttributes() - 1);
数据库
从数据库中读取数据稍微难一点,但是仍然是很简单的,首先,你需要修改你的DatabaseUtils.props(自己看一下原文,基本上都有链接)重组(resemble)你的数据库连接。比如,你想要连接一个MySQL服务器,这个服务器运行于3306端口(默认),MySQL JDBC驱动被称为Connector/J(驱动类是org.gjt.mm.mysql.Driver)。假设存放你数据的数据库是some_database。因为你只是读取数据,你可以用默认用户nobody,不设密码。你需要添加下面两行在你的props文件中:
jdbcDriver=org.gjt.mm.mysql.Driver
jdbcURL=jdbc:mysql://localhost:3306/some_database
其次,你的读取数据的Java代码,应该写成下面这样:
import weka.core.Instances;
import weka.experiment.InstanceQuery;
...
InstanceQuery query = new InstanceQuery();
query.setUsername("nobody");
query.setPassword("");
query.setQuery("select * from whatsoever");
// if your data is sparse, then you can say so too
// query.setSparseData(true);
Instances data = query.retrieveInstances();
注意:
l 别忘了把JDBC驱动加入你的CLASSPATH中
l 如果你要用MS Access,你需要用JDBC-ODBC-bridge,它是JDK的一部分。
参数设置(Option handling)
Weka中实现了weka.core.OptionHandler接口,这个接口为比如classifiers,clusterers,filers等提供了设置,获取参数的功能,函数如下:
l void setOptions(String[] Options)
l String[] getOptions()
下面依次介绍几种参数设置的方法:
l 手工建立一个String数组
String[] options = new String[2];
options[0] = "-R";
options[1] = "1";
l 用weka.core.Utils类中的函数splitOptions将一个命令行字符串转换成一下数组
String[] options = weka.core.Utils.splitOptions("-R 1");
l 用OptionsToCode.java类自动将一个命令行转换成代码,对于命令行中包含nested classes,这些类又有它们自己的参数,如果SMO的核参数这种情况很有帮助。
java OptionsToCode weka.classifiers.functions.SMO
将产生以下输出:
//create new instance of scheme
weka.classifiers.functions.SMO scheme = new
weka.classifiers.functions.SMO();
// set options
scheme.setOptions(weka.core.Utils.splitOptions("-C 1.0 -L 0.0010 -P
1.0E-12 -N 0 -V -1 -W 1 -K /"
weka.classifiers.functions.supportVector.PolyKernel -C 250007 -E
1.0/""));
并且,OptionTree.java工具可以使你观察一个nested参数字符串。
Filter
一个filter有两种不同的属性
l 监督的或是监督的(supervised or unsupervised)
是否受用户控制
l 基于属性的或是基于样本的(attribute- or instance-based)
比如:删除满足一定条件的属性或是样本
多数filters实现了OptionHandler接口,这意味着你可以通过String数组设置参数,而不用手工地用set-方法去依次设置。比如你想删除数据集中的第一个属性,你可用这个filter。
weka.
-R 1
如果你有一个Instances对象,比如叫data