Weka1 Use Weka in your Java code.docx
- 文档编号:8995200
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:26
- 大小:24.60KB
Weka1 Use Weka in your Java code.docx
《Weka1 Use Weka in your Java code.docx》由会员分享,可在线阅读,更多相关《Weka1 Use Weka in your Java code.docx(26页珍藏版)》请在冰豆网上搜索。
Weka1UseWekainyourJavacode
Weka[-1]UseWekainyourJavacode
译者:
Koala++/屈伟
无意间在网上看到了:
相对我写的代码,它的当然更有权威性。
翻译完了,第一次翻译,术语的汉语很多不清楚。
还没有校对,有什么错误请告诉我。
你可能要用的最常用的组件(components)是:
●
●
●
●
●
Instances你的数据
Filter对数据的预处理
Classifiers/Clusterer被建立在预处理的数据上,分类/聚类
Evaluating评价classifier/clusterer
Attributeselection去除数据中不相关的属性
下面将介绍如果在你自己的代码中使用WEKA,其中的代码可以在上面网址的尾部找到。
Instances
ARFF文件
3.5.5和3.4.X版本
从ARFF文件中读取是一个很直接的
importweka.core.Instances;
importjava.io.BufferedReader;
importjava.io.FileReader;
...
Instancesdata=newInstances(
newBufferedReader(
newFileReader("/some/where/data.arff")));
//settingclassattribute
data.setClassIndex(data.numAttributes()-1);
ClassIndex是指示用于分类的目标属性的下标。
在ARFF文件中,它被默认为是最后一
个属性,这也就是为什么它被设置成numAttributes-1.
你必需在使用一个Weka函数(ex:
weka.classifiers.Classifier.buildClassifier(data))之前
设置ClassIndex。
3.5.5和更新的版本
DataSource类不仅限于读取ARFF文件,它同样可以读取CSV文件和其它格式的文件(基
本上Weka可以通过它的转换器(converters)导入所有的文件格式)。
importweka.core.converters.ConverterUtils.DataSource;
...
DataSourcesource=newDataSource("/some/where/data.arff");
Instancesdata=source.getDataSet();
//settingclassattributeifthedataformatdoesnotprovidethis
//information
//E.g.,theXRFFformatsavestheclassattributeinformationaswell
if(data.classIndex()==-1)
data.setClassIndex(data.numAttributes()-1);
数据库
从数据库中读取数据稍微难一点,但是仍然是很简单的,首先,你需要修改你的
DatabaseUtils.props(自己看一下原文,基本上都有链接)重组(resemble)你的数据库连接。
比如,你想要连接一个MySQL服务器,这个服务器运行于3306端口(默认),MySQLJDBC
驱动被称为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代码,应该写成下面这样:
importweka.core.Instances;
importweka.experiment.InstanceQuery;
...
InstanceQueryquery=newInstanceQuery();
query.setUsername("nobody");
query.setPassword("");
query.setQuery("select*fromwhatsoever");
//ifyourdataissparse,thenyoucansaysotoo
//query.setSparseData(true);
Instancesdata=query.retrieveInstances();
注意:
●
●
别忘了把JDBC驱动加入你的CLASSPATH中
如果你要用MSAccess,你需要用JDBC-ODBC-bridge,它是JDK的一部分。
参数设置(Optionhandling)
Weka中实现了weka.core.OptionHandler接口,这个接口为比如classifiers,clusterers,
filers等提供了设置,获取参数的功能,函数如下:
●
●
●
●
●
voidsetOptions(String[]Options)
String[]getOptions()
下面依次介绍几种参数设置的方法:
手工建立一个String数组
String[]options=newString[2];
options[0]="-R";
options[1]="1";
用weka.core.Utils类中的函数splitOptions将一个命令行字符串转换成一下数组
String[]options=weka.core.Utils.splitOptions("-R1");
用OptionsToCode.java类自动将一个命令行转换成代码,对于命令行中包含nested
classes,这些类又有它们自己的参数,如果SMO的核参数这种情况很有帮助。
javaOptionsToCodeweka.classifiers.functions.SMO
将产生以下输出:
//createnewinstanceofscheme
weka.classifiers.functions.SMOscheme=new
weka.classifiers.functions.SMO();
//setoptions
scheme.setOptions(weka.core.Utils.splitOptions("-C1.0-L0.0010-P
1.0E-12-N0-V-1-W1-K\"
weka.classifiers.functions.supportVector.PolyKernel-C250007-E
1.0\""));
并且,OptionTree.java工具可以使你观察一个nested参数字符串。
Filter
一个filter有两种不同的属性
●
●
监督的或是监督的(supervisedorunsupervised)
是否受用户控制
基于属性的或是基于样本的(attribute-orinstance-based)
比如:
删除满足一定条件的属性或是样本
多数filters实现了OptionHandler接口,这意味着你可以通过String数组设置参数,而不用
手工地用set-方法去依次设置。
比如你想删除数据集中的第一个属性,你可用这个filter。
weka.filters.unsupervised.attribute.Remove
通过设置参数
-R1
如果你有一个Instances对象,比如叫data,你可以用以下方法产生并使用filter:
importweka.core.Instances;
importweka.filters.Filter;
importweka.filters.unsupervised.attribute.Remove;
...
String[]options=newString[2];
options[0]="-R";
options[1]="1";
Removeremove=newRemove();
remove.setOptions(options);
//"range"
//firstattribute
//newinstanceoffilter
//setoptions
//informfilteraboutdataset//**AFTER**settingoptions
remove.setInputFormat(data);
InstancesnewData=Filter.useFilter(data,remove);
//applyfilter
运行中过滤(Filteringon-the-fly)
FilteredClassifiermeta-classifier是一种运行中过滤的方式。
它不需要在分类器训练之
前先对数据集过滤。
并且,在预测的时候,你也不需要将测试数据集再次过滤。
下面的例子
中使用meta-classifierwithRemovefilter和J48,删除一个attributeID为1的属性。
importweka.core.Instances;
importweka.filters.Filter;
importweka.filters.unsupervised.attribute.Remove;
...
String[]options=newString[2];
options[0]="-R";
options[1]="1";
Removeremove=newRemove();
remove.setOptions(options);
//"range"
//firstattribute
//newinstanceoffilter
//setoptions
//informfilteraboutdataset**AFTER**settingoptions
remove.setInputFormat(data);
InstancesnewData=Filter.useFilter(data,remove);
importweka.classifiers.meta.FilteredClassifier;
importweka.classifiers.trees.J48;
importweka.filters.unsupervised.attribute.Remove;
...
//applyfilter
Instancestrain=...
Instancestest=...
//filter
Removerm=newRemove();
rm.setAttributeIndices("1");
//classifier
J48j48=newJ48();
j48.setUnpruned(true);
//fromsomewhere
//fromsomewhere
//remove1stattribute
//usinganunprunedJ48
//meta-classifier
FilteredClassifierfc=newFilteredClassifier();
fc.setFilter(rm);
fc.setClassifier(j48);
//trainandmakepredictions
fc.buildClassifier(train);
for(inti=0;i doublepred=fc.classifyInstance(test.instance(i)); System.out.printn("ID: "+test.instance(i).value(0)); System.out.print(",actual: "+test.classAttribute().value((int) test.instance(i).classValue())); System.out.println(",predicted: "+ test.classAttribute().value((int)pred)); } 其它Weka中便利的meta-schemes: weka.clusterers.FilteredClusterer(since3.5.4) weka.associations.FilteredAssociator(since3.5.6) 批过滤(Batchfiltering) 在命令行中,你可以用-b选项enable第二个input/ouput对,用对第一个数据集过滤 的设置来过滤第二个数据集。 如果你正使用特征选择(attributeselection)或是正规化 (standardization),这是必要的,否则你会得到两个不兼容的数据集。 其实这做起来很容易, 只需要用setInputFormat(Instances)去初始化一个过滤器,即用trainingset,然后将这个过 滤器依次用于trainingset和testset。 下面的例子将展示如何用Standardize过滤器过滤一 个训练集和测试集的。 Instancestrain=... Instancestest=... //fromsomewhere //fromsomewhere //initializingthefilteroncewithtrainingset Standardizefilter=newStandardize(); filter.setInputFormat(train); //configurestheFilterbasedontraininstancesandreturnsfiltered //instances InstancesnewTrain=Filter.useFilter(train,filter); //createnewtestset InstancesnewTest=Filter.useFilter(test,filter); 调用转换(Callingconventions) setInputFormat(Instances)方法总是必需是应用过滤器时最后一个调用,比如用 Filter.useFilter(Instances,Filter)。 为什么? 首先,它是使用过滤器的转换,其实,很多过滤 器在setInputFormat(Instances)方法中用当前的设置参数产生输出格式(outputformat)(在 这个调用后设置参数不再有任何作用)。 分类(classification) 一些必要的类可以在下面的包中找到: weka.classifiers 建立一个分类器(Buildaclassifier) 批(Batch) 在一个给定的数据集上训练一个Weka分类器是非常简单的事。 例如,我们可以训练一 个C4.5树在一个给定的数据集data上。 训练是通过buildClassifier(Instances)来完成的。 importweka.classifiers.trees.J48; ... String[]options=newString[1]; options[0]="-U"; J48tree=newJ48(); tree.setOptions(options); tree.buildClassifier(data); //unprunedtree //newinstanceoftree //settheoptions //buildclassifier 增量式(Incremental) 实现了weka.classifiers.UpdateabeClassifier接口的分类器可以增量式的训练,它可以节 约内存,因为你不需要把数据一次全部读入内存。 你可以查一下文档,看哪些分类器实现了 这个接口。 真正学习一个增量式的分类器是很简单的: ● ● 调用buildClassifier(Instances),其中Instances包话这种数据集的结构,其中Instances 可以有数据,也可以没有。 顺序调用updateClassifier(Instances)方法,通过一个新的weka.core.Instances,更新分 类器。 这里有一个用 weka.core.converters.ArffLoader 读取数据,并用 weka.classifiers.bayes.NaiveBayesUpdateable训练分类器的例子。 // loaddata ArffLoaderloader=newArffLoader(); loader.setFile(newFile("/some/where/data.arff")); Instancesstructure=loader.getStructure(); structure.setClassIndex(structure.numAttributes()-1); //trainNaiveBayes NaiveBayesUpdateablenb=newNaiveBayesUpdateable(); nb.buildClassifier(structure); Instancecurrent; while((current=loader.getNextInstance(structure))! =null) nb.updateClassifier(current); Evaluating 交叉检验 如果你一个训练集并且没有测试集,你也话想用十次交叉检验的方法来评价分类器。 这 可以很容易地通过Evaluation类来实现。 这里,我们用1作为随机种子进行随机选择,查 看Evaluation类,可以看到更多它输出的统计结果。 importweka.classifiers.Evaluation; importjava.util.Random; ... Evaluationeval=newEvaluation(newData); eval.crossValidateModel(tree,newData,10,newRandom (1)); 注意: 分类器(在这个例子中是tree)不应该在作为crossValidateModel参数之前训练, 为什么? 因为每当buildClassifier方法被调用时,一个分类器必需被重新初始化(换句话说: 接下来调用buildClassifier方法总是返回相同的结果),你将得到不一致,没有任何意义的 结果。 crossValidateModel方法处理分类器的training和evaluation(每一次cross-validation, 它产生一个你作为参数的原分类器的复本(copy))。 Train/Setset 如果你有一个专用的测试集,你可以在训练集上训练一个分类器,再在测试集上测试。 在下 面的例子中,一个J48被实例化,训练,然后评价。 在控制台输出一些统计值。 importweka.core.Instances; importweka.classifiers.Evaluation; importweka.classifiers.trees.J48; ... Instancestrain=... Instancestest=... //fromsomewhere //fromsomewhere //trainclassifier Classifiercls=newJ48(); cls.buildClassifier(train); //evaluateclassifierandprintsomestatistics Evaluationeval=newEvaluation(train); eval.evaluateModel(cls,test); System.out.println(eval.toSummaryString("\nResults\n======\n", false)); 统计(statistics) 下面是一些获取评价结果的方法 ● 数值型类别 Ø Ø Ø Correct()分类正确的样本数(还有incorrect()) pctCorrect()分类正确的百分比(还有pctIncorrect()) kappa()Kappastatistics ● 离散型类别 Ø correlationCoefficient()相关系数 ● 通用 Ø Ø Ø Ø meanAbsoluteError()平均绝对误差 rootMeanSquaredError()均方根误差 unclassified()未被分类的样本数 pctUnclassified()未被分类的样本百分比 如果你想通过命令行获得相同的结果,使用以下方法: importweka.classifiers.trees.J48; importweka.classifiers.Evaluation; ... String[]options=newString[2]; options[0]="-t"; options[1]="/some/where/somefile.arff"; System.out.println(Evaluation.evaluateModel(newJ48(),options)); ROC曲线/AUC(ROCcurves/AUC) 从Weka3.5.1开始,你可以在测试中产生
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Weka1 Use Weka in your Java code
![提示](https://static.bdocx.com/images/bang_tan.gif)