Kai*_*Kai 22 apache-spark apache-spark-ml apache-spark-mllib
试图在Spark中进行doc分类.我不确定HashingTF中的散列是做什么的; 它会牺牲任何准确性吗?我对此表示怀疑,但我不知道.spark文档说它使用了"散列技巧"......只是工程师使用的另一个非常糟糕/混乱命名的例子(我也很内疚).CountVectorizer还需要设置词汇量大小,但它有另一个参数,一个阈值参数,可用于排除出现在文本语料库中某个阈值以下的单词或标记.我不明白这两个变形金刚之间的区别.使这一点很重要的是算法中的后续步骤.例如,如果我想在生成的tfidf矩阵上执行SVD,那么词汇量大小将决定SVD矩阵的大小,这会影响代码的运行时间,以及模型性能等.我一般有困难在API文档之外找到关于Spark Mllib的任何来源以及没有深度的非常简单的例子.
zer*_*323 23
一些重要的区别:
CountVectorizer)vs不可逆(HashingTF) - 由于散列不可逆,因此无法从散列向量中恢复原始输入.另一方面,带有模型(索引)的计数向量可用于恢复无序输入.因此,使用散列输入创建的模型可能更难以解释和监视.HashingTF只需要一次数据扫描,并且不需要超出原始输入和向量的额外内存.CountVectorizer需要对数据进行额外扫描以构建模型和额外的内存来存储词汇(索引).在unigram语言模型的情况下,它通常不是问题,但是在更高的n-gram的情况下,它可能过于昂贵或不可行.HashingTF这种情况,可以减少可能的碰撞.CountVectorizer丢弃不常见的令牌.它如何影响下游模型取决于特定的用例和数据.pra*_*nth 13
根据Spark 2.1.0文档,
HashingTF和CountVectorizer都可用于生成术语频率向量.
HashingTF
HashingTF是一个Transformer,它接受一组术语并将这些集转换为固定长度的特征向量.在文本处理中,"一组术语"可能是一包单词.HashingTF利用散列技巧.通过应用散列函数将原始特征映射到索引(术语).这里使用的哈希函数是MurmurHash 3.然后,基于映射的索引计算术语频率.这种方法避免了计算全局术语到索引映射的需要,这对于大型语料库来说可能是昂贵的,但是它遭受潜在的哈希冲突,其中不同的原始特征可能在散列之后变成相同的术语.
为了减少冲突的可能性,我们可以增加目标要素维度,即哈希表的桶数.由于使用简单模来将散列函数转换为列索引,因此建议使用2的幂作为要素维,否则要素将不会均匀映射到列.默认要素尺寸为2 ^ 18 = 262,144.可选的二进制切换参数控制术语频率计数.设置为true时,所有非零频率计数都设置为1.这对于模拟二进制而非整数计数的离散概率模型特别有用.
CountVectorizer
CountVectorizer和CountVectorizerModel旨在帮助将文本文档集合转换为令牌计数向量.当a-priori字典不可用时,CountVectorizer可用作Estimator来提取词汇表,并生成CountVectorizerModel.该模型为词汇表上的文档生成稀疏表示,然后可以将其传递给其他算法,如LDA.
在拟合过程中,CountVectorizer将选择按语料库中的术语频率排序的顶级词汇量词.可选参数minDF还通过指定术语必须出现在文档中的最小数量(或<1.0)来影响拟合过程.另一个可选的二进制切换参数控制输出向量.如果设置为true,则所有非零计数都设置为1.这对于模拟二进制而非整数计数的离散概率模型尤其有用.
示例代码
from pyspark.ml.feature import HashingTF, IDF, Tokenizer
from pyspark.ml.feature import CountVectorizer
sentenceData = spark.createDataFrame([
(0.0, "Hi I heard about Spark"),
(0.0, "I wish Java could use case classes"),
(1.0, "Logistic regression models are neat")],
["label", "sentence"])
tokenizer = Tokenizer(inputCol="sentence", outputCol="words")
wordsData = tokenizer.transform(sentenceData)
hashingTF = HashingTF(inputCol="words", outputCol="Features", numFeatures=100)
hashingTF_model = hashingTF.transform(wordsData)
print "Out of hashingTF function"
hashingTF_model.select('words',col('Features').alias('Features(vocab_size,[index],[tf])')).show(truncate=False)
# fit a CountVectorizerModel from the corpus.
cv = CountVectorizer(inputCol="words", outputCol="Features", vocabSize=20)
cv_model = cv.fit(wordsData)
cv_result = model.transform(wordsData)
print "Out of CountVectorizer function"
cv_result.select('words',col('Features').alias('Features(vocab_size,[index],[tf])')).show(truncate=False)
print "Vocabulary from CountVectorizerModel is \n" + str(cv_model.vocabulary)
Run Code Online (Sandbox Code Playgroud)
输出如下
Hashing TF错过了对LDA等技术至关重要的词汇表.为此,必须使用CountVectorizer功能.无论词汇大小如何,CountVectorizer函数估计术语频率而不涉及任何近似值,这与HashingTF不同.
参考:
https://spark.apache.org/docs/latest/ml-features.html#tf-idf
https://spark.apache.org/docs/latest/ml-features.html#countvectorizer
哈希技巧实际上是功能哈希的另一个名称。
我在引用Wikipedia的定义:
在机器学习中,类似于内核技巧,特征哈希(也称为哈希技巧)是对特征进行矢量化的一种快速且节省空间的方法,即将任意特征转换为向量或矩阵中的索引。它通过对特征应用哈希函数并直接将其哈希值用作索引来工作,而不是在关联数组中查找索引。
您可以在本文中了解更多信息。
因此实际上实际上是为了空间高效的特征向量化。
而CountVectorizer仅执行词汇提取并将其转换为Vector。
| 归档时间: |
|
| 查看次数: |
10769 次 |
| 最近记录: |