WEKA 学习总结

一、一些基础概念

1.      Weka处理的数据表格中,一个横行称为一个实例(Instance),竖行代表一个属性(Arrtibute),数据表格称为一个数据集,在weka看来,呈现了属性之间的一种关系(Relation)

2.      Weka存储数据的格式是ARFF(Attribute-RelationFile Format)文件,这是一种ASCII文本文件。

3.      Weka的ARFF文件可以分为两部分。第一部分给出了头信息(Head information),包括了对关系的声明和对属性的声明。第二部分给出了数据信息(Data information),即数据集中给出的数据。从@Data标记开始,后面的就是数据信息了。

4.      Weka作为数据挖掘,面临的第一个问题往往是我们的数据不是ARFF格式的。幸好,WEKA还提供了对CSV文件的支持,而这种格式是被许多其他软件所支持的。此外,WEKA还提供了通过JDBC访问数据库的功能。

5.      需要注意的是,matlab给出的csv文件往往没有属性名(Excel 给出的也可能没有)。而WEKA必须从CSV文件的第一行读取属性名,否则就会把第一行的各属性值读成变量名。因此我们对于matlab给出的csv文件需要用UltraEdit打开,手工添加一行属性名。

6.      Weka提供了命令将CSV文件转换成arff文件。

7.      Weka GUI根据不同功能分为8个界面:

(1)    区域1的几个选项卡用来切换不同的挖掘任务面板。

(2)    区域2是一些常用按钮。包括打开数据,保存及编辑功能。

(3)    选择某个Filter,可以实现筛选数据或者对数据进行某种变换。

(4)    区域4展示了数据集的一些基本情况。

(5)    列出了数据集的所有属性。

(6)    区域6中有关于这个属性的摘要,注意对于数值属性和分类属性,摘要的方式是不一样的。

(7)    区域7中是区域5属性的直方图。

(8)    区域8是状态栏,可以查看Log义判断是否有错。右边的weka鸟在动的话说明weka正在执行挖掘任务。右键点击状态栏可以执行java内存垃圾回收。

8.      通常对于数据挖掘任务来说,ID这样的信息是无用的。

9.      Weka把分类(Classification)和回归(Regression)都放在“Classify”选项卡中。

10.  在weka中,待预测的目标(输出)被称为Class属性,这应该是来自分类任务的“类”。一般的,若Class属性是分类型时我们的任务才叫分类,Class属性是数值型时我们的任务叫回归。

11.  所谓回归分析法,是在掌握大量观察数据的基础上,利用数理统计方法建立因变量和自变量之间的回归关系函数表达式(称回归方程)。

12.  在回归分析中,又依据描述自变量和因变量之间因果关系的函数表达式是线性的还是非线性的,分为线性回归分析和非线性分析。通常线性回归分析法是最基本的分析方法,遇到非线性回归问题可以借助数学手段化为线性回归问题处理。

13.  一元线性回归是指事物发展的自变量和因变量之间是单因素的简单线性关系,它的模型可以表示为: y=a+bx

14.  多元线性回归是指一个因变量和多个自变量之间的线性关系,模型一般形式为:

Y=a+b1x1+b2x2+…+bnxn

15.  为了保证生成的模型的准确性而不至于出现拟合的现象,我们有必要采用10折交叉验证来选择和评估模型。

16.  10 折交叉验证:英文名叫做10-fold corss –validation,用来测试算法的准确性。是常用的测试方法。将数据集分成10份,轮流将其中9份作为训练数据,1份作为测试数据,进行试验。每次试验都会得到相应的正确率(或差错率)。10次的结果的正确率(或差错率)的平均值作为对算法精确读的估计,一般还需要进行多次10折交叉验证。

17.  数据挖掘中分类与聚类最本质的区别:

简单的说:分类是“监督学习”,事先知道有那些类别可以分。聚类—是“无监督学习”,事先不知道要分成哪些类。

数据分类是指分析数据库中的一组对象,找出去共同属性。然后根据分类模型,把他们划分为不同的类别。分类数据首先根据训练数据建立分类模型,然后根据这些分类描述分类数据中的测试数据或产生更恰当的描述。文本分类的一般流程是:(1)构造训练集(预先对文档手工标注类别、分词、去掉stopword和常用词、提取特征词、计算特征值TF-IDF) (2)对要预测的新文本需(分词、去掉stopword和常用词、计算特征值) (3)用分类器进行预测分类

聚类是指数据库中的数据可以划分为一些列有意义的子集,即类。在同一类别中,个体之间的距离较小,而不同类别上的个体之间的距离偏大。聚类分析通常称为“无监督的学习”:不需要训练过程、以及不需要预先对文档手工标注类别,因此具有较高的灵活性和自动化处理能力,成为对文本信息进行有效组织、摘要和导航的重要手段。

18.  在进行聚类运算时,设置seed是设置一个随机种子,依此产生一个随机数,用来得到K均值算法中第一次给出的K个簇中心的位置。

