您的当前位置:首页正文

15.Spark学习(Python版本):特征处理相关的算法(T

来源:华拓网
特征处理相关的算法,大体分为以下三类:

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

特征抽取–TF-IDF (HashingTF and IDF)

“词频-逆向文件频率”(TF-IDF)是一种在文本挖掘中广泛使用的特征向量化方法,它可以体现一个文档中词语在语料库中的重要程度。


​ 词语由t表示,文档由d表示,语料库由D表示。词频TF(t,d)是词语t在文档d中出现的次数。文件频率DF(t,D)是包含词语的文档的个数。


如果我们只使用词频来衡量重要性,很容易过度强调在文档中经常出现,却没有太多实际信息的词语,比如“a”,“the”以及“of”,意味着它并不能很好的对文档进行区分。想想如果一个词语的TF很高,但是IDF比较低,不就说明这个词语很能代表此文档吗?

在Spark ML库中,TF-IDF被分成两部分:TF (+hashing) 和 IDF。

TF: HashingTF 是一个Transformer,在文本处理中,接收词条的集合然后把这些集合转化成固定长度的特征向量。这个算法在哈希的同时会统计各个词条的词频。

IDF: IDF是一个Estimator,在一个数据集上应用它的fit()方法,产生一个IDFModel。 该IDFModel 接收特征向量(由HashingTF产生),然后计算每一个词在文档中出现的频次。IDF会减少那些在语料库中出现频率较高的词的权重。

我们尝试一下生成tfidf向量:
mashu@mashu-Inspiron-5458:/usr/local/spark/python_code/ML$ vim ml_tfidf.py

from pyspark.sql import SparkSession
from pyspark.ml.feature import HashingTF, IDF, Tokenizer

spark = SparkSession.builder.master("local").appName("Word Tfidf").getOrCreate()
sentenceData = spark.createDataFrame([(0,"I heard about Spark and I love Spark"), (0,"I wish Java could use case classes"), (1,"Logistic regression models are neat")]).toDF("label","sentence")

# Split words with tokenizer.transform()
tokenizer = Tokenizer(inputCol="sentence",outputCol="words")
wordsData = tokenizer.transform(sentenceData)

# Hash sentence word to TF feature vec by hashingTF.transform() 
hashingTF = HashingTF(inputCol="words",outputCol="rawFeatures",numFeatures=20)
featurizedData = hashingTF.transform(wordsData)

# Add IDF to modify TF vec to create tfidf feature vec
idf = IDF(inputCol="rawFeatures",outputCol="features")
idfModel = idf.fit(featurizedData)
rescaledData = idfModel.transform(featurizedData)

rescaledData.select("label","features").show(truncate=False) #不删减内容显示

输出结果如下:


特征抽取–Word2Vec

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

Word2Vec具有两种模型,其一是 CBOW ,其思想是通过每个词的上下文窗口词词向量来预测中心词的词向量。其二是 Skip-gram,其思想是通过每个中心词来预测其上下文窗口词,并根据预测结果来修正中心词的词向量。两种方法示意图如下图所示:




在ml库中,Word2vec 的实现使用的是skip-gram模型。Skip-gram的训练目标是学习词表征向量分布,其优化目标是在给定中心词的词向量的情况下,最大化以下似然函数:


下面介绍ML库中Word2Vec类的使用。
我们首先用一组文档,其中一个词语序列代表一个文档。对于每一个文档,我们将其转换为一个特征向量。此特征向量可以被传递到一个学习算法。

​首先,导入Word2Vec所需要的包,并创建三个词语序列,每个代表一个文档:

from pyspark.sql import SparkSession
from pyspark.ml.feature import Word2Vec

spark = SparkSession.builder.master("local").appName("Word Tfidf").getOrCreate()
documentDF = spark.createDataFrame([
                ("Hi I heard about Spark".split(" "),),
                ("I wish Java could use case classes".split(" "),),
                ("Logistic regression models are neat".split(" "),)],
                ["text"])

# Create a word2vec model
word2vec = Word2Vec(vectorSize=3, minCount=0, inputCol="text", outputCol="result")
model = word2vec.fit(documentDF)

# Transform document to feature vector
result = model.transform(documentDF)
for row in result.collect():
        text,vector = row
        print("Text:[%s] => \nVector:%s\n" % (", ".join(text),str(vector)))

输出结果如下:



可以看到,文档被转变为了一个3维的特征向量,这些特征向量就可以被应用到相关的机器学习方法中。