【spark ML系列】Vectors向量上进行矢量化统计的工具

【spark ML系列】Vectors上进行矢量化统计的工具点击这里看全文

一、原理

Spark的Summarizer源码是用于在MLlib Vectors上进行矢量化统计的工具。它提供了一组方法,用于计算给定列的摘要统计信息。

首先,Summarizer中的metrics方法接受一组指标,并返回一个构建器对象SummaryBuilder。该构建器对象用于计算列的指标。

SummaryBuilder中,根据用户请求的指标,调用summary方法返回一个聚合列,包含所请求指标的列的摘要统计信息。summary方法使用MetricsAggregate实现聚合操作,并返回一个Column对象。

MetricsAggregate是一个TypedImperativeAggregate的实现类,负责执行具体的统计计算。它根据用户请求的指标和计算度量,在输入数据上进行聚合计算,并将结果封装成InternalRow对象。

SummarizerBuffer是一个用于存储和更新统计数据的辅助类。它包含各种变量和方法,用于计算并存储每个指标的结果。在每次添加新样本或合并多个SummarizerBuffer时,都会更新统计数据。

最后,用户可以根据需要选择性地调用Summarizer中提供的方法,获取特定指标的统计结果。

总体而言,Summarizer源码通过组合和调用不同的类和方法,实现了在MLlib Vectors上进行矢量化统计的功能。它提供了灵活和高效的统计计算方法,方便用户对数据进行摘要分析。

二、功能用法

1.SummaryBuilder

用于提供有关给定列的摘要统计信息的构建器对象。

用户不应直接创建这样的构建器,而应使用Summarizer中的方法之一。

2.Summarizer

用于在MLlib Vectors上进行矢量化统计的工具。

该包中的方法为DataFrames中包含的Vectors提供了各种统计数据。

此类使用户可以选择他们想要从给定列提取的统计信息。以下是Scala中的示例:

