当前位置:   article > 正文

spark之特征提取

spark之特征提取

1、特征处理分类

特征抽取:从原始数据中抽取特征
特征转换:特征的维度、特征的转化、特征的修改
特征选取:从大规模特征集中选取一个子集

2、特征提取

2.1、TF-IDF 

词频-逆向文件频率;词频TF(t,d)是词语t在文档d中出现的次数。文件频率DF(t,D)是包含词语的文档的个数。

tf=|t|/|d|

tf-idf=tf*idf

公式中使用log函数,当词出现在所有文档中时,它的IDF值变为0。加1是为了避免分母为0的情况。

Spark.mllib 中实现词频率统计使用特征hash的方式,原始特征通过hash函数,映射到一个索引值。后面只需要统计这些索引值的频率,就可以知道对应词的频率。这种方式避免设计一个全局1对1的词到索引的映射,这个映射在映射大量语料库时需要花费更长的时间。但需要注意,通过hash的方式可能会映射到同一个值的情况,即不同的原始特征通过Hash映射后是同一个值。为了降低这种情况出现的概率,我们只能对特征向量升维。i.e., 提高hash表的桶数,默认特征维度是 2^20 = 1,048,576.

  1. #tf-idf特征生成
  2. from pyspark.ml.feature import HashingTF,IDF,Tokenizer
  3. sentenceData = spark.createDataFrame([(0, "the spark quick"),(0, "the hadoop test"),(1, "the saprk diff")]).toDF("label", "sentence")
  4. tokenizer = Tokenizer(inputCol="sentence", outputCol="words")
  5. wordsData = tokenizer.transform(sentenceData)
  6. #将词hash成特征向量
  7. hashTF = HashingTF(inputCol="words", outputCol="rawFeatures", numFeatures=6)
  8. featurizedData = hashTF.transform(wordsData)
  9. featurizedData.show()
  10. #最后,使用IDF来对单纯的词频特征向量进行修正,使其更能体现不同词汇对文本的区别能力,IDF是一个Estimator,调用fit()方法并将词频向量传入,即产生一个IDFModel。
  11. idf = IDF(inputCol="rawFeatures", outputCol="features")
  12. idfModel = idf.fit(featurizedData)
  13. rescaledData = idfModel.transform(featurizedData)
  14. rescaledData.show()
  15. rescaledData.select("label", "features").show()

结果:

 

2.2、Word2Vec

Word2Vec 是一种著名的 词嵌入(Word Embedding) 方法,它可以计算每个单词在其给定语料库环境下的 分布式词向量(Distributed Representation,亦直接被称为词向量)。词向量表示可以在一定程度上刻画每个单词的语义。

​ Word2vec是一个Estimator,它采用一系列代表文档的词语来训练word2vecmodel。该模型将每个词语映射到一个固定大小的向量。word2vecmodel使用文档中每个词语的平均数来将文档转换为向量,然后这个向量可以作为预测的特征,来计算文档相似度计算等等。

在ml库中,使用的是skip-gram方式,优化的目标函数如下:

softmax直接计算:

skip-gram采取了层次softmax来进行计算,计算复杂度从O(V)降到了O(log(V))

  1. from pyspark.ml.feature import Word2Vec
  2. documentDF = spark.createDataFrame([
  3. ("Hi I heard about Spark".split(" "), ),
  4. ("I wish Java could use case classes".split(" "), ),
  5. ("Logistic regression models are neat".split(" "), )
  6. ], ["text"])
  7. word2Vec = Word2Vec(vectorSize=3, minCount=0, inputCol="text", outputCol="result")
  8. model = word2Vec.fit(documentDF)
  9. result = model.transform(documentDF)
  10. for row in result.collect():
  11. print(row)
  12. text, vector = row
  13. print("Text: [%s] => \nVector: %s\n" % (", ".join(text), str(vector)))
  14. #寻找heard的同义词
  15. model.findSynonyms("heard", 2).show()
  16. #显示词向量
  17. model.getVectors().show()
  18. #句向量
  19. df_vec=model.transform(documentDF)
  20. df_vec.show()

heard相似词查询结果:

句向量结果:

2.3、CountVectorizer

CountVectorizer旨在通过计数来将一个文档转换为向量。当不存在先验字典时,Countvectorizer作为Estimator提取词汇进行训练,并生成一个CountVectorizerModel用于存储相应的词汇向量空间。该模型产生文档关于词语的稀疏表示,其表示可以传递给其他算法,例如LDA。

  1. from pyspark.ml.feature import CountVectorizer
  2. df = spark.createDataFrame([
  3. (0, "a b c".split(" ")),
  4. (1, "a b b c a".split(" "))
  5. ], ["id", "words"])
  6. # fit a CountVectorizerModel from the corpus.
  7. cv = CountVectorizer(inputCol="words", outputCol="features", vocabSize=3, minDF=2.0)
  8. model = cv.fit(df)
  9. result = model.transform(df)
  10. result.show()

结果 :

3、特征变换

Spark ML包中提供了几个相关的转换器,StringIndexer、IndexToString、OneHotEncoder、VectorIndexer

3.1、StringIndexer

