pyspark之MLlib学习【数据统计】(2)

来源:互联网 发布:js 继承 阮一峰 编辑:程序博客网 时间:2024/05/21 17:46

pyspark系列文章是本人根据《PySpark实战指南》学习pyspark中学习笔记,这本书是一本译文,有些地方感觉有点小问题,不过在本人的这些笔记中都是亲自测试跑通后的小例子。仅作参考和学习。

在前一篇文章中,我们已经清理我们的原始数据,本文将了解数据的各种统计信息。

1.基本统计

在spark的DataFrame中通过.discribe()方法实现数据的各种统计信息,但在使用MLib时则采用.colStats()方法。该方法使用RDD的数据来计算MultivariateStatisticalSummary对象的描述性统计信息,并返回MultivariateStatisticalSummary

  • count():行数
  • max():列中的最大值
  • mean():列中所有值的平均值
  • min():列中的最小值
  • normL1():列中值的L1-Norm值
  • normL2():列中值的L2-Norm值
  • numNonzeros():列中非零值的数量
  • variance():列中值的方差
  • ......
#计算数字特征的统计特性import pyspark.mllib.stat as stimport numpy as npnumeric_cols = ['MOTHER_AGE_YEARS','FATHER_COMBINED_AGE',    'CIG_BEFORE','CIG_1_TRI','CIG_2_TRI','CIG_3_TRI',    'MOTHER_HEIGHT_IN','MOTHER_PRE_WEIGHT',    'MOTHER_DELIVERY_WEIGHT','MOTHER_WEIGHT_GAIN']numeric_rdd = births_transformed.select(numeric_cols).rdd.map(lambda row: [e for e in row])mllib_stats = st.Statistics.colStats(numeric_rdd)for col,m,v in zip(numeric_cols,mllib_stats.mean(),mllib_stats.variance()):    print ('{0}: \t {1:.2f} \t {2:.2f}'.format(col,m,np.sqrt(v)) )
MOTHER_AGE_YEARS:    28.30      6.08FATHER_COMBINED_AGE:    44.55      27.55CIG_BEFORE:     1.43   5.18CIG_1_TRI:      0.91   3.83CIG_2_TRI:      0.70   3.31CIG_3_TRI:      0.58   3.11MOTHER_HEIGHT_IN:   65.12      6.45MOTHER_PRE_WEIGHT:      214.50     210.21MOTHER_DELIVERY_WEIGHT:     223.63     180.01MOTHER_WEIGHT_GAIN:     30.74      26.23
从结果中我们可以看出:与父亲相比,母亲的年龄更小:母亲的平均年龄是28岁,而父亲的平均年龄则超过44岁;且许多母亲怀孕后开始戒烟了(这对宝宝来说是一个好的现象);而令人吃惊的是,有些母亲在怀孕后仍持续吸烟。

对于分类变量,我们将计算其值的频率:

#查看分类变量的统计特性categorical_cols = [e for e in births_transformed.columns if e not in numeric_cols]categorical_rdd = births_transformed.select(categorical_cols).rdd.map(lambda row : [e for e in row])for i,col in enumerate(categorical_cols):    agg = categorical_rdd.groupBy(lambda row:row[i]).map(lambda row :(row[0],len(row[1])))    print (col,sorted(agg.collect(),key=lambda e1:e1[1],reverse=True))
('INFANT_ALIVE_AT_REPORT', [(1, 23349), (0, 22080)])('BIRTH_PLACE', [(u'1', 44558), (u'4', 327), (u'3', 224), (u'2', 136), (u'7', 91), (u'5', 74), (u'6', 11), (u'9', 8)])('DIABETES_PRE', [(0, 44881), (1, 548)])('DIABETES_GEST', [(0, 43451), (1, 1978)])('HYP_TENS_PRE', [(0, 44348), (1, 1081)])('HYP_TENS_GEST', [(0, 43302), (1, 2127)])('PREV_BIRTH_PRETERM', [(0, 43088), (1, 2341)])
从结果中可以看出,大部分的生产是在医院里(BIRTH_PLACE为1);大约550例的生产是在家中:其中有些是计划好的(BIRTH_PLACE为3),而有些不是(BIRTH_PLACE为4)

2.相关性

相关性有助于识别特征之间的关联性。下面我们将检查前面数据的性关系。

  • 计算相关性矩阵,且只打印相关系数大于5的特征。

