python开发TFIDF值

        数据处理过程中很多情况需要对某个信息进行打分,判断这个信息字段的重要行,这里拿文章的单词进行距离,获取TFIDF值。

TFIDF打分:某个词对文章重要性
1、TF:一个词在文章中出现的次数
2、IDF:反文档频率
词频(TF ):某个词在文章中出现的次数:
    词频(TF )=某个词在文章中出现的次数/文章的总词数
    词频(TF )=某个词在文章中出现的次数/该文出现次数最多的词的出现次数
反文档频率(IDF )= log ( 语料库的文档总数/包含该词的文档数+1)
TF-IDF =  词频(TF )* 反文档频率(IDF)
TF-IDF与一个词在文档中的出现次数成正比,与包含该词的文档数成反比。

IDF值的计算:

run.sh

  1 
  2 INPUT_FILE_PATH="/test/work02/idf_input.data"
  3 OUTPUT_PATH="/test/work02/tfidf_output"
  4 
  5 hadoop fs -rmr $OUTPUT_PATH
  6 
  7 hadoop jar /usr/local/src/hadoop-2.6.0/share/hadoop/tools/lib/hadoop-streaming-2.6.0.jar \
  8         -input $INPUT_FILE_PATH \
  9     -output $OUTPUT_PATH \
 10     -mapper "python map.py" \
 11     -reducer "python red.py" \
 12     -file ./map.py \
 13     -file ./red.py 

map.py

  1 import sys
  2 
  3 for line in sys.stdin:
  4         ss = line.strip().split('\t')
  5         if len(ss) != 2:
  6                 continue
  7         file_name, file_content = ss
  8         word_list = file_content.strip().split(' ')
  9         word_set = set(word_list)
 10         for word in word_set:
 11                 print '\t'.join([word,'1'])

这个map的作用就是读取文件内容,过滤脏数据,将文章内容存放到set集合中,并对文章中的单词进行计数。

注意:

    1、我的数据源是将多篇文件提前进行了中文分词分割,然后将多个文章文件进行合并,合并后每行使用数字标识,‘\t’进行分割,每一行对应一篇文档;

    2、第5是对脏数据进行过滤;

    8、我的文章分词是使用的空格,这里是将文件拆分成单个的单词存放列表中

    9、将列表转换成set集合,这个转换是为了去重,因为一篇文章中某个单词可能包含多个,但是我只需要记一次,所以需要去重。

red.py

  1 import sys
  2 import math
  3 
  4 current_word = None
  5 sum = 0
  6 docs_cnt = 508
  7 for line in sys.stdin:
  8         ss = line.strip().split('\t')
  9         if len(ss) !=2:
 10                 continue
 11         word, val = ss
 12         if current_word == None:
 13                 current_word = word
 14         if current_word != word:
 15                 idf = math.log(float(docs_cnt) / (float(sum) + 1.0))
 16                 print '\t'.join([current_word, str(idf)])
 17                 current_word = word
 18                 sum = 0
 19 
 20         sum += int(val)
 21 idf = math.log(float(docs_cnt) / (float(sum) + 1.0))
 22 print '\t'.join([current_word, str(idf)])

计算TFIDF值

  1 import sys
  2 
  3 input_file_article = sys.argv[1]
  4 input_idf = sys.argv[2]
  5 input_con = sys.argv[3]
  6 input_work = sys.argv[4]
  7 def read():
  8         file_work = {}
  9         idf = {}
 10         sum = 0
 11         idf_work = open(input_idf, 'r')
 12         for line in idf_work:
 13                 ss = line.strip().split('\t')
 14                 if len(ss) != 2:
 15                         continue
 16                 word, con = ss
 17                 idf[word] = float(con)
 18         file_article = open(input_file_article, 'r')
 19         for line in file_article:
 20                 ss = line.strip().split('\t')
 21                 if len(ss) != 2:
 22                         continue
 23                 con, words = ss
 24                 if input_con != con:
 25                         continue
 26                 for word in words.strip().split(' '):
 27                         if word not in file_work:
 28                                 file_work[word] = 1
 29                         else:
 30                                 file_work[word] += 1
 31                         sum += 1
 32 
 33         if (input_work not in idf) or (input_work not in file_work):
 34                 print input_work
 35                 print 'not found work'
 36                 sys.exit(-1)
 37         tf = file_work[input_work]
 38         print tf
 39         print idf[input_work]
 40         tfidf = tf * idf[input_work]
 41         print '\t'.join([input_con, input_work, str(tfidf)])
 42         sys.exit(-1)
 43 
 44 
 45 if __name__ == "__main__":
 46         read() 

这里使用一个简单的py程序计算结果,需要注意的一下几个地方:

    1、我是将上面生成的idf值从hdfs上面拉到了本地

    2、直接套取前面写的公式。























你可能感兴趣的:(python开发MR)