ml计数器矢量器输出说明

8mmmxcuj  于 2021-07-09  发布在  Spark
关注(0)|答案(1)|浏览(338)

请帮助理解spark ml countvectorizer的输出,并建议哪些文档对其进行了解释。

  1. val cv = new CountVectorizer()
  2. .setInputCol("Tokens")
  3. .setOutputCol("Frequencies")
  4. .setVocabSize(5000)
  5. .setMinTF(1)
  6. .setMinDF(2)
  7. val fittedCV = cv.fit(tokenDF.select("Tokens"))
  8. fittedCV.transform(tokenDF.select("Tokens")).show(false)

2374应该是词典中的术语(单词)数。什么是“[2,63285481234]”?
它们是字典中“[航空公司,包,年份,世界,冠军]”的索引吗?如果是这样,为什么同一个单词“airline”在第二行有不同的索引“0”?

  1. +------------------------------------------+----------------------------------------------------------------+
  2. |Tokens |Frequencies |
  3. +------------------------------------------+----------------------------------------------------------------+
  4. ...
  5. |[airline, bag, vintage, world, champion] |(2374,[2,6,328,548,1234],[1.0,1.0,1.0,1.0,1.0]) |
  6. |[airline, bag, vintage, jet, set, brown] |(2374,[0,2,6,328,405,620],[1.0,1.0,1.0,1.0,1.0,1.0]) |
  7. +------------------------------------------+----------------------------------------------------------------+
  8. [1]: https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.ml.feature.CountVectorizer
tvz2xvvm

tvz2xvvm1#

有一些医生在解释基础知识。然而,这是相当赤裸裸的。
对。数字代表词汇索引中的单词。但是,频率向量中的顺序与令牌向量中的顺序不对应。 airline, bag, vintage 在两行中,因此它们对应于索引[2,6328]。但你不能依赖同样的顺序。
行数据类型是sparsevector。第一个数组显示索引,第二个数组显示值。
例如

  1. vector[328]
  2. => 1.0

Map可以如下所示:

  1. vocabulary
  2. airline 328
  3. bag 6
  4. vintage 2
  5. Frequencies
  6. 2734, [2, 6 ,328], [99, 5, 7]
  7. # counts
  8. vintage x 99
  9. bag x 5
  10. airline 7

为了找回单词,你可以在词汇表中进行查找。这需要广播给不同的工人。您可能还希望将每个文档的计数分解为单独的行。
这里有一些 python 代码片段,用于使用自定义项将每个文档的前25个常用词提取到单独的行中,并计算每个词的平均值

  1. import pyspark.sql.types as T
  2. import pyspark.sql.functions as F
  3. from pyspark.sql import Row
  4. vocabulary = sc.broadcast(fittedCV.vocabulary)
  5. def _top_scores(v):
  6. # create count tuples for each index(i) in a vector(v)
  7. # `.item()` is used, because in python the count value is a numpy datatype, in `scala` it will be just double
  8. counts = [Row(i=i.item(),count=v[i.item()].item()) for i in v.indices]
  9. # => [Row(i=2, count=30, Row(i=362, count=40)]
  10. # return 25 top count rows
  11. counts = sorted(counts, reverse=True, key=lambda x: x.count)
  12. return counts[:25]
  13. top_scores = F.udf(_top_scores, T.ArrayType(T.StructType().add('i', T.IntegerType()).add('count', T.DoubleType())))
  14. vec_to_word = F.udf(_vecToWord, T.StringType())
  15. def _vecToWord(i):
  16. return vocabulary.value[i]
  17. res = df.withColumn('word_count', explode(top_scores('Frequencies')))
  18. =>
  19. +-----+-----+----------+
  20. doc_id, ..., word_count
  21. (i, count)
  22. +-----+-----+----------+
  23. 4711, ..., (2, 30.0)
  24. 4711, ..., (362, 40.0)
  25. +-----+-----+----------+
  26. res = res \
  27. .groupBy('word_count.i').agg( \
  28. avg('word_count.count').alias('mean')
  29. .orderBy('mean', ascending=False)
  30. res = res.withColumn('token', vec_to_word('i'))
  31. =>
  32. +---+---------+----------+
  33. i, token, mean
  34. +---+---------+----------+
  35. 2, vintage, 15
  36. 328, airline, 30
  37. +--+----------+----------+
展开查看全部

相关问题