weka詳解

本篇文章針對weka API的幾個(gè)簡單使用介紹,weka官網(wǎng)文檔介紹非常詳細(xì),可參考。

1.?weka官網(wǎng):https://www.cs.waikato.ac.nz/~ml/weka/

2. weka官方文檔:https://waikato.github.io/weka-wiki/

3. weka API文檔:https://weka.sourceforge.io/doc.stable-3-8/

4. 推薦值得學(xué)習(xí)的blog:https://www.cnblogs.com/zlslch/category/999872.html

此博客是介紹weka比較系統(tǒng)和詳細(xì)的博客,有些不明白的地方可以查看官網(wǎng)。

備注:weka官方文檔上有相應(yīng)例子,有些例子對應(yīng)版本比較舊,可對應(yīng)更新為自己使用的版本

建議看下官網(wǎng)的有關(guān)weka視頻的介紹:https://youtu.be/TF1yh5PKaqI

一、Java調(diào)用Weka API創(chuàng)建Arff文件

Arff(attribute relation file format 關(guān)系屬性格式)文件是一種由獨(dú)立、無序?qū)嵗M成的數(shù)據(jù)集文件,是一種 ASCII 文本文件。在 Arff 文件中,%開始表示注釋;@relation 表示數(shù)據(jù)之間的關(guān)系;@attribute 表示字段名稱和字段類型;@data 表示具體的數(shù)據(jù),同時(shí)數(shù)據(jù)的順序要和@attribute 中的屬性保持一致。文件內(nèi)容中,最開始的部分顯示文件注釋,之后顯示關(guān)系的名字和屬性的具體定義,在屬性下是具體的數(shù)據(jù)集合。

1. 總共就這么四步,關(guān)鍵代碼:

1)一開始需要實(shí)例化一個(gè)Vector來保存數(shù)據(jù)屬性:

FastVector atts =newFastVector();// 保存屬性

2)同時(shí)需要有保存單條數(shù)據(jù)

double[]vals;// arff保存單條數(shù)據(jù)

3)判斷數(shù)據(jù)格式之后新建數(shù)據(jù)屬性:

atts.addElement(newAttribute(numName));

4)之后填充數(shù)據(jù):

vals[j] =instances.attribute(j).addStringValue("XXXXX");

2.?完整代碼:

/** * 創(chuàng)建合法格式的Arff文件 * * @param data 該參數(shù)為封裝好的Data參數(shù),數(shù)據(jù)類型為 * Map<String, List<Object>> * @return * @throws Exception */

