加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

WEKA学习笔记-01 特征选择

(2015-09-16 13:41:09)
标签:

文化

分类: 大数据-数据挖掘

1. 什么是特征选择

特征选择 ( Feature Selection )也称特征子集选择( Feature Subset Selection , FSS ) ,或属性选择( Attribute Selection ) ,是指从全部特征中选取一个特征子集,使构造出来的模型更好。

 

2. 为什么要做特征选择

在机器学习的实际应用中,特征数量往往较多,其中可能存在不相关的特征,特征之间也可能存在相互依赖,容易导致如下的后果:

  • 特征个数越多,分析特征、训练模型所需的时间就越长。

  • 特征个数越多,容易引起“维度灾难”,模型也会越复杂,其推广能力会下降。

 

特征选择能剔除不相关(irrelevant)或亢余(redundant )的特征,从而达到减少特征个数,提高模型精确度,减少运行时间的目的。另一方面,选取出真正相关的特征简化了模型,使研究人员易于理解数据产生的过程。


3. 特征选择评估函数

评价函数的作用是评价产生过程所提供的特征子集的好坏。

评价函数根据其工作原理,主要分为筛选器(Filter)、封装器( Wrapper )两大类。


筛选器通过分析特征子集内部的特点来衡量其好坏。筛选器一般用作预处理,与分类器的选择无关。筛选器的原理如下图3



http://pic002.cnblogs.com/images/2011/63234/2011090620205673.jpg特征选择" />

3. Filter原理(Ricardo Gutierrez-Osuna 2008 )

 

封装器实质上是一个分类器,封装器用选取的特征子集对样本集进行分类,分类的精度作为衡量特征子集好坏的标准。封装器的原理如图4所示。

http://pic002.cnblogs.com/images/2011/63234/2011090620213253.jpg特征选择" />

4. Wrapper原理 (Ricardo Gutierrez-Osuna 2008 )

 

 

下面简单介绍常见的评价函数。

(1) 相关性( Correlation)

运用相关性来度量特征子集的好坏是基于这样一个假设:好的特征子集所包含的特征应该是与分类的相关度较高(相关度高),而特征之间相关度较低的(亢余度低)。

可以使用线性相关系数(correlation coefficient) 来衡量向量之间线性相关度。


http://pic002.cnblogs.com/images/2011/63234/2011090620220822.png特征选择" />

2) 距离 (Distance Metrics )

运用距离度量进行特征选择是基于这样的假设:好的特征子集应该使得属于同一类的样本距离尽可能小,属于不同类的样本之间的距离尽可能远。

常用的距离度量(相似性度量)包括欧氏距离、标准化欧氏距离、马氏距离等。


(3) 信息增益( Information Gain )

假设存在离散变量Y,Y中的取值包括{y1,y2,....,ym} ,yi出现的概率为Pi。则Y的信息熵定义为:



http://pic002.cnblogs.com/images/2011/63234/2011090620241669.png特征选择" />

信息熵有如下特性:若集合Y的元素分布越“纯”,则其信息熵越小;若Y分布越“紊乱”,则其信息熵越大。在极端的情况下:若Y只能取一个值,即P1=1,则H(Y)取最小值0;反之若各种取值出现的概率都相等,即都是1/m,则H(Y)取最大值log2m。

在附加条件另一个变量X,而且知道X=xi后,Y的条件信息熵(Conditional Entropy)表示为:

http://pic002.cnblogs.com/images/2011/63234/2011090620245858.png特征选择" />


在加入条件X前后的Y的信息增益定义为http://pic002.cnblogs.com/images/2011/63234/2011090620253263.png特征选择" />


类似的,分类标记C的信息熵H( C )可表示为:http://pic002.cnblogs.com/images/2011/63234/2011090620261033.png特征选择" />将特征Fj用于分类后的分类C的条件信息熵H( C | Fj )表示为:http://pic002.cnblogs.com/images/2011/63234/2011090620265132.png特征选择" />


选用特征Fj前后的C的信息熵的变化成为C的信息增益(Information Gain),用http://pic002.cnblogs.com/images/2011/63234/2011090620273361.png特征选择" />

