您的位置:首页 > 其它

weka数据挖掘拾遗(一)---- 生成Arff格式文件

2014-02-12 10:49 387 查看
一、什么是arff格式文件

  1、arff是Attribute-Relation File Format缩写,从英文字面也能大概看出什么意思。它是weka数据挖掘开源程序使用的一种文件模式。由于weka是个很出色的数据挖掘开源项目,所以使用的比较广,这也无形中推广了它的数据存储格式。

  2、下面是weka自带的一个arff文件例子(weather.arff)

@relation weather

@attribute outlook {sunny, overcast, rainy}
@attribute temperature real
@attribute humidity real
@attribute windy {TRUE, FALSE}
@attribute play {yes, no}

@data
sunny,85,85,FALSE,no
sunny,80,90,TRUE,no
overcast,83,86,FALSE,yes
rainy,70,96,FALSE,yes
rainy,68,80,FALSE,yes
rainy,65,70,TRUE,no
overcast,64,65,TRUE,yes
sunny,72,95,FALSE,no
sunny,69,70,FALSE,yes
rainy,75,80,FALSE,yes
sunny,75,70,TRUE,yes
overcast,72,90,TRUE,yes
overcast,81,75,FALSE,yes
rainy,71,91,TRUE,no


  a) 第1行,是关系名称,这个自己随便起,不过写的最好要有意义。

   b) 第3~7行是特征列表,其中第1列是特征说明,不可缺少,第2列是特征名称,第3列是特征类型或特征取值范围。

   c) @data(第9行)是数据域说明,在它下面的全是数据。其中每一行体表一条数据。

   d) 例子中给出的数据域是最基本的表示方法,实际应用中,一般都是用稀疏表示法。

   e) 此处对于arff文件格式不做进一步解释,不懂的地方可以给我留言。

二、总体思路

  1、生成特征文件

  2、文件格式转换

三、具体实现

  1、特征的生成

    这里假设我们已经生成了特征。(因为特征选择我会另写一篇文章单独介绍)

  2、arff文件生成

    a) 生成文件的接口

package com.lvxinjian.alg.models.generatefile;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Callable;

import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.SparseInstance;

import com.iminer.alg.models.getInstance.InstanceFactory;
import com.iminer.tool.common.util.FileTool;

/**
* @Description : 生成arff文件的工具类
* @author : Lv Xinjian
*/
public class ArffFileUtils {

/**
* @function 生成特征向量
* @param lexDataPath 特征文件路径
* @param words    保存特征词
* @param classifyAttribute 类别特征
* @return    特征向量
* @throws IOException 文件读取异常
*/
public static FastVector GetAttributes(String lexDataPath , List<String> words ,ClassifyAttribute classifyAttribute)
throws IOException {
HashMap<Integer, String> termId_term = FileTool.LoadIdStrFromFile(
lexDataPath, 0, 0, 1, "\t", Charset.forName("utf8"));
FastVector atts = new FastVector();
// - numeric
for (int tid = 0; tid < termId_term.size(); tid++) {
atts.addElement(new Attribute(termId_term.get(tid)));
words.add(termId_term.get(tid));
}
atts.addElement(new Attribute(classifyAttribute.getClassname(), classifyAttribute.getAttClassLabel()));

System.out.println("atribute size :" + atts.size());
return atts;
}
/**
* @function 保存Arff文件
* @param data arff格式的数据
* @param outputPath 数据保存路径
* @return
*/
public static boolean savaInstances(Instances data , String outputPath)
{
try{
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputPath), Charset.forName("utf-8")));

bw.write(data.toString());
bw.close();
}catch(Exception e){
e.printStackTrace();
return false;
}
return true;
}
}
/**
* @Description 分类器 类别特征
* @author Administrator
*
*/
class ClassifyAttribute{
/**
* 分类特征名 , 默认为"CLASS"
*/
private String classname = "CLASS";
private FastVector attClassLabel = new FastVector();
public ClassifyAttribute(String [] labels){
for(String label: labels){
this.attClassLabel.addElement(label);
}
}
public ClassifyAttribute(){}
/**
* @function 获取类别特征名
* @return
*/
public String getClassname() {
return classname;
}
/**
* @functoin 设置类别特征名
* @param classname
*/
public void setClassname(String classname) {
this.classname = classname;
}
/**
* @function 获取类别特征
* @return 类别特征
*/
public FastVector getAttClassLabel() {
return attClassLabel;
}
/**
* @function 设置类别特征
* @param attClassLabel
*/
public void setClassLabel(FastVector attClassLabel) {
this.attClassLabel = attClassLabel;
}
/**
* @function 设置类别特征分类标签
* @param labels
*/
public void setClassLabel(String [] labels) {
for(String label: labels){
this.attClassLabel.addElement(label);
}
}

}

/**
* @Description 把字符串转化成 instance实例
* @author Administrator
*
*/
class MyCallableClass implements Callable{
/**
* 输入的文本
*/
private String _text;
/**
* 文本的极性标签
*/
private double _labelVal;
/**
* 生成instance的方法
*/
private String _getInstancesMothed = null;
/**
* 获取instance方法 的 初始化词表
*/
private List<String> _set = null;
/**
* @function 构造函数,初始化参数
* @param labelVal 极性类别标签
* @param text 输入的文本内容
* @param set 获取instance方法 的 初始化词表
* @param getInstancesMothed 生成instance的方法
*/
public MyCallableClass(final double labelVal, String text ,List<String> set ,String getInstancesMothed)
{
this._text = text;
this._labelVal = labelVal;
this._getInstancesMothed = getInstancesMothed;
this._set = set;

}
public Instance call() throws Exception{
double[] vals;
try {
//获取instance的double 数组
vals = InstanceFactory.getInstance(this._getInstancesMothed, this._set ).getInstanceFromText(this._text );
if (vals != null) {
vals[vals.length - 1] = _labelVal;
SparseInstance si = new SparseInstance(1.0, vals);
return si;
}

} catch (Exception e) {
e.printStackTrace();
}
return null;

}
}


View Code
    e) 以上代码缺少了几个类,但由于涉及到公司的保密制度,所以不方便上传。如有疑问,可以给我留言。(其实就是一个生成instance的方法,不过我的方法中揉了些东西进去,方法本身很简单,几行代码的事儿,有空我会补上)

四、小结

    1、考虑到抽取instance可能会有不同的需求,所以用了一个工厂类,这样方便 使用和新方法的添加。

    2、考虑到效率问题,所以使用了多线程进行生成。

    3、代码的结构、风格以及变量命名是硬伤,希望多多批评、指点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: