【问题标题】:Spark RFormula InterpretationSpark R公式解释
【发布时间】:2020-04-19 01:29:47
【问题描述】:

我正在阅读“Spark The Definitive Guide”,我在 MLlib 章节中遇到了一个代码部分,其中包含以下代码:

var df = spark.read.json("/data/simple-ml") 
df.orderBy("value2").show()
import org.apache.spark.ml.feature.RFormula
// Unable to understand the interpretation of this formulae
val supervised = new RFormula().setFormula("lab ~ . + color:value1 + color:value2")
val fittedRF = supervised.fit(df)
val preparedDF = fittedRF.transform(df) 
preparedDF.show()

其中 /data/simple-ml 包含一个 JSON 文件,其中包含(例如):-

"lab":"good","color":"green","value1":1,"value2":14.386294994851129 “实验室”:“坏”,“颜色”:“蓝色”,“值 1”:8,“值 2”:14.386294994851129 “实验室”:“坏”,“颜色”:“蓝色”,“值 1”:12,“值 2”:14.386294994851129 "lab":"good","color":"green","value1":15,"value2":38.9718713375581

您可以在https://github.com/databricks/Spark-The-Definitive-Guide/blob/master/data/simple-ml/part-r-00000-f5c243b9-a015-4a3b-a4a8-eca00f80f04c.json 找到完整的数据集 以上行产生的输出为:-

[绿色,好,1,14.386294994851129,(10,[0,2,3,4,7],[1.0,1.0,14.386294994851129,1.0,14.386294994851129]),0.0] [蓝色,坏,8,14.386294994851129,(10,[2,3,6,9],[8.0,14.386294994851129,8.0,14.386294994851129]),1.0]
[蓝色,坏,12,14.386294994851129,(10,[2,3,6,9],[12.0,14.386294994851129,12.0,14.386294994851129]),1.0]
[绿色,好,15,38.97187133755819,(10,[0,2,3,4,7],[1.0,15.0,38.97187133755819,15.0,38.97187133755819]),0.0]

现在我无法理解它是如何计算第 5 列(以粗体标记)的值。