StringIndexer转换器可以把一列类别型的特征(或标签)进行编码,使其数值化,索引的范围从0开始,该过程可以使得相应的特征索引化。索引构建的顺序为标签的频率,优先编码频率较大的标签,所以出现频率最高的标签为0号。
 

3.2、IndexToString

与StringIndexer相对应,IndexToString的作用是把标签索引的一列重新映射回原有的字符型标签。

其主要使用场景一般都是和StringIndexer配合,先用StringIndexer将标签转化成标签索引,进行模型训练,然后在预测标签的时候再把标签索引转化成原有的字符标签。当然,你也可以另外定义其他的标签。

3.3、OneHotEncoder

​独热编码(One-Hot Encoding) 是指把一列类别性特征(或称名词性特征,nominal/categorical features)映射成一系列的二元连续特征的过程,原有的类别性特征有几种可能取值,这一特征就会被映射成几个二元连续特征,每一个特征代表一种取值,若该样本表现出该特征,则取1,否则取0。

3.4、VectorIndexer

之前介绍的StringIndexer是针对单个类别型特征进行转换,倘若所有特征都已经被组织在一个向量中,又想对其中某些单个分量进行处理时,Spark ML提供了VectorIndexer类来解决向量数据集中的类别性特征转换。

3.5、实例

  1. #特征变换
  2. #StringIndexer:把一列类别型的特征转化为数字编码
  3. from pyspark.ml.feature import StringIndexer
  4. df = spark.createDataFrame(
  5. [(0, "a"), (1, "b"), (2, "c"), (3, "a"), (4, "a"), (5, "c")],
  6. ["id", "category"])
  7. indexer = StringIndexer(inputCol="category", outputCol="categoryIndex")
  8. model = indexer.fit(df)
  9. indexed = model.transform(df)
  10. indexed.show()
  11. #IndexToString还原标签索引为字符型标签
  12. from pyspark.ml.feature import IndexToString
  13. converter = IndexToString(inputCol="categoryIndex", outputCol="originalCategory")
  14. converted = converter.transform(indexed)
  15. converted.show()
  16. #OneHotEncoder:指把一列类别性特征(或称名词性特征,nominal/categorical features)映射成一系列的二元连续特征
  17. from pyspark.ml.feature import OneHotEncoder, StringIndexer
  18. #独热编码;setDropLast(False);不设置这个出现频率最低的将不会占用1位2进制位
  19. encoder = OneHotEncoder(inputCol="categoryIndex", outputCol="categoryVec").setDropLast(False)
  20. encoded = encoder.transform(indexed)
  21. encoded.show()
  22. #之前介绍的StringIndexer是针对单个类别型特征进行转换,倘若所有特征都已经被组织在一个向量中,又想对其中某些单个分量进行处理时,Spark ML提供了VectorIndexer类来解决向量数据集中的类别性特征转换。
  23. from pyspark.ml.feature import VectorIndexer
  24. from pyspark.ml.linalg import Vectors
  25. df = spark.createDataFrame([(Vectors.dense([-1.0, 0.0]),),
  26. (Vectors.dense([0.0, 1.0]),), (Vectors.dense([0.0, 2.0]),), (Vectors.dense([1.0, 2.0]),)], ["a"])
  27. vectorIndexer = VectorIndexer(maxCategories=2, inputCol="a", outputCol="indexed")
  28. model = vectorIndexer.fit(df)
  29. vectorIndexed=model.transform(df)
  30. print(model.categoryMaps)
  31. vectorIndexed.show()

4、特征选取

特征选择(Feature Selection)指的是在特征向量中选择出那些“优秀”的特征,组成新的、更“精简”的特征向量的过程。它在高维数据分析中十分常用,可以剔除掉“冗余”和“无关”的特征,提升学习器的性能。

特征选择方法和分类方法一样,也主要分为有监督(Supervised)和无监督(Unsupervised)两种,卡方选择则是统计学上常用的一种有监督特征选择方法,它通过对特征和真实标签之间进行卡方检验,来判断该特征和真实标签的关联程度,进而确定是否对其进行选择。

卡方选择:

https://blog.csdn.net/shuzfan/article/details/52993427

https://www.cnblogs.com/massquantity/p/10486904.html

卡方选择则是统计学上常用的一种有监督特征选择方法,它通过对特征和真实标签之间进行卡方检验,来判断该特征和真实标签的关联程度,进而确定是否对其进行选择。

  1. from pyspark.ml.feature import ChiSqSelector
  2. from pyspark.ml.linalg import Vectors
  3. df = spark.createDataFrame([
  4. (7, Vectors.dense([0.0, 0.0, 18.0, 1.0]), 1.0,),
  5. (8, Vectors.dense([0.0, 1.0, 12.0, 0.0]), 0.0,),
  6. (9, Vectors.dense([1.0, 0.0, 15.0, 0.1]), 0.0,)], ["id", "features", "clicked"])
  7. selector = ChiSqSelector(numTopFeatures=1, featuresCol="features",
  8. outputCol="selectedFeatures", labelCol="clicked")
  9. result = selector.fit(df).transform(df)
  10. result.show()

结果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/885157
推荐阅读
相关标签
  

闽ICP备14008679号