import org.apache.spark.ml.linalg._
import org.apache.spark.sql.Row
val dataframe = ... // 包含特征列和权重列的DataFrame
val multiStatsDF = dataframe.select(
    Summarizer.metrics("min", "max", "count").summary($"features", $"weight")
val Row(minVec, maxVec, count) = multiStatsDF.first()

如果只想获取单个指标,则还提供了快捷方式:

val meanDF = dataframe.select(Summarizer.mean($"features"))
val Row(meanVec) = meanDF.first()

注意:当前,使用此接口的性能约为使用RDD接口的2倍至3倍。

3.metrics

给定一组指标,提供一个构建器,用于计算列的指标。

请参阅Summarizer的文档以获取示例。

接受以下指标(区分大小写):

  • mean: 包含按系数求平均值的向量。
  • sum: 包含按系数求和的向量。
  • variance: 包含按系数求方差的向量。
  • std: 包含按系数求标准差的向量。
  • count: 观察到的向量总数。
  • numNonzeros: 每个系数的非零数量向量
  • max: 每个系数的最大值。
  • min: 每个系数的最小值。
  • normL2: 每个系数的欧几里德范数。
  • normL1: 每个系数的L1范数(绝对值之和)。

4.mean

获取给定列的平均值。

5.sum

获取给定列的总和。

6.variance

获取给定列的方差。

7.std

获取给定列的标准差。

8.count

获取给定列的观察到的向量总数。

9.numNonZeros

获取给定列中每个系数的非零数量。

10.max

获取给定列中每个系数的最大值。

11.min

获取给定列中每个系数的最小值。

12.normL1

获取给定列中每个系数的L1范数(绝对值之和)。

13.normL2

获取给定列中每个系数的欧几里德范数。

三、示例

package org.example.spark

import org.apache.spark.ml.stat.Summarizer
import org.apache.spark.sql.functions.lit
import org.apache.spark.sql.{
   Row, SparkSession}
 
object VectorStatExample {
   
  def main(args: Array[String]): Unit = {
   
    // 创建SparkSession
    val spark = SparkSession.builder()
      .appName("VectorStatExample")
      .master("local[*]")
      .getOrCreate()

    // 加载数据集
    val vecData = spark.read.format("libsvm")
      .load("D:\\work\\src\\sparkall\\spark-2.4.0\\spark-2.4.0\\data\\mllib\\sample_linear_regression_data.txt")
      .withColumn("weight",lit(1.0))
    import org.apache.spark.sql.functions.col

    /**
     * 获取单个指标
     */
    val meanDF = vecData.select(Summarizer.mean(col("features")).alias( "vec_mean"))
    val Row(meanVec) = meanDF.first()

    println("meanVec="+meanVec)

    /**
     * 从给定向量列提取的统计信息
     */
    val multiStatsDF = vecData.select(
      Summarizer.metrics("min", "max", "count").summary(col("features"),col("weight") ).alias("vec_stat")
    ).select("vec_stat.min","vec_stat.max","vec_stat.count")

    val Row(minVec , maxVec, count) = multiStatsDF.first()
    println("minVec="+minVec+"\n maxVec="+maxVec+"\ncount="+count)

    // 关闭SparkSession
    spark.stop()
  }
}
//meanVec=[0.018333248314819788,0.028086075973169845,0.018246937236849677,0.057697144268681534,-0.023457518227654153,-0.023676137051387665,0.012449307729786111,0.024422549927171893,-0.00822425472262257,0.022538317316159982]
//minVec=[-0.9919593184325572,-0.9981936663594053,-0.9993240281686275,-0.9982007415355478,-0.9950315917350652,-0.9996126872234177,-0.994819896842561,-0.9942304127133292,-0.9975425877998279,-0.9992933613402135]
//maxVec=[0.9990215581592679,0.9990094335332504,0.9949216290375054,0.9917728248530817,0.9974035542095165,0.9993906921393696,0.9992936758550379,0.9995670294711712,0.9938658554834845,0.9917688731048739]
//count=501

四、源码分析

SummaryBuilder

/**
 * 用于计算列的摘要统计信息的构建器对象。
 *
 * 用户不应直接创建此类的实例,而应使用`Summarizer`中的方法之一。
 */
@Since("2.3.0")
sealed abstract class SummaryBuilder {
   
  /**
   * 返回一个聚合对象,其中包含具有所请求指标的列的摘要统计信息。
   *
   * @param featuresCol 包含特征向量对象的列。
   * @param weightCol 包含权重值的列。默认权重为1.0。
   * @return 一个包含统计信息的聚合列。此结构的确切内容在构建器创建过程中确定。
   */
  @Since("2.3.0")
  def summary(featuresCol: Column, weightCol: Column): Column

  /**
   * 使用默认权重值调用`summary`方法。
   *
   * @param featuresCol 包含特征向量对象的列。
   * @return 一个包含统计信息的聚合列。此结构的确切内容在构建器创建过程中确定。
   */
  @Since("2.3.0")
  def summary(featuresCol: Column): Column = summary(featuresCol, lit(1.0))

}

object Summarizer

/**
 * 用于对MLlib向量进行向量化统计的工具。
 *
 * 这个类允许用户选择他们想要提取的给定列的统计信息。
 以下是一个示例:
 * {
   {
   {
 *   import org.apache.spark.ml.linalg._
 *   import org.apache.spark.sql.Row
 *   val dataframe = ... // 一个包含特征列和权重列的DataFrame
 *   val multiStatsDF = dataframe.select(
 *       Summarizer.metrics("min", "max", "count").summary($"features", $"weight")
 *   val Row(minVec, maxVec, count) = multiStatsDF.first()
 * }}}
 *
 * 如果只想获取单个统计指标,也可以使用快捷方式:
 * {
   {
   {
 *   val meanDF = dataframe.select(Summarizer.mean($"features"))
 *   val Row(meanVec) = meanDF.first()
 * }}}
 *
 * 注意:目前,使用此接口的性能约为RDD接口的2倍到3倍。
 */
@Since("2.3.0")
object Summarizer extends Logging {
   

  import SummaryBuilderImpl._

  /**
   * 给定一组指标,提供一个构建器,用于计算列的指标。
   *
   * 可以提供以下指标(区分大小写):
   *  - mean: 包含逐个系数的均值向量。
   *  - sum: 包含逐个系数的求和向量。
   *  - variance: 包含逐个系数的方差向量。
   *  - std: 包含逐个系数的标准差向量。
   *  - count: 观察到的向量数量。
   *  - numNonzeros: 每个系数的非零值数量的向量。
   *  - max: 每个系数的最大值。
   *  - min: 每个系数的最小值。
   *  - normL2: 每个系数的欧氏范数。
   *  - normL1: 每个系数的L1范数(绝对值之和)。
   *
   * @param metrics 可以提供的指标。
   * @return 一个构建器。
   * @throws IllegalArgumentException 如果其中一个指标名称无法识别。
   */
  @Since("2.3.0")
  @scala.annotation.varargs
  def metrics(metrics: String*): SummaryBuilder = {
   
    require(metrics.nonEmpty, "至少应包含一个指标")
    val (typedMetrics, computeMetrics) = getRelevantMetrics(metrics)
    new SummaryBuilderImpl(typedMetrics, computeMetrics)
  }

  @Since("2.3.0")
  def mean(col: Column, weightCol: Column): Column = {
   
    getSingleMetric(col, weightCol, "mean")
  }

  @Since("2.3.0")
  def mean(col: Column): Column = mean(col, lit(1.0))

  @Since("3.0.0")
  def sum(col: Column, weightCol: Column): Column = {
   
    getSingleMetric(col, weightCol, "sum")
  }

  @Since("3.0.0")
  def sum(col: Column): Column = sum(col, lit(1.0))

  @Since("2.3.0")
  def variance(col: Column, weightCol: Column): Column = {
   
    getSingleMetric(col, weightCol, "variance")
  }

  @Since("2.3.0")
  def variance(col: Column): Column = variance(col, lit(1.0))

  @Since("3.0.0")
  def std(col: Column, weightCol: Column): Column = {
   
    getSingleMetric(col, weightCol, "std")
  }

  @Since("3.0.0")
  def std(col: Column): Column = std(col, lit(1.0))

  @Since("2.3.0")
  def count(col: Column, weightCol: Column): Column = {
   
    getSingleMetric(col, weightCol, "count")
  }

  @Since("2.3.0")
  def count(col: Column): Column = count(col, lit(1.0))

  @Since("2.3.0")
  def numNonZeros(col: Column, weightCol: Column): Column = {
   
    getSingleMetric(col, weightCol, "numNonZeros")
  }

  @Since("2.3.0")
  def numNonZeros(col: Column)
  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BigDataMLApplication

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值