赞
踩
1、特征处理分类
特征抽取:从原始数据中抽取特征
特征转换:特征的维度、特征的转化、特征的修改
特征选取:从大规模特征集中选取一个子集
2、特征提取
词频-逆向文件频率;词频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.
- #tf-idf特征生成
- from pyspark.ml.feature import HashingTF,IDF,Tokenizer
- sentenceData = spark.createDataFrame([(0, "the spark quick"),(0, "the hadoop test"),(1, "the saprk diff")]).toDF("label", "sentence")
- tokenizer = Tokenizer(inputCol="sentence", outputCol="words")
- wordsData = tokenizer.transform(sentenceData)
- #将词hash成特征向量
- hashTF = HashingTF(inputCol="words", outputCol="rawFeatures", numFeatures=6)
- featurizedData = hashTF.transform(wordsData)
- featurizedData.show()
- #最后,使用IDF来对单纯的词频特征向量进行修正,使其更能体现不同词汇对文本的区别能力,IDF是一个Estimator,调用fit()方法并将词频向量传入,即产生一个IDFModel。
-
-
- idf = IDF(inputCol="rawFeatures", outputCol="features")
- idfModel = idf.fit(featurizedData)
- rescaledData = idfModel.transform(featurizedData)
- rescaledData.show()
- 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))
- from pyspark.ml.feature import Word2Vec
- documentDF = spark.createDataFrame([
- ("Hi I heard about Spark".split(" "), ),
- ("I wish Java could use case classes".split(" "), ),
- ("Logistic regression models are neat".split(" "), )
- ], ["text"])
- word2Vec = Word2Vec(vectorSize=3, minCount=0, inputCol="text", outputCol="result")
- model = word2Vec.fit(documentDF)
-
- result = model.transform(documentDF)
- for row in result.collect():
- print(row)
- text, vector = row
- print("Text: [%s] => \nVector: %s\n" % (", ".join(text), str(vector)))
-
- #寻找heard的同义词
- model.findSynonyms("heard", 2).show()
- #显示词向量
- model.getVectors().show()
- #句向量
- df_vec=model.transform(documentDF)
- df_vec.show()
heard相似词查询结果:
句向量结果:
2.3、CountVectorizer
CountVectorizer旨在通过计数来将一个文档转换为向量。当不存在先验字典时,Countvectorizer作为Estimator提取词汇进行训练,并生成一个CountVectorizerModel用于存储相应的词汇向量空间。该模型产生文档关于词语的稀疏表示,其表示可以传递给其他算法,例如LDA。
- from pyspark.ml.feature import CountVectorizer
- df = spark.createDataFrame([
- (0, "a b c".split(" ")),
- (1, "a b b c a".split(" "))
- ], ["id", "words"])
- # fit a CountVectorizerModel from the corpus.
- cv = CountVectorizer(inputCol="words", outputCol="features", vocabSize=3, minDF=2.0)
- model = cv.fit(df)
- result = model.transform(df)
- 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、实例
- #特征变换
- #StringIndexer:把一列类别型的特征转化为数字编码
- from pyspark.ml.feature import StringIndexer
-
- df = spark.createDataFrame(
- [(0, "a"), (1, "b"), (2, "c"), (3, "a"), (4, "a"), (5, "c")],
- ["id", "category"])
- indexer = StringIndexer(inputCol="category", outputCol="categoryIndex")
- model = indexer.fit(df)
- indexed = model.transform(df)
- indexed.show()
-
- #IndexToString还原标签索引为字符型标签
- from pyspark.ml.feature import IndexToString
- converter = IndexToString(inputCol="categoryIndex", outputCol="originalCategory")
- converted = converter.transform(indexed)
- converted.show()
-
-
- #OneHotEncoder:指把一列类别性特征(或称名词性特征,nominal/categorical features)映射成一系列的二元连续特征
- from pyspark.ml.feature import OneHotEncoder, StringIndexer
- #独热编码;setDropLast(False);不设置这个出现频率最低的将不会占用1位2进制位
- encoder = OneHotEncoder(inputCol="categoryIndex", outputCol="categoryVec").setDropLast(False)
-
- encoded = encoder.transform(indexed)
- encoded.show()
-
- #之前介绍的StringIndexer是针对单个类别型特征进行转换,倘若所有特征都已经被组织在一个向量中,又想对其中某些单个分量进行处理时,Spark ML提供了VectorIndexer类来解决向量数据集中的类别性特征转换。
- from pyspark.ml.feature import VectorIndexer
- from pyspark.ml.linalg import Vectors
- df = spark.createDataFrame([(Vectors.dense([-1.0, 0.0]),),
- (Vectors.dense([0.0, 1.0]),), (Vectors.dense([0.0, 2.0]),), (Vectors.dense([1.0, 2.0]),)], ["a"])
- vectorIndexer = VectorIndexer(maxCategories=2, inputCol="a", outputCol="indexed")
- model = vectorIndexer.fit(df)
- vectorIndexed=model.transform(df)
- print(model.categoryMaps)
-
- vectorIndexed.show()
4、特征选取
特征选择(Feature Selection)指的是在特征向量中选择出那些“优秀”的特征,组成新的、更“精简”的特征向量的过程。它在高维数据分析中十分常用,可以剔除掉“冗余”和“无关”的特征,提升学习器的性能。
特征选择方法和分类方法一样,也主要分为有监督(Supervised)和无监督(Unsupervised)两种,卡方选择则是统计学上常用的一种有监督特征选择方法,它通过对特征和真实标签之间进行卡方检验,来判断该特征和真实标签的关联程度,进而确定是否对其进行选择。
卡方选择:
https://blog.csdn.net/shuzfan/article/details/52993427
https://www.cnblogs.com/massquantity/p/10486904.html
卡方选择则是统计学上常用的一种有监督特征选择方法,它通过对特征和真实标签之间进行卡方检验,来判断该特征和真实标签的关联程度,进而确定是否对其进行选择。
- from pyspark.ml.feature import ChiSqSelector
- from pyspark.ml.linalg import Vectors
- df = spark.createDataFrame([
- (7, Vectors.dense([0.0, 0.0, 18.0, 1.0]), 1.0,),
- (8, Vectors.dense([0.0, 1.0, 12.0, 0.0]), 0.0,),
- (9, Vectors.dense([1.0, 0.0, 15.0, 0.1]), 0.0,)], ["id", "features", "clicked"])
- selector = ChiSqSelector(numTopFeatures=1, featuresCol="features",
- outputCol="selectedFeatures", labelCol="clicked")
- result = selector.fit(df).transform(df)
- result.show()
结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。