因工作需要,会用到MLLib的卡方特征选择算法,但是以前没有接触过任何类似的东西,在官网看和百度找了很久机会都是抄袭官网的例子,最重要的是例子没有说明,不知道为什么这么用?有什么效果?
所以在这里不多说了,直接介绍怎么用,为什么这么用,有什么用!
数据说明:
gender: 0–女 1–男
hobby: 我乱写的, 1-篮球 2-足球 3-乒乓 4-逛街 5-购物
age:年龄,是我自己编的
salary:工资,这个也是乱写的
makeup:是否化妆 1–化妆 0–不化妆
说明:数据源一定要是数字类型的,很多算法都要求是double的,所以你在使用spark做处理的时候,要把数据源归类处理,不要使用什么中文,和字母之类的,用数字分类,不然spark不认识
id | gender | hobby | age | salary | makeup |
---|---|---|---|---|---|
1 | 0 | 4 | 22 | 4000 | 1 |
2 | 0 | 4 | 22 | 6000 | 1 |
3 | 0 | 5 | 25 | 5000 | 1 |
4 | 0 | 5 | 28 | 7000 | 1 |
5 | 0 | 3 | 25 | 1000 | 1 |
6 | 0 | 4 | 30 | 5000 | 0 |
7 | 1 | 1 | 21 | 6000 | 0 |
8 | 1 | 1 | 22 | 4000 | 0 |
9 | 1 | 3 | 23 | 6000 | 0 |
10 | 1 | 2 | 25 | 7000 | 0 |
我现在想知道,化不化妆(应变量),这个标签,到底与哪几个特征有关系?
如果使用卡方检验计算的话,当然是可以计算出来的,有公式,这里我也不会这些公式,可以自己搜索,spark mllib提供了现成的方法,直接看代码吧:
下面这代码的格式,我调了半天, 没调好,将就下吧, 第一次玩这个.
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;
import java.util.Arrays;
import java.util.List;
/**
* @author Hh
* @create 2018-07-30 17:38
* 卡方特征选择
**/
public class MyChiSelect {
public static void main(String[] args) {
SparkSession spark = SparkSession.builder()
.appName(“MyChiSelect”)
.master(“local”)
.getOrCreate();
List data = Arrays.asList(
//下面的数据跟我上面的表格不完全一致因为,我是分两次写的,但是不影响,你们可以自己把它改成一致,我就不改了,上班写博客呢
//数据的顺序可以不保持一致,但是features一定是一个vector的数组
//label,也就是标签,是否化妆这列数据,单独分出来
//所以下面的数据格式就是[features],makeup
RowFactory.create(Vectors.dense(1.0, 2, 22.0, 22222), 1.0),
RowFactory.create(Vectors.dense(1.0, 2, 22.0, 22222), 1.0),
RowFactory.create(Vectors.dense(1.0, 3, 22.0, 2323), 1.0),
RowFactory.create( Vectors.dense(1.0, 3, 22.0, 32323), 1.0),
RowFactory.create( Vectors.dense(1.0, 4,22.0, 4444), 0.0),
RowFactory.create( Vectors.dense(0.0, 9, 22.0, 345345), 0.0),
RowFactory.create( Vectors.dense(0.0, 9, 22.0, 435345), 0.0),
RowFactory.create( Vectors.dense(0.0, 6,22.0, 436345), 0.0),
RowFactory.create( Vectors.dense(0.0, 5, 22.0, 234234), 0.0),
RowFactory.create( Vectors.dense(1.0, 5, 22.0, 4564), 1.0)
);
StructType schema = new StructType(
new StructField[] {
new StructField("feature", new VectorUDT(), false, Metadata.empty()),
new StructField("makeup", DataTypes.DoubleType, false, Metadata.empty()), });
Dataset df = spark.createDataFrame(data, schema);
//学习并建立模型
ChiSqSelector chiSqSelector = new ChiSqSelector()
.setNumTopFeatures(1)
.setFeaturesCol("feature")
.setLabelCol("makeup")
.setOutputCol("selectFeatures");
ChiSqSelectorModel fit = chiSqSelector.fit(df);
//根据算法计算, 选择的到底是features中的哪一列,这里保存的是索引
//gender hobby age salary 这几列是features列
//如果ints 存的是0,代表选择了gender列,如果是0,1代表选择了gender hobby两列
int[] ints = fit.selectedFeatures();
Dataset result = fit.transform(df);
result.show();
}
说明根据计算,选择了features中的第一列(gender), 那么就说明, makeup这列的值, 是与gender这列的值有很大关系的, 那么经过卡方特征选择后得到的特征与我们自己猜测的一致。
+——————–+——-+————–+
| feature|makeup|selectFeatures|
+——————–+——-+————–+
|[1.0,2.0,22.0,222…| 1.0| [1.0]|
|[1.0,2.0,22.0,222…| 1.0| [1.0]|
|[1.0,3.0,22.0,232…| 1.0| [1.0]|
|[1.0,3.0,22.0,323…| 1.0| [1.0]|
|[1.0,4.0,22.0,444…| 0.0| [1.0]|
|[0.0,9.0,22.0,345…| 0.0| [0.0]|
|[0.0,9.0,22.0,435…| 0.0| [0.0]|
|[0.0,6.0,22.0,436…| 0.0| [0.0]|
|[0.0,5.0,22.0,234…| 0.0| [0.0]|
|[1.0,5.0,22.0,456…| 1.0| [1.0]|
+——————–+——-+————–+