【问题标题】:How to normalize or standardize the data having multiple columns/variables in spark using scala?如何使用scala规范化或标准化spark中具有多列/变量的数据?
【发布时间】:2018-06-19 23:37:44
【问题描述】:

我是 apache spark 和 scala 的新手。我有这样的数据集,我从 csv 文件中获取并使用 scala 将其转换为 RDD。

+-----------+-----------+----------+
| recent    | Freq      | Monitor  |
+-----------+-----------+----------+
|        1  |       1234 |   199090|
|        4  |       2553|    198613|
|        6  |       3232 |   199090|
|        1  |       8823 |   498831|
|        7  |       2902 |   890000|
|        8  |       7991 |   081097|
|        9  |       7391 |   432370|
|        12 |       6138 |   864981|
|        7  |       6812 |   749821|
+-----------+-----------+----------+

我想计算 z-score 值或标准化数据。所以我正在计算每列的 z 分数,然后尝试将它们组合起来,这样我就得到了标准比例。

这是我计算第一列 z 分数的代码

val scores1 = sorted.map(_.split(",")(0)).cache
val count = scores.count
val mean = scores.sum / count
val devs = scores.map(score => (score - mean) * (score - mean))
val stddev = Math.sqrt(devs.sum / count)
val zscore = sorted.map(x => math.round((x.toDouble - mean)/stddev)) 

如何计算每一列?或者有没有其他方法来规范化或标准化数据?

我的要求是分配等级(或等级)。

谢谢

【问题讨论】:

    标签: scala apache-spark statistics


    【解决方案1】:

    如果要标准化列,可以使用 Spark MLlib 中的 StandardScaler 类。数据应采用RDD[Vectors[Double] 的形式,其中向量是MLlib Linalg 包的一部分。您可以选择使用均值或标准差或两者来标准化您的数据。

    import org.apache.spark.mllib.feature.StandardScaler
    import org.apache.spark.mllib.linalg.Vectors
    
    val data = sc.parallelize(Array(
        Array(1.0,2.0,3.0),
        Array(4.0,5.0,6.0),
        Array(7.0,8.0,9.0),
        Array(10.0,11.0,12.0)))
    
    // Converting RDD[Array] to RDD[Vectors]
    val features = data.map(a => Vectors.dense(a))
    // Creating a Scaler model that standardizes with both mean and SD
    val scaler = new StandardScaler(withMean = true, withStd = true).fit(features)
    // Scale features using the scaler model
    val scaledFeatures = scaler.transform(features)
    

    这个scaledFeatures RDD 包含所有列的 Z-score。

    希望这个答案有帮助。查看文档以获取更多信息。

    【讨论】:

    • 谢谢。我用你的数据运行你的代码,它工作正常,但是当尝试使用整数数据时,我遇到了错误
    • scala> val features = data.map(a => Vectors.dense(a)) :25: 错误:重载方法值密集与替代:(值:数组 [双]) org.apache.spark.mllib.linalg.Vector (firstValue: Double,otherValues: Double*)org.apache.spark.mllib.linalg.Vector 不能应用于 (Array[_24]) val features = data。 map(a => Vectors.dense(a))'
    • 是的,MLlib 向量不能用于整数类型。因此,在将数组转换为向量之前,您应该将所有值转换为 Double。
    • 好的,谢谢。只是一个简单的问题,我想对这些数据进行排名,所以我需要通过对数据进行排序然后规范化来对其进行排名,反之亦然。对不起,我只是对排名感到困惑。
    • 如果有帮助,请接受此问题的答案。 :) 首先或最后对其进行排序不会对您获得的结果产生任何影响。
    【解决方案2】:

    您可能希望使用以下代码对所需列执行标准缩放。向量汇编器用于选择需要转换的所需列。 StandardScaler 构造函数还为您提供了选择平均值和标准差值的选项

    代码:

    import org.apache.spark.ml.feature.VectorAssembler
    import org.apache.spark.ml.linalg.Vectors
    import org.apache.spark.ml.feature
    import org.apache.spark.ml.feature.StandardScaler
    
    val sqlContext = new org.apache.spark.sql.SQLContext(sc)
    val df = sqlContext.read.format("csv").option("header", "true").option("inferSchema", "true").load("/user/hadoop/data/your_dataset.csv")
    df.show(Int.MaxValue)
    
    val assembler = new VectorAssembler().setInputCols(Array("recent","Freq","Monitor")).setOutputCol("features")
    
    val transformVector = assembler.transform(df)
    
    val scaler = new StandardScaler().setInputCol("features").setOutputCol("scaledFeatures").setWithStd(true).setWithMean(false)
    
    val scalerModel = scaler.fit(transformVector)
    val scaledData = scalerModel.transform(transformVector)
    
    scaledData.show() 20, False
    scaledData.show(Int.MaxValue)
    scaledData.show(20, false)
    

    【讨论】:

    • 我正在尝试 MinMaxScaler,但需要几天时间才能完成。有更快的实现吗?
    猜你喜欢
    • 2017-10-19
    • 1970-01-01
    • 2018-01-04
    • 2018-10-14
    • 2018-10-30
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    相关资源
    最近更新 更多