? ? public String createArffFile(Data data, int userID) throws Exception {

? ? ? ? FastVector atts = new FastVector();// 保存屬性

? ? ? ? double[] vals;// arff保存單條數(shù)據(jù)

? ? ? ? // 創(chuàng)建List作為數(shù)據(jù)類型flag

? ? ? ? List<Object> indexList = new LinkedList<Object>();

? ? ? ? // 獲取data數(shù)據(jù)

? ? ? ? wekaData = XMLParser.praseXML(data.getData_Content());

? ? ? ? // 獲取data中的第0行為title,第一行為判斷數(shù)據(jù)類型

? ? ? ? List<Object> titleList = wekaData.get("0");

? ? ? ? List<Object> firstList = wekaData.get("1");

? ? ? ? // 遍歷title中的數(shù)據(jù)類型,為arff文件創(chuàng)建attribute

? ? ? ? for (int i = 0; i < firstList.size(); i++) {

? ? ? ? ? ? Object obj = firstList.get(i);

? ? ? ? ? ? String objStr = obj.toString();

? ? ? ? ? ? if (isNumeric(objStr)) {

? ? ? ? ? ? ? ? indexList.add("Numeric");

? ? ? ? ? ? ? ? String numName = String.valueOf(titleList.get(i));

? ? ? ? ? ? ? ? atts.addElement(new Attribute(numName));

? ? ? ? ? ? } else if (isValidDate(objStr)) {

? ? ? ? ? ? ? ? indexList.add("Date");

? ? ? ? ? ? ? ? atts.addElement(new Attribute((String) titleList.get(i), "yyyy-MM-dd"));

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? indexList.add("String");

? ? ? ? ? ? ? ? atts.addElement(new Attribute((String) titleList.get(i), (FastVector) null));

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? // 必須放在創(chuàng)建attribute之后 否則會(huì)報(bào)異常

? ? ? ? Instances instances = new Instances(data.getData_Name(), atts, 0); // 創(chuàng)建一個(gè)weka data實(shí)例

? ? ? ? System.out.println(indexList);

? ? ? ? // 填充數(shù)據(jù)

? ? ? ? for (int i = 1; i < wekaData.size(); i++) {

? ? ? ? ? ? vals = new double[instances.numAttributes()];

? ? ? ? ? ? String index = String.valueOf(i);

? ? ? ? ? ? int length = wekaData.get(index).size();

? ? ? ? ? ? System.out.println(length);

? ? ? ? ? ? // 遍歷填充

? ? ? ? ? ? for (int j = 0; j < length; j++) {

? ? ? ? ? ? ? ? if (indexList.get(j).equals("String")) {

? ? ? ? ? ? ? ? ? ? System.out.println("string");

? ? ? ? ? ? ? ? ? ? vals[j] = instances.attribute(j).addStringValue((String) wekaData.get(index).get(j));

? ? ? ? ? ? ? ? } else if (indexList.get(j).equals("Numeric")) {

? ? ? ? ? ? ? ? ? ? System.out.println("number");

? ? ? ? ? ? ? ? ? ? System.out.println((String) wekaData.get(index).get(j));

? ? ? ? ? ? ? ? ? ? double num = Double.valueOf((String) wekaData.get(index).get(j));

? ? ? ? ? ? ? ? ? ? vals[j] = num;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? instances.add(new Instance(1.0, vals));

? ? ? ? ? ? // end

? ? ? ? }

? ? ? ? System.out.println(instances.toString());

? ? ? ? // IP時(shí)間戳工具

? ? ? ? IPTimeStamp ipTimeStamp = new IPTimeStamp();

? ? ? ? // 保存文件加時(shí)間戳重命名,防止不同文件重名覆蓋

? ? ? ? String fileName = ipTimeStamp.getIPTimeRand() + "_" + userID + "_" + data.getData_Name();

? ? ? ? String path = configProperty.getArffPath() + fileName + ".arff";

? ? ? ? File outFile = new File(path);

? ? ? ? FileUtils.writeStringToFile(outFile, instances.toString(), false);

? ? ? ? System.out.println("ArffPath" + configProperty.getArffPath());

? ? ? ? return path;

? ? }

構(gòu)建好的格式舉例:K-means聚類樣本.arff

@relation K-means聚類樣本

@attribute X numeric

@attribute Y numeric

@data

0,0

1,0

二、Weka API使用訓(xùn)練好的已知模型進(jìn)行實(shí)時(shí)預(yù)測

1、自己根據(jù)屬性構(gòu)建instance實(shí)例。

2、調(diào)用之前已經(jīng)訓(xùn)練的模型,調(diào)用時(shí)需要將模型強(qiáng)制轉(zhuǎn)變?yōu)槟P蜋C(jī)器學(xué)習(xí)類型,如NaiveBayes的模型需要這樣操作。

Classifier m_Classifier =?(NaiveBayes)SerializationHelper.read(new FileInputStream("model/bayes.model"));

以下是本文構(gòu)建的Weka實(shí)時(shí)預(yù)測功能:

本實(shí)例中instance具有四個(gè)屬性,第一個(gè)為double屬性,第二個(gè)是double屬性,第三個(gè)是Nominal類型,第四個(gè)是Class類型(預(yù)測值)。

注:本文中使用的模型可以使用Weka圖形界面操作生成。

代碼思路:

首先,構(gòu)建一個(gè)instances結(jié)構(gòu),構(gòu)建instances具有什么樣的屬性;其次,指定instances的類別索引,即指定哪個(gè)屬性代表的是類別。之后,構(gòu)建instance實(shí)例,將instances的結(jié)構(gòu)框架指定為instance的數(shù)據(jù)集,給instance賦值,此處傳值時(shí)不需要傳入Class值,因?yàn)檫@是我們要預(yù)測的;最后,使用已知模型的classifyInstance方法對instance進(jìn)行預(yù)測,再根據(jù)預(yù)測出的索引得到預(yù)測類別的值。

以下是編寫的Weka實(shí)時(shí)預(yù)測代碼:

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import weka.classifiers.Classifier;

import weka.classifiers.bayes.NaiveBayes;

import weka.core.Attribute;

import weka.core.FastVector;

import weka.core.Instance;

import weka.core.Instances;

import weka.core.SerializationHelper;

public class WekaTestInstance

{

? ? Instances m_Data = null;

? ? Classifier m_Classifier = null;

? ? public WekaTestInstance() throws FileNotFoundException, Exception

? ? {

? ? ? ? m_Classifier = (NaiveBayes)SerializationHelper.read(new FileInputStream("model/bayes.model"));?


? ? ? ? String nameOfDataset = "messDataset";

? ? ? ? FastVector attributes = new FastVector();

? ? ? ? attributes.addElement(new Attribute("aa"));

? ? ? ? attributes.addElement(new Attribute("bb"));


? ? ? ? FastVector fvNominalVal = new FastVector(3);

? ? ? ? fvNominalVal.addElement("blue");

? ? ? ? fvNominalVal.addElement("gray");

? ? ? ? fvNominalVal.addElement("black");? ? ? ? ? ? ?

? ? ? ? attributes.addElement(new Attribute("Nominal", fvNominalVal));


? ? ? ? FastVector classValues = new FastVector(2);

? ? ? ? classValues.addElement("pos");

? ? ? ? classValues.addElement("neg");

? ? ? ? attributes.addElement(new Attribute("Class", classValues));

? ? ? ? m_Data = new Instances(nameOfDataset, attributes, 10);

? ? ? ? m_Data.setClassIndex(m_Data.numAttributes()-1);

? ? }

? ? public void classifyMessage(double aa,double bb,String nominal) throws Exception

? ? {

? ? ? ? Instances testset = m_Data.stringFreeStructure();

? ? ? ? Instance instance = makeInstance(aa,bb,nominal,testset);

? ? ? ? System.out.println(m_Data.numAttributes());

? ? ? ? System.out.println(instance);

? ? ? ? double predicted = m_Classifier.classifyInstance(instance);

? ? ? ? System.out.println("predicted:"+predicted);

? ? ? ? System.out.println("Message classified as : " +

? ? ? ? ? ? ? ? m_Data.classAttribute().value((int)predicted));

? ? }

? ? private Instance makeInstance(double aa,double bb,String nominal,Instances data)

? ? {

? ? ? ? Instance instance = new Instance(4);

? ? ? ? instance.setDataset(data);

? ? ? ? Attribute aaAtt = data.attribute("aa");

? ? ? ? Attribute bbAtt = data.attribute("bb");

? ? ? ? Attribute nominalAtt = data.attribute("Nominal");


? ? ? ? instance.setValue(aaAtt, aa);

? ? ? ? instance.setValue(bbAtt, bb);

? ? ? ? instance.setValue(nominalAtt, nominal);


//? ? ? instance.setValue((Attribute)instance.attribute(0), aa);

//? ? ? instance.setValue((Attribute)instance.attribute(1), bb);

//? ? ? instance.setValue((Attribute)instance.attribute(2),nominal);? ? ? ?

? ? ? ? return instance;

? ? }

? ? public static void main(String[] args) throws Exception

? ? {

? ? ? ? WekaTestInstance wTestInstance = new WekaTestInstance();

? ? ? ? wTestInstance.classifyMessage(5.6,9.9,"gray");

? ? }

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容