Spark R公式解释

use*_*635 1 classification machine-learning apache-spark apache-spark-mllib

我正在阅读“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()
Run Code Online (Sandbox Code Playgroud)

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

“实验室”:“好”,“颜色”:“绿色”,“值1”:1,“值2”:14.386294994851129 “实验室”:“坏”,“颜色”:“蓝色”,“值1”:8,”值2":14.386294994851129"实验室":"坏","颜色":"蓝色","值1":12,"值2":14.386294994851129"实验室":"好","颜色":"绿色","值1" :15,“值2”: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.38629499485112 9、(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.38629499 4851129 ,12.0,14.386294994851129]) ,1.0]
[绿色,好,15,38.97187133755819, (10,[0,2,3,4,7],[1.0,15.0,38.97187133755819,15.0,38.9718713375581 9]) ,0.0]

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

Hri*_*iev 6

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

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

所以

(10,[0,2,3,4,7],[1.0,1.0,14.386294994851129,1.0,14.386294994851129])
Run Code Online (Sandbox Code Playgroud)

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

 0       2    3                   4          7
[1.0, 0, 1.0, 14.386294994851129, 1.0, 0, 0, 14.386294994851129, 0, 0]
Run Code Online (Sandbox Code Playgroud)

(显示非零元素的位置)

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

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

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)
Run Code Online (Sandbox Code Playgroud)

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

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

尽管您有三个类别,但只有两个用于编码。在这种情况下,蓝色会被丢弃,因为它的存在没有信息价值 - 如果它存在,所有三列的总和将始终为 1,这使得它们线性相关。删除蓝色类别的效果是,它成为截距的一部分的基线,并且拟合模型预测将类别从蓝色更改为绿色或从蓝色更改为红色会对标签产生什么影响。这种特定的编码选择有点随意——在我的系统上,红色绿色的列被交换了。

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

以下是读取第一行的方法:

(10,[0,2,3,4,7],[1.0,1.0,14.386294994851129,1.0,14.386294994851129])
Run Code Online (Sandbox Code Playgroud)

是稀疏向量表示

[1.0, 0, 1.0, 14.386294994851129, 1.0, 0, 0, 14.386294994851129, 0, 0]
 |--1--| |2|  |-------3--------|  |---4---|  |----------5-----------|
Run Code Online (Sandbox Code Playgroud)

其中包含以下各个组件:

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