19.  朴素贝叶斯(NaiveBayes)
朴素贝叶斯模型(NBC)发源于古典数学理论,有着坚实的数学基础,以及稳定的分类效率。同时,NBC 模型所需估计的参数很少,对缺失数据不太敏感,算法也比较简单。NBC 模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,这给 NBC 模型的正确分类带来了一定影响。在属性个数(特征维度)比较多或者属性之间相关性较大时,NBC 模型的分类效率比不上决策树模型。而在属性相关性较小时,NBC 模型的性能最为良好。

二、weka 中的几个分类、聚类例子


import java.io.File;

import weka.classifiers.Classifier;
import weka.classifiers.trees.J48;
import weka.core.Instances;
import weka.core.converters.ArffLoader;

/**
 * J48 即决策树 C4.5 算法
C4.5 算法一种分类决策树算法 , 其核心算法是 ID3 算法。C4.5 算法继承了 ID3 算法的优点,并在以下几方面对 ID3 算法进行了改进:
1、用信息增益率来选择属性,克服了用信息增益选择属性时偏向选择取值多的属性的不足;
2、在树构造过程中进行剪枝;
3、能够完成对连续属性的离散化处理;
4、能够对不完整数据进行处理。
C4.5 算法有如下优点:
产生的分类规则易于理解,准确率较高。
其缺点是:在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导致算法的低效。
* http://www.ibm.com/developerworks/cn/opensource/os-cn-datamining/
*/
public class J48Test {

	public static void main(String[] args) throws Exception {
		Classifier m_classifier = new J48();
		// 训练语料文件,官方自带的 demo 里有
		File inputFile = new File("D:\\c_install_program\\Weka-3-6\\data\\cpu.with.vendor.arff");
		ArffLoader atf = new ArffLoader();
		atf.setFile(inputFile);
		Instances instancesTrain = atf.getDataSet(); // 读入训练文件
		// 测试语料文件:随便 copy 一段训练文件出来,做分类的预测准确性校验
		inputFile = new File("D:\\c_install_program\\Weka-3-6\\data\\cpu.with.vendor_test.arff");
		atf.setFile(inputFile);
		Instances instancesTest = atf.getDataSet(); // 读入测试文件
		instancesTest.setClassIndex(0); // 设置分类属性所在行号(第一行为0号),instancesTest.numAttributes()可以取得属性总数
		double sum = instancesTest.numInstances(), // 测试语料实例数
		right = 0.0f;
		instancesTrain.setClassIndex(0);// 分类属性:第一个字段
		m_classifier.buildClassifier(instancesTrain); // 训练
		for (int i = 0; i < sum; i++)// 测试分类结果
		{
			double predicted = m_classifier.classifyInstance(instancesTest.instance(i));
			System.out.println("预测某条记录的分类id:" + predicted + ", 分类值:"
					+ instancesTest.classAttribute().value((int) predicted));
			System.out.println("测试文件的分类值: " + instancesTest.instance(i).classValue() + ", 记录:"
					+ instancesTest.instance(i));
			System.out.println("--------------------------------------------------------------");

			// 如果预测值和答案值相等(测试语料中的分类列提供的须为正确答案,结果才有意义)
			if (m_classifier.classifyInstance(instancesTest.instance(i)) == instancesTest.instance(i)
					.classValue()) {
				right++;// 正确值加1
			}
		}
		// 请将文件内容的第一列 ? 换成正确答案,才能评判分类预测的结果,本例中只是单纯的预测,下面的输出没有意义。
		System.out.println("J48 classification precision:" + (right / sum));
	}

}



import weka.clusterers.ClusterEvaluation;
import weka.clusterers.EM;
import weka.core.Instances;
import weka.core.converters.ConverterUtils.DataSource;
import weka.filters.Filter;
import weka.filters.unsupervised.attribute.Remove;

/**
 *EM是一种基于模型的聚类算法,假设样本符合高斯混合模型,算法的目的是确定各个高斯部件之间的参数,充分拟合给定数据,
 *并得到一个模糊聚类,即每个样本以不同概率属于每个高斯分布,概率数值将由以上个参数获得。
 * http://irwenqiang.iteye.com/blog/1601902
 */
public class ClassesToClusters {
  public static void main(String[] args) throws Exception {
    // load data
    Instances data = DataSource.read("D:\\c_install_program\\Weka-3-6\\data\\iris.arff");
    data.setClassIndex(data.numAttributes() - 1);

    // generate data for clusterer (w/o class)
    Remove filter = new Remove();
    filter.setAttributeIndices("" + (data.classIndex() + 1));
    filter.setInputFormat(data);
    Instances dataClusterer = Filter.useFilter(data, filter);

    // train clusterer
    EM clusterer = new EM();
    // set further options for EM, if necessary...
    clusterer.buildClusterer(dataClusterer);

    // evaluate clusterer
    ClusterEvaluation eval = new ClusterEvaluation();
    eval.setClusterer(clusterer);
    eval.evaluateClusterer(data);

    // print results
    System.out.println(eval.clusterResultsToString());
  }
}