假设存在特征子集A和特征子集B,分类变量为C,若IG( C|A ) > IG( C|B ) ,则认为选用特征子集A的分类结果比B好,因此倾向于选用特征子集A。

有一篇博客有详细介绍信息增益的原理的,通俗易懂http://blog.csdn.net/lixuemei504/article/details/7278748



(4)一致性( Consistency )

若样本1与样本2属于不同的分类,但在特征A、 B上的取值完全一样,那么特征子集{A,B}不应该选作最终的特征集。


(5)分类器错误率 (Classifier error rate )

使用特定的分类器,用给定的特征子集对样本集进行分类,用分类的精度来衡量特征子集的好坏。

    

以上5种度量方法中,相关性、距离、信息增益、一致性属于筛选器,而分类器错误率属于封装器。


筛选器由于与具体的分类算法无关,因此其在不同的分类算法之间的推广能力较强,而且计算量也较小。而封装器由于在评价的过程中应用了具体的分类算法进行分类,因此其推广到其他分类算法的效果可能较差,而且计算量也较大。


4. WEKA内嵌特征选择算法

特征选择主要

需要设置3个方面,第一:对属性评价的类(自己到Weka软件里看一下,英文Attribute Evaluator),第二:搜索的方式(自己到Weka软件里看一下,英文Search Method),第三:就是你要进行特征选择的数据集了。


方法一:下边使用CFS的特征子集选择方法,配以最佳优先的搜索或者贪心搜索,这样可以将维度比较高的训练特征集降维并简化

 4http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />package edu.tju.ikse.mi.util;
 5http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />
 6http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />import java.io.File;
 7http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />import java.io.IOException;
 8http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />import java.util.Random;
 9http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />
10http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />import weka.attributeSelection.ASEvaluation;
11http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />import weka.attributeSelection.ASSearch;
12http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />import weka.attributeSelection.AttributeSelection;
13http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />import weka.attributeSelection.BestFirst;
14http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />import weka.attributeSelection.CfsSubsetEval;
15http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />import weka.core.Instances;
16http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />import weka.core.converters.ArffLoader;
17http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />
18
22http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif特征选择" />public class WekaSelector {
23http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />
24http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />    private ArffLoader loader;
25http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />    private Instances dataSet;
26http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />    private File arffFile;
27http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />    private int sizeOfDataset;
28http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />    private int numOfOldAttributes;
29http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />    private int numOfNewAttributes;
30http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />    private int classIndex;
31http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />    private int[] selectedAttributes;
32http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />
33http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif特征选择" />    public WekaSelector(File file) throws IOException {
34http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        loader new ArffLoader();
35http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        arffFile file;
36http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        loader.setFile(arffFile);
37http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        dataSet loader.getDataSet();
38http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        sizeOfDataset dataSet.numInstances();
39http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        numOfOldAttributes dataSet.numAttributes();
40http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        classIndex numOfOldAttributes 1;
41http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        dataSet.setClassIndex(classIndex);
42http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif特征选择" />    }

43http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />
44http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif特征选择" />    public void select() throws Exception {
45http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        ASEvaluation evaluator new CfsSubseteval_r();
46http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        ASSearch search new BestFirst();
47http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        AttributeSelection eval null;
48http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />
49http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        eval new AttributeSelection();
50http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        eval.setEvaluator(evaluator);
51http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        eval.setSearch(search);
52http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />
53http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        eval.SelectAttributes(dataSet);
54http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        numOfNewAttributes eval.numberAttributesSelected();
55http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        selectedAttributes eval.selectedAttributes();
56http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        System.out.println("result is " eval.toResultsString());
57http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif特征选择" />        
69http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        System.out.println("old number of Attributes is " numOfOldAttributes);
70http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        System.out.println("new number of Attributes is " numOfNewAttributes);
71http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif特征选择" />        for(int i=0;i{
72http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />            System.out.println(selectedAttributes[i]);
73http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif特征选择" />        }

74http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif特征选择" />    }

