机器学习(十五) 特征选择-卡方选择器

卡方选择器

【版权声明】本文为原创,转载请注明原地址 https://www.jianshu.com/p/f97419da1a7a
同步更新在个人网站:http://www.wangpengcufe.com/machinelearning/ml-ml15/

一、公式

卡方检验的基本公式,也就是χ2的计算公式,即观察值和理论值之间的偏差

卡方检验公式

其中:A 为观察值,E为理论值,k为观察值的个数,最后一个式子实际上就是具体计算的方法了 n 为总的频数,p为理论频率,那么n*p自然就是理论频数(理论值)

二、相关概念

卡方分布:可以看出当观察值和理论值十分接近的时候,也就是我们做的假设是正确的时候,χ2的值就越趋近于0,也就是说我们计算的偏差越小,那么假设值就越可能是对的,反之偏差值越大,假设值就越不准确。那么到底多大才算不准确,有没有个衡量的数值标准呢?答案是有:卡方分布。

卡方检验是以χ2分布为基础的一种常用假设检验方法。若k 个随机变量Z1、……、Zk 相互独立,且数学期望为0、方差为 1(即服从标准正态分布),则随机变量X被称为服从自由度为 k 的卡方分布,记作

卡方分布

,卡方分布的公式为:

卡方分布

自由度:自由度指的是计算某一统计量时,取值不受限制的变量个数。通常df=n-k。其中n为样本数量,k为被限制的条件数或变量个数。自由度v=(行数-1)(列数-1)。

自由度与卡方分布的关系

如图

自由度与卡方分布的关系图

图中的Freedom 这里有5条线,分别对应Freedom=1, 4, 10, 20 , 100 。这个Freedom 就是自由度,即个式子中独立变量的个数。 x 横坐标是卡方检验公式计算出来的偏差χ2,而 y 纵坐标表示假设的正确的概率。当自由度为1时,卡方分布式一个倾斜的曲线,当自由度逐渐增大是,卡方分布逐步变的平缓。在一定范围内,随着自由度越来越大,卡方分布会越来越接近正态分布。

三、利用卡方检验用来特征选择

特征选择(Feature Selection):指的是在特征向量中选择出那些“优秀”的特征,组成新的、更“精简”的特征向量的过程。它在高维数据分析中十分常用,可以剔除掉“冗余”和“无关”的特征,提升学习器的性能。

特征选择方法和分类方法一样,也主要分为有监督(Supervised)和无监督(Unsupervised)两种,卡方选择则是统计学上常用的一种有监督特征选择方法,它通过对特征和真实标签之间进行卡方检验,来判断该特征和真实标签的关联程度,进而确定是否对其进行选择。

对于建立模型而言并非特征越多越好,因为建模的目标是使用尽量简单的模型去实现尽量好的效果。减少一些价值小贡献小的特征有利于在表现效果不变或降低度很小的前提下,新找到最简单的模型。

那么什么样的特征是价值小的呢?想想我们之所以用机器学习的模型去学习特征,是为了更好地预测被特征影响着的应变量(标签)。那么那些根本不会对应变量产生影响,或者影响很小的特征理应事先去掉。

那么怎么判断特征对应变量的影响程度的大小呢?我们可以使用卡方检验对特征与应变量进行独立性检验,如果独立性高,那么表示两者没太大关系,特征可以舍弃;如果独立性小,两者相关性高,则说明该特征会对应变量产生比较大的影响,应当选择。

卡方检验在实际应用到特征选择中的时候,不需要知道自由度,也不用知道卡方分布,只需要根据算出来的χ2 进行排序即可,值越大越好。挑选最大的一堆,就完成了利用卡方检验来进行特征提取。

四、代码实现

和ML库中的大多数学习方法一样,ML中的卡方选择也是以estimator+transformer的形式出现的,其主要由ChiSqSelector和ChiSqSelectorModel两个类来实现。

1、首先引入相关需要用的包

import java.util.Arrays;
import java.util.List;
import org.apache.spark.ml.feature.ChiSqSelector;
import org.apache.spark.ml.feature.ChiSqSelectorModel;
import org.apache.spark.ml.linalg.VectorUDT;
import org.apache.spark.ml.linalg.Vectors;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.SparkSession;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.Metadata;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;

2、接下来获取spark

SparkSession spark =  SparkSession.builder().appName("ChiSqSelectorTest").master("local").getOrCreate();

3、然后,我们构造一个数据集DataFrame:

List<Row> rawData = Arrays.asList(RowFactory.create(1, Vectors.dense(0.0, 0.0, 18.0, 1.0), 1),
                                  RowFactory.create(2, Vectors.dense(0.0, 1.0, 12.0, 0.0), 0),
                                  RowFactory.create(3, Vectors.dense(1.0, 0.0, 15.0, 0.1), 0));
StructType schema = new StructType(new StructField[] {
        new StructField("id",DataTypes.IntegerType,false,Metadata.empty()),    
        new StructField("features",new VectorUDT(),false,Metadata.empty()),
        new StructField("label",DataTypes.IntegerType,false,Metadata.empty())
});

Dataset<Row> df = spark.createDataFrame(rawData,schema);
df.show(false);

打印结果:

+---+------------------+-----+
|id |features          |label|
+---+------------------+-----+
|1  |[0.0,0.0,18.0,1.0]|1    |
|2  |[0.0,1.0,12.0,0.0]|0    |
|3  |[1.0,0.0,15.0,0.1]|0    |
+---+------------------+-----+

4、接着我们开始用卡方选择进行特征选择器的训练

ChiSqSelector select = new ChiSqSelector().setNumTopFeatures(1)
                                          .setFeaturesCol("features")
                                          .setLabelCol("label")
                                          .setOutputCol("selected-feature");
ChiSqSelectorModel selectModel = select.fit(df);
Dataset<Row> result = selectModel.transform(df);
result.show(false);

numTopFeatures:用来设置固定的提取特征的数量,程序会根据卡方值的高低返回前n个卡方值最高的特征。(预测能力最强的前n个特征),默认选择前50个特征。这里,我们设置ChiSqSelector(卡方选择器)的numTopFeatures = 1,即在4个特征中选择处最好的1个特征。

打印结果:

+---+------------------+-----+----------------+
|id |features          |label|selected-feature|
+---+------------------+-----+----------------+
|1  |[0.0,0.0,18.0,1.0]|1    |[18.0]          |
|2  |[0.0,1.0,12.0,0.0]|0    |[12.0]          |
|3  |[1.0,0.0,15.0,0.1]|0    |[15.0]          |
+---+------------------+-----+----------------+

用训练出的模型对原数据集进行处理,可以看见,第三列特征被选出作为最有用的特征列。

参考资料: http://spark.apache.org/docs/latest/ml-features.html#chisqselector

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352