#计算相关性,且只打印相关系数大于0.5的特征corrs = st.Statistics.corr(numeric_rdd)for i ,e1 in enumerate(corrs>0.5):    correlated = [        (numeric_cols[j],corrs[i][j])for j,e in enumerate(e1) if e == 1.0 and j != i    ]    if len(correlated)>0:        for e in correlated:            print ('{0}-to-{1}: {2:.2f}'.format(numeric_cols[i],e[0],e[1]))
CIG_BEFORE-to-CIG_1_TRI: 0.83CIG_BEFORE-to-CIG_2_TRI: 0.72CIG_BEFORE-to-CIG_3_TRI: 0.62CIG_1_TRI-to-CIG_BEFORE: 0.83CIG_1_TRI-to-CIG_2_TRI: 0.87CIG_1_TRI-to-CIG_3_TRI: 0.76CIG_2_TRI-to-CIG_BEFORE: 0.72CIG_2_TRI-to-CIG_1_TRI: 0.87CIG_2_TRI-to-CIG_3_TRI: 0.89CIG_3_TRI-to-CIG_BEFORE: 0.62CIG_3_TRI-to-CIG_1_TRI: 0.76CIG_3_TRI-to-CIG_2_TRI: 0.89MOTHER_PRE_WEIGHT-to-MOTHER_DELIVERY_WEIGHT: 0.54MOTHER_PRE_WEIGHT-to-MOTHER_WEIGHT_GAIN: 0.65MOTHER_DELIVERY_WEIGHT-to-MOTHER_PRE_WEIGHT: 0.54MOTHER_DELIVERY_WEIGHT-to-MOTHER_WEIGHT_GAIN: 0.60MOTHER_WEIGHT_GAIN-to-MOTHER_PRE_WEIGHT: 0.65MOTHER_WEIGHT_GAIN-to-MOTHER_DELIVERY_WEIGHT: 0.60
从结果中可以看出“CIG_...”的相关特征是高度相关的。由于我们要预测婴儿的生存几率,所以我们只会保留“CIG_1_TR1"特征,且重量特征也是高度相关的,在此我们只会保留“MOTHER_PRE_WEIGHT”

#需要保留的特征features_to_keep = [    'INFANT_ALIVE_AT_REPORT',    'MOTHER_AGE_YEARS',    'FATHER_COMBINED_AGE',    'CIG_1_TRI',    'MOTHER_HEIGHT_IN',    'MOTHER_PRE_WEIGHT',     'DIABETES_PRE',    'DIABETES_GEST',    'HYP_TENS_PRE',    'HYP_TENS_GEST',    'PREV_BIRTH_PRETERM'    ],births_transformed = births_transformed.select([e for e in features_to_keep])
3.统计测试

我们无法计算分类特征的相关性。然而,我们可以进行卡方检验来确定是否存在显著差异。

import pyspark.mllib.linalg as lnfor cat in categorical_cols[1:]:    agg = births_transformed.groupBy('INFANT_ALIVE_AT_REPORT').pivot(cat).count()    agg_rdd = agg.rdd.map(lambda row:                          [0 if e == None else e for e in row]).collect()    row_length = len(agg.collect()[0]) -1    agg = ln.Matrices.dense(row_length,2,agg_rdd)    test = st.Statistics.chiSqTest(agg)    print cat,round(test.pValue,4)spark.stop()
循环遍历所有的分类变量,并通过“INFANT_ALIVE_AT_REPORT”特征进行转换,以获取计数。接下来,我们将其转换为RDD,因此我们可以使用pyspark.mllib.linalg模块

将它们转换成矩阵。

.Matrices.dende()方法的第一个参数指定矩阵的行数,本例子中是分类特征的不同值的长度;第二个参数是指列数,因为我们的“INFANT_ALIVE_AT_REPORT”目标变量只有两个值,所以列为二;最后一个参数是要转换为矩阵的值的列表。

例如:

print (ln.Matrices.dense(3,2,[1,2,3,4,5,6]))
DenseMatrix([[ 1.,  4.],             [ 2.,  5.],             [ 3.,  6.]])

一旦我们以矩阵的形式存放我们的计数,那么我们可以使用.chiSqTest()方法来计算我们需要的结果。

BIRTH_PLACE 0.0DIABETES_PRE 0.0DIABETES_GEST 0.0HYP_TENS_PRE 0.0HYP_TENS_GEST 0.0PREV_BIRTH_PRETERM 0.0

阅读全文
0 0
原创粉丝点击