Spark RFormula 解释

我在阅读《Spark 权威指南》时,遇到了 MLlib 章节中的一段代码,代码如下:

var df = spark.read.json("/data/simple-ml") df.orderBy("value2").show()import org.apache.spark.ml.feature.RFormula// 无法理解此公式的解释eval 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″lab”:”bad”,”color”:”blue”,”value1″:8,”value2″:14.386294994851129″lab”:”bad”,”color”:”blue”,”value1″:12,”value2″: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 找到完整的数据集,上述代码会产生以下输出:

[green,good,1,14.386294994851129,(10,[0,2,3,4,7],[1.0,1.0,14.386294994851129,1.0,14.386294994851129]),0.0]
[blue,bad,8,14.386294994851129,(10,[2,3,6,9],[8.0,14.386294994851129,8.0,14.386294994851129]),1.0]
[blue,bad,12,14.386294994851129,(10,[2,3,6,9],[12.0,14.386294994851129,12.0,14.386294994851129]),1.0]
[green,good,15,38.97187133755819,(10,[0,2,3,4,7],[1.0,15.0,38.97187133755819,15.0,38.97187133755819]),0.0]

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


回答:

第五列是 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]

(显示了非零元素的位置)

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

RFormula 生成一个特征的向量列和一个标签的双精度或字符串列。就像在 R 中用于线性回归的公式一样,字符串输入列将被独热编码,数值列将被转换为双精度。如果标签列是字符串类型,它将首先通过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)

为了便于阅读,我已将输出分行并缩进。因此. + color:value1 + color:value2展开为[color,value1,value2,{color,value1},{color,value2}]。其中,color是一个分类特征,它通过以下映射被独热编码为一组指示特征:

  • green变为[1, 0]
  • blue变为[0, 0]
  • red变为[0, 1]

虽然你有三个类别,但只有两个用于编码。在这种情况下,blue被丢弃,因为它的存在没有信息价值 – 如果它存在,所有三个列将始终总和为1,这使它们线性相关。丢弃blue类别的效果是它成为截距的一部分,作为基线,拟合模型预测从blue更改为green或从blue更改为red对标签的影响。这种编码的选择有点随意 – 在我的系统上,redgreen的列顺序被交换了。

value1value2是双精度数,因此它们在特征向量中保持不变。{color,value1}color特征和value1特征的乘积,因此是color的独热编码与标量value1的乘积,产生三个新特征。请注意,在这种情况下,我们不能丢弃一个类别,因为交互作用使得“基准”值依赖于交互中的第二个特征的值。同样的情况也适用于{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的独热编码(减去线性相关的第三个类别)
  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. [..., 14.386294994851129, 0, 0]color x value2交互项,green的独热编码([1, 0, 0])和14.38629…的乘积

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注