75http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />
76http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif特征选择" />    
79http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif特征选择" />    public static void main(String[] args) {
80http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        // TODO Auto-generated method stub
81http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />        File file new File("iris.arff");
82http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif特征选择" />        try {
83http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />            WekaSelector ws new WekaSelector(file);
84http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />            ws.select();
85http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />            
86http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif特征选择" />        }
 catch (IOException e) {
87http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />            // TODO Auto-generated catch block
88http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />            e.printStackTrace();
89http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif特征选择" />        }
 catch (Exception e) {
90http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />            // TODO Auto-generated catch block
91http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />            e.printStackTrace();
92http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif特征选择" />        }

93http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />
94http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif特征选择" />    }

95http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif特征选择" />
96http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif特征选择" />}

97http://www.blogjava.net/Images/OutliningIndicators/None.gif特征选择" />


方法二:直接使用ranker

这里使用infogain作为评估函数。

package com.csdn;

 

import java.io.File;

 

import weka.attributeSelection.InfoGainAttributeEval;

import weka.attributeSelection.Ranker;

import weka.classifiers.Classifier;

import weka.core.Instances;

import weka.core.converters.ArffLoader;

 

public class SimpleAttributeSelection {

 

    

    public static void main(String[] args) {

       // TODO Auto-generated method stub

       Instances trainIns = null;

      

       try{

          

           

           File file= new File("C://Program Files//Weka-3-6//data//segment-challenge.arff");

           ArffLoader loader = new ArffLoader();

           loader.setFile(file);

           trainIns = loader.getDataSet();

          

           //在使用样本之前一定要首先设置instancesclassIndex,否则在使用instances对象是会抛出异常

           trainIns.setClassIndex(trainIns.numAttributes()-1);

          

           

           Ranker rank = new Ranker();

           InfoGainAttributeEval eval = new InfoGainAttributeeval_r();

          

           

           eval.buildEvaluator(trainIns);

           //System.out.println(rank.search(eval, trainIns));

          

           

           int[] attrIndex = rank.search(eval, trainIns);

          

           

           StringBuffer attrIndexInfo = new StringBuffer();

           StringBuffer attrInfoGainInfo = new StringBuffer();

           attrIndexInfo.append("Selected attributes:");

           attrInfoGainInfo.append("Ranked attributes:/n");

           for(int i = 0; i < attrIndex.length; i ){

              attrIndexInfo.append(attrIndex[i]);

              attrIndexInfo.append(",");

             

              attrInfoGainInfo.append(eval.evaluateAttribute(attrIndex[i]));

              attrInfoGainInfo.append("/t");

              attrInfoGainInfo.append((trainIns.attribute(attrIndex[i]).name()));

              attrInfoGainInfo.append("/n");

           }

           System.out.println(attrIndexInfo.toString());

           System.out.println(attrInfoGainInfo.toString());

          

       }catch(Exception e){

           e.printStackTrace();

       }

    }

 

}


在这个实例中,我用了InfoGain的属性选择类来进行特征选择。InfoGainAttributeEval主要是计算出各个属性的InfoGain信息。同时在weka中为属性选择方法配备的有搜索算法(seacher method),在这里我们用最简单的Ranker类。它对属性进行了简单的排序。在Weka中我们还可以对搜索算法设置一些其它的属性,例如设置搜索的属性集,阈值等等,如果有需求大家可以进行详细的设置。

在最后我们打印了一些结果信息,打印了各个属性的InfoGain的信息。


其他weka内嵌特征选择算法:



Refence: http://www.cnblogs.com/heaad/archive/2011/01/02/1924088.html

                  http://blog.csdn.net/anqiang1984/article/details/4048177

                  http://wenku.baidu.com/link?url=jFGt5Hft1EFBCGKQyUyGRebDsZDhClDVfgZSucQem-lLjNTdM8uC-sXlW-mV6ubENy4FEV9XBEKXQ_5kzRDNIGxTMfOdpTL996ofxNhuaXG

                  http://www.blogjava.net/changedi/archive/2010/11/23/338756.html

                  http://zwustudy.iteye.com/blog/1847473


0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有