基于最新2.2.0版本翻译
本节介绍和特征一起工作的算法,大致分为以下几类:提取:从原始数据提取特征
转换:缩放,转换,或者修改特征
选择:从一个大的特征集合里面选择一个子集
局部敏感哈希(LSH):这类算法能将特征变换与其他算法相结合
目录特征提取TF-IDF
Word2Vec
CountVectorizer
特征转换标记生成器(Tokenizer)
停用词移除器(StopWordsRemover)
n-gram
二值化
PCA
多项式展开(PolynomialExpansion)
离散余弦变换(Discrete Cosine Transform DCT)
StringIndexer
IndexToString
OneHotEncoder
VectorIndexer
Interaction
Normalizer
StandardScaler
MinMaxScaler
MaxAbsScaler
Bucketizer
ElementwiseProduct
SQLTransformer
VectorAssembler
QuantileDiscretizer
Imputer
特征选择VectorSlicer
RFormula
ChiSqSelector
局部敏感哈希欧几里德距离的随机投影
Jaccard距离最小hash特征转换
近似相似性join
近似最近邻搜索LSH操作
LSH算法
特征提取
TF-IDF
TF-IDF是在文本挖掘中广泛使用的特征向量化方法,以反映语料库中文档的词语的重要性。用t表示一个词,d表示一篇文档,D表示文档集, 词频TF(t, d)表示表示文档d中词t的个数,文档频率DF(t,D)表示在文档集D中词t出现的个数。如果我们仅仅用词频衡量重要性,非常容易出现那些 频频繁出现的词如the,of但表示出很少和文档有关的信息。如果一个词语在语料库中经常出现,这意味着它不携带关于特定文档的特殊信息。逆文档频率IDF是一个词语能提供多少信息的数值化表示。IDF(t,D)=log((|D|+1)/(DF(t, D) + 1))
在这里,|D|是语料的总文档数,由于使用对数,如果一个词出现在所有文档中,则IDF值 为0,应用平滑项以避免分母为0。TF-IDF是度量TF和IDF的产物:TF-IDF(t,d,D)=TF(t,d)*IDF(t,D)
词频和文档频率有很多定义的方法。在MLlib,我们分离TF和IDF,使其灵活。
TF:HashingTF和CountVectorizer都可以用来生成词频向量。
HashingTF是一个转换器,它接受词集合输入,并将这些集合转换为固定长度的特征向量。
在文本处理中,一个词语集合也许是一个词袋。HashingTF利用哈希技巧。原始特征被映射到索引通过使用Hash函数。Hash函数使用MurmurHash 3,然后根据映射的索引计算词频。这个方法避免了在大语料上成本昂贵的全局词索引map的计算方式,但是会存在潜在的hash冲突,也就是不同的词特征在hash后被映射成相同的词。为了减少冲突的机会,我们可以增加目标特征维度,即散列表的桶数。由于使用简单的模数将散列函数转换为列索引,建议使用两个幂作为特征维,否则不会将特征均匀地映射到列。默认的特征维度为2^18=262,144.可选的二进制切换参数控制词频计数。当设置为true时,所有非零频率计数设置为1.对于模拟二进制而不是整数计数的离散概率模型特别有用。
CountVectorizer 将一个文本文档转成词数向量,具体参考CountVectorizer
IDF:IDF是一个估计器,通过拟合数据集产生一个IDFModel。IDFModel输入特征向量(通过由HashingTF 或者 CountVectorizer创建)并且缩放每列。直观地说,它减少了在语料库中频繁出现的列。
注意:spark.ml 不提供文本分词,我们参照Stanford NLP Group和scalanlp/chalk.
示例
在下面的代码段中,我们从一组句子开始。我们用Tokenizer将每个句子分成单词。
对于每个句子(包的单词),我们使用HashingTF将该句子哈希成特征向量。我们使用IDF来重新缩放特征向量;这通常在使用文本作为功能时提高性能。然后,我们的特征向量可以被传递给学习算法。
参考HashingTF Scala docs和IDF Scala docs获得更详细的APIimport org.apache.spark.ml.feature.{HashingTF, IDF, Tokenizer}val sentenceData = spark.createDataFrame(Seq(
(0.0, "Hi I heard about Spark"),
(0.0, "I wish Java could use case classes"),
(1.0, "Logistic regression models are neat")
)).toDF("label", "sentence")val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words")val wordsData = tokenizer.transform(sentenceData)val hashingTF = new HashingTF()
.setInputCol("words").setOutputCol("rawFeatures").setNumFeatures(20)val featurizedData = hashingTF.transform(wordsData)// alternatively, CountVectorizer can also be used to get term frequency vectorsval idf = new IDF().setInputCol("rawFeatures").setOutputCol("features")val idfModel = idf.fit(featurizedData)val rescaledData = idfModel.transform(featurizedData)
rescaledData.select("label", "features").show()
完整示例请参考spark仓库examples/src/main/scala/org/apache/spark/examples/ml/TfIdfExample.scala
作者:xcrossed
链接:https://www.jianshu.com/p/91a3920932c0