import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;

import weka.clusterers.XMeans;
import weka.core.Instances;
import weka.core.converters.ArffLoader;

public class WekaCluster {

	private ArffLoader loader;
	private Instances dataSet;
	private weka.clusterers.Clusterer cluster;
	private int numOfClusters;
	private String newAttribute;
	private File arffFile;
	private int sizeOfDataset;

	public WekaCluster(File arffFile) {
		this.arffFile = arffFile;
		doCluster();
	}

	private void doCluster() {
		loader = new ArffLoader();
		newAttribute = "";
		try {
			loader.setFile(arffFile);
			dataSet = loader.getDataSet();
			cluster = new XMeans();
			cluster.buildClusterer(dataSet);
			numOfClusters = cluster.numberOfClusters();
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < numOfClusters; i++) {
				sb.append("s" + (i + 1) + " ");
			}
			newAttribute = sb.toString().trim();
			sizeOfDataset = dataSet.numInstances();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void newArffWriter() {
		int lineNum = 0;
		try {
			Scanner input = new Scanner(arffFile);
			// PrintWriter out = new
			// PrintWriter(CfUtil.GetFileNameNoExtFromFileName(arffFile.getName())
			// + "_classification.arff");
			PrintWriter out = new PrintWriter("D:\\c_install_program\\Weka-3-6\\data\\cpu.arff");

			while (input.hasNext()) {
				String line = input.nextLine();
				if (line.startsWith("@relation")) {
					out.println("@relation" + line.substring(9) + "_classification");
				} else if (line.startsWith("@data")) {
					out.println("@attribute shape {" + newAttribute + "}");
					out.println("@data");
				} else if (line.startsWith("@attribute")) {
					out.println(line);
				} else if (line.isEmpty()) {
					out.println();
				} else {
					line += ",class" + (cluster.clusterInstance(dataSet.instance(lineNum)) + 1);
					out.println(line);
					lineNum++;
				}
			}
			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public int clusterNewInstance(weka.core.Instance instance) {
		int indexOfCluster = -1;
		try {
			indexOfCluster = cluster.clusterInstance(instance);
			// System.out.println("cluster " + indexOfCluster);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return indexOfCluster;
	}

	public double[] frequencyOfCluster() {
		int[] sum = new int[this.numOfClusters];
		try {
			System.out.println("---------- will show the every instance's clusterIndex: ");
			for (int i = 0; i < this.sizeOfDataset; i++) {
				int clusterIndex = cluster.clusterInstance(dataSet.instance(i));
				sum[clusterIndex]++;
				System.out.println("instanceIndex: " + i + ", clusterIndex: " + clusterIndex + ",\t"
						+ dataSet.instance(i));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		double[] fre = new double[sum.length];
		for (int i = 0; i < sum.length; i++) {
			fre[i] = (double) sum[i] / (double) this.sizeOfDataset;
		}
		return fre;
	}

	public static void main(String[] args) {
		File file = new File("D:\\c_install_program\\Weka-3-6\\data\\cpu.arff");
		WekaCluster wc = new WekaCluster(file);
		double[] fre = wc.frequencyOfCluster();
		for (int i = 0; i < fre.length; i++) {
			System.out.println("clusterIndex " + i + "'s freq: " + fre[i]);
		}

		// wc.newArffWriter(file);
		double[] feature = { 125, 256, 6000, 256, 16, 128, 199 };
		// double[] feature = { 1480,11000,14000,01,01,10,45222 };
		weka.core.Instance ins = new weka.core.Instance(7);
		// int insNums = wc.dataSet.numInstances();
		for (int i = 0; i < ins.numAttributes(); i++) {
			ins.setValue(i, feature[i]);
			// System.out.println(wc.dataSet.lastInstance().attribute(i).getLowerNumericBound());
		}
		// wc.dataSet.add(ins);
		// ins.setDataset(wc.dataSet);
		// System.out.println(ins.attribute(1).getLowerNumericBound());
		// System.out.println(wc.dataSet.instance(insNums));
		System.out.println(ins + " in cluster: " + wc.clusterNewInstance(ins));
	}

}


三、REF

Weka教程(包含了数据格式、数据准备、分类和聚类Demo)

http://irwenqiang.iteye.com/blog/1308834

http://www.blogjava.net/changedi/archive/2010/11/04/337190.html

基于 VSM(向量空间模型)的文本聚类算法
http://irwenqiang.iteye.com/blog/1544217
http://irwenqiang.iteye.com/category/182686
WEKA学习总结
http://blog.csdn.net/lantian0802/article/details/8875874
用JAVA程序调用LibSVM API示例
http://blog.csdn.net/yangliuy/article/details/8041343
http://blog.csdn.net/yangliuy/article/details/7628976

朴素贝叶斯分类器的应用

http://www.ruanyifeng.com/blog/2013/12/naive_bayes_classifier.html

十大数据挖掘算法及各自优势

http://www.199it.com/archives/272346.html

你可能感兴趣的:(WEKA 学习总结)