PySpark计算TF-IDF

目录

      • 1. TF
      • 2. IDF
      • 3. TF-IDF
      • 4. 代码实现计算IDF
      • 5. 计算TF

tf-idf是一种用于信息检索与文本挖掘的常用加权技术。tf-idf是一种统计方法,用以评估一字词对于一个文档集或一个语料库中的其中一份文档的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。

1. TF

在一份给定的文档 d d d里,词频(term frequency,tf)指的是某一个给定的词语在该文档中出现的频率。这个数字是对词数(term count)的归一化,以防止它偏向长的文档。(同一个词语在长文档里可能会比短文档有更高的词数,而不管该词语重要与否。)对于在某一特定文档里的词语 w i {\displaystyle w_i} wi来说,它的重要性可表示为:
T F w i , d = c o u n t 词 w i 在 文 档 d 中 出 现 的 次 数 c o u n t 文 档 d 的 总 词 数 TF_{{w_i},d} = \frac{count_{词w_{i}在文档d中出现的次数}}{count_{文档 d 的总词数}} TFwi,d=countdcountwid

2. IDF

逆向文档频率(inverse document frequency,idf)是一个词语普遍重要性的度量。某一特定词语的idf,可以由总文档数目除以包含该词语之文档的数目,再将得到的商取以10为底的对数得到:
I D F w i = l o g c o u n t 所 有 文 档 总 数 1 + c o u n t 包 含 词 w i 文 档 总 数 IDF_{w_i} = log \frac{count_{所有文档总数}}{1+count_{包含词w_{i}文档总数}} IDFwi=log1+countwicount
如果一个词越常见,那么分母就越大,逆文档频率(IDF)就越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词),log表示对得到的值取对数。

3. TF-IDF

某一特定文档内的高词语频率,以及该词语在整个文档集合中的低文档频率,可以产生出高权重的tf-idf。因此,tf-idf倾向于过滤掉常见的词语,保留重要的词语。
T F − I D F = T F ∗ I D F TF-IDF = TF * IDF TFIDF=TFIDF

4. 代码实现计算IDF

from pyspark import SparkConf
from pyspark.sql import SparkSession
from pyspark.sql import HiveContext
import re
import math

sc = SparkContext()
sqlContext = HiveContext(sc)

#表结构样例
#############################
# query        | tokens
# 南京市长江大桥 | 南京市,长江大桥
#############################

token_data = sqlContext.sql("select query,tokens from db.table")
counts_all = token_data.count()  #文档总数
tokens = token_data.rdd.map(lambda x: x.__getitem__("tokens"))

# 正则,去掉一些无效字符
pattern = re.compile(r'[\s+\\r\\u3000\\u3000\.\!\/_,;’:‘“”$%^*(+\"\']+|[+——!】,【。?、~@#¥%……&*():]+\'')
data_re = tokens.map(lambda x: re.sub(pattern, '##', x)).map(lambda x: list(set(x.split("##"))))

# 单篇文档,每个词的词频都是1
data_reshape = data_re.flatMap(lambda x: x).map(lambda x: (x, 1))

# reduceByKey函数,将不同文档相同分词结果按y累加,得到该词在所有文档中出现的总次数
data_reduceBykey = data_reshape.reduceByKey(lambda x, y: x+y)

# 计算公式
def get_idf(x):
    return round(math.log(counts_all/(x+1)), 2) #idf值保留2位有效数字
    
# IDF计算
data_idf = data_reduceBykey.map(lambda x:(x[0],get_idf(x[1]))).filter(lambda x:x[0] != '')
# 结果存储到HDFS上
data_idf.saveAsTextFile("hdfs://.../path")

5. 计算TF

tf计算很简单,就偷一下懒不写了

参考1
参考2
参考3

你可能感兴趣的:(pyspark,NLP)