【问题标题】:From DataFrame to RDD[LabeledPoint]从 DataFrame 到 RDD[LabeledPoint]
【发布时间】:2015-09-04 17:01:25
【问题描述】:

我正在尝试使用 Apache Spark MLlib 实现文档分类器,但在表示数据时遇到了一些问题。我的代码如下:

import org.apache.spark.sql.{Row, SQLContext}
import org.apache.spark.sql.types.{StringType, StructField, StructType}
import org.apache.spark.ml.feature.Tokenizer
import org.apache.spark.ml.feature.HashingTF
import org.apache.spark.ml.feature.IDF

val sql = new SQLContext(sc)

// Load raw data from a TSV file
val raw = sc.textFile("data.tsv").map(_.split("\t").toSeq)

// Convert the RDD to a dataframe
val schema = StructType(List(StructField("class", StringType), StructField("content", StringType)))
val dataframe = sql.createDataFrame(raw.map(row => Row(row(0), row(1))), schema)

// Tokenize
val tokenizer = new Tokenizer().setInputCol("content").setOutputCol("tokens")
val tokenized = tokenizer.transform(dataframe)

// TF-IDF
val htf = new HashingTF().setInputCol("tokens").setOutputCol("rawFeatures").setNumFeatures(500)
val tf = htf.transform(tokenized)
tf.cache
val idf = new IDF().setInputCol("rawFeatures").setOutputCol("features")
val idfModel = idf.fit(tf)
val tfidf = idfModel.transform(tf)

// Create labeled points
val labeled = tfidf.map(row => LabeledPoint(row.getDouble(0), row.get(4)))

我需要使用数据框来生成令牌并创建 TF-IDF 功能。当我尝试将此数据帧转换为 RDD [LabeledPoint] 时出现问题。我映射了数据框行,但 Row 的 get 方法返回 Any 类型,而不是数据框架构(Vector)上定义的类型。因此,我无法构建训练 ML 模型所需的 RDD。

在计算 TF-IDF 后获得 RDD[LabeledPoint] 的最佳选择是什么?

【问题讨论】:

    标签: scala apache-spark apache-spark-mllib


    【解决方案1】:

    你需要使用getAs[T](i: Int): T

    // Create labeled points
    import org.apache.spark.mllib.linalg.{Vector, Vectors}
    val labeled = tfidf.map(row => LabeledPoint(row.getDouble(0), row.getAs[Vector](4)))
    

    【讨论】:

    • 我收到此错误:错误:类型参数(Vector)的种类不符合类型参数(T 类型)的预期种类。 Vector 的类型参数与类型 T 的预期参数不匹配:类型 Vector 有一个类型参数,但类型 T 没有
    • @Miguel 我遇到了同样的错误,并从here 找到了一个很好的修复方法。您需要显式导入 Spark Vector 类,因为 Scala 默认导入其内置的 Vector 类型。 import org.apache.spark.mllib.linalg.{Vector, Vectors} 然后 Chris 的代码就可以工作了。
    【解决方案2】:

    铸造对象对我有用。

    试试:

    // Create labeled points
    val labeled = tfidf.map(row => LabeledPoint(row.getDouble(0), row(4).asInstanceOf[Vector]))
    

    【讨论】:

      猜你喜欢
      • 2018-10-20
      • 2015-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-29
      • 1970-01-01
      • 2021-06-14
      • 1970-01-01
      相关资源
      最近更新 更多