【问题讨论】:

    标签: apache-spark machine-learning classification apache-spark-mllib


    【解决方案1】:

    第 5 列是 Spark 中表示稀疏向量的结构。它包含三个组成部分:

    • 向量长度 - 在这种情况下,所有向量的长度都是 10 个元素
    • 包含非零元素索引的索引数组
    • 非零值的值数组

    所以

    (10,[0,2,3,4,7],[1.0,1.0,14.386294994851129,1.0,14.386294994851129])
    

    表示以下长度为10的稀疏向量(取第i个值并将其放在位置i):

     0       2    3                   4          7
    [1.0, 0, 1.0, 14.386294994851129, 1.0, 0, 0, 14.386294994851129, 0, 0]
    

    (显示非零元素的位置)

    该向量的各个组成部分是什么?根据documentation

    RFormula 生成特征向量列和标签的双精度列或字符串列。就像在 R 中使用公式进行线性回归一样,字符串输入列将被一次性编码,而数字列将被转换为双精度值。如果标签列是字符串类型,它将首先转换为带有StringIndexer 的双精度。如果 DataFrame 中不存在 label 列,则从公式中指定的响应变量创建输出 label 列。

    lab ~ . + color:value1 + color:value2 是一种来自 R 语言的特殊语法。它描述了一个模型,该模型将 lab 的值回归到所有其他功能以及两个交互(产品)项上。您可以通过打印fittedRF 并查看其中包含的ResolvedRFormula 实例来查看所有功能的列表:

    scala> println(fittedRF)
    RFormulaModel(
     ResolvedRFormula(
      label=lab,
      terms=[color,value1,value2,{color,value1},{color,value2}],
      hasIntercept=true
     )
    ) (uid=rFormula_0847e597e817)
    

    为了便于阅读,我将输出分成几行并缩进。所以. + color:value1 + color:value2 扩展为[color,value1,value2,{color,value1},{color,value2}]。其中,color 是一个分类特征,它使用以下映射在一组指标特征中进行单热编码:

    • 绿色变成[1, 0]
    • 蓝色变成[0, 0]
    • 红色变成[0, 1]

    虽然您有三个类别,但只有两个用于编码。在这种情况下,Blue 会被删除,因为它的存在没有信息值 - 如果它存在,所有三列的总和将始终为 1,这使得它们线性相关。删除 blue 类别的效果是它成为基线作为截距的一部分,拟合模型预测将类别从 blue 更改为 green 或从 bluered 都会有标签。这种特殊的编码选择有点随意——在我的系统上,redgreen 的列被交换了。

    value1value2 是双精度数,因此它们在特征向量中保持不变。 {color,value1}color 功能和value1 功能的乘积,因此是color 与标量value1 的one-hot 编码的乘积,产生了三个新功能。请注意,在这种情况下,我们不能删除一个类别,因为交互使“基础”值依赖于交互中第二个特征的值。 {color,value2} 也一样。所以你最终得到了 2 + 1 + 1 + 3 + 3 或 10 个特征。您在show() 的输出中看到的是组装后的向量特征列,可以用作其他 Spark ML 类的输入。

    这里是如何读取第一行:

    (10,[0,2,3,4,7],[1.0,1.0,14.386294994851129,1.0,14.386294994851129])
    

    是的稀疏向量表示

    [1.0, 0, 1.0, 14.386294994851129, 1.0, 0, 0, 14.386294994851129, 0, 0]
     |--1--| |2|  |-------3--------|  |---4---|  |----------5-----------|
    

    其中包含以下单个组件:

    1. [1.0, 0, ...] - color,类别 green 的 one-hot 编码(减去线性相关的第三类)
    2. [..., 1.0, ...] - value1,值 1
    3. [..., 14.386294994851129, ...] - value2,值 14,38629...
    4. [..., 1.0, 0, 0, ...] - color x value1 交互项,green ([1, 0, 0]) 和 1
    5. 的 one-hot 编码的产物
    6. [..., 14.386294994851129, 0, 0] - color x value2 交互项,green ([1, 0, 0]) 和 14,38629 的 one-hot 编码的产物...

    【讨论】:

    • 精彩的解释,除了为什么我们说蓝色被丢弃以及它如何成为基线之外,我能够理解每一个单词,请你也帮我理解这一点。
    • 想象一个基于一个分类变量的线性模型,它有两个类别:y = a0 + a1 * x1 + a2 * x2,其中x1x2 是每个类别的指标,as 是拟合的模型参数. x1x2 唯一可能的值是 x1 = 1x2 = 0(第 1 类)或 x1 = 0x2 = 1(第 2 类),因此它们的总和始终为 1。那么我们可以表示 @ 987654370@ 以x1x2 = 1 - x1,因此模型变为y = a0 + a1 * x1 + a2 * (1 - x1) = (a0 + a2) + (a1 - a2) * x1。现在在给定预测器类别的情况下查看y 的值:
    • 在原始模型中,当x1 = 1x2 = 0(第1 类)时,y = a0 + a1。如果x1 = 0x2 = 1(类别2),则y = a0 + a2。在我们将x2 表示为1 - x1 的情况下,我们有:当x1 = 1(第1 类)时,y = (a0 + a2) + (a1 - a2) = a0 + a1,当x1 = 0(第2 类)时,y = (a0 + a2)。所以我们得到相同的输出,但是现在x1之前的系数是a1 - a2,这正是起始模型中两个类别的权重之差。 x2 的系数被截距(或基值)吸收。现在只需对三个类别重复相同的操作即可。
    • x1x2 训练模型可以教会它分别识别一些基线和每个类别的权重。仅使用x1 训练模型会教它识别两个权重之间的差异并吸收截距(基线)中第二类的权重。请注意,后一种情况更“自然”,因为前一种中的基线是人为的 - 你不能让 x1x2 都等于 0,因此模型的输出永远不会是 a0
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 2017-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多