1) 语义相似、但字面不相似
2) 字面相似、但是语义不相似
1) 语义相似:依靠用户行为,最基本的方法:(1)基于共点击的行为(协同过滤),(2)借助回归算法
2) 字面相似:(1) LCS最大公共子序列 (2) 利用中文分词
|A| = sqrt(1*1+2*2+3*3) = 3.74
|B| = sqrt(2*2+3*3+4*4) = 5.38
分母:|A|*|B| = 20.12
1) TF:词频
关键词:在当前文章出现较多,但在其他文章中出现较少
2) IDF:反文档频率
score = TF * IDF
1) 确定关键词集合(两种方法(a)top-10 (b)阈值截断 > 0.8 )
2)哪些句子包含关键词,把这些句子取出来
3) 对关键词排序,对句子做等级划分
4)把等级高的句子取出来,就是摘要
1.idf实践:
一共508篇文章
(1)数据预处理:把所有文章的内容,全部收集到一个文件中
]# python convert.py input_tfidf_dir/ > idf_input.data
(2)计算IDF:通过mr批量计算IDF
计算方法:文档总数/包含该词的文档数
代码:
convert.py:
import os
import sys
file_path_dir = sys.argv[1]
def read_file_handler(f):
fd = open(f, 'r')
return fd
file_name = 0
for fd in os.listdir(file_path_dir):
file_path = file_path_dir + '/' + fd
content_list = []
file_fd = read_file_handler(file_path)
for line in file_fd:
content_list.append(line.strip())
print '\t'.join([str(file_name), ' '.join(content_list)])
file_name += 1
map.py:
import sys
for line in sys.stdin:
ss = line.strip().split('\t')
if len(ss) != 2:
continue
file_name, file_content = ss
word_list = file_content.strip().split(' ')
word_set = set(word_list)
for word in word_set:
print '\t'.join([word, '1'])
red.py:
import sys
import math
current_word = None
sum = 0
docs_cnt = 508
for line in sys.stdin:
ss = line.strip().split('\t')
if len(ss) != 2:
continue
word, val = ss
if current_word == None:
current_word = word
if current_word != word:
idf = math.log(float(docs_cnt) / (float(sum) + 1.0))
print '\t'.join([current_word, str(idf)])
current_word = word
sum = 0
sum += int(val)
idf = math.log(float(docs_cnt) / (float(sum) + 1.0))
print '\t'.join([current_word, str(idf)])
编写run.sh脚本运行MapReduce:
7.LCS(最长公共子序列)解决方案:
动态规划解决:
LCSpython实践:
1.数据:
2.python代码:
map.py:
# -*- coding: utf-8 -*-
#!/usr/bin/python
import sys
def cal_lcs_sim(first_str, second_str):
len_vv = [[0] * 50] * 50
first_str = unicode(first_str, "utf-8", errors='ignore')
second_str = unicode(second_str, "utf-8", errors='ignore')
len_1 = len(first_str.strip())
len_2 = len(second_str.strip())
for i in range(1, len_1 + 1):
for j in range(1, len_2 + 1):
if first_str[i - 1] == second_str[j - 1]:
len_vv[i][j] = 1 + len_vv[i - 1][j - 1]
else:
len_vv[i][j] = max(len_vv[i - 1][j], len_vv[i][j - 1])
return float(float(len_vv[len_1][len_2] * 2) / float(len_1 + len_2))
for line in sys.stdin:
ss = line.strip().split('\t')
if len(ss) != 2:
continue
first_str = ss[0].strip()
second_str = ss[1].strip()
sim_score = cal_lcs_sim(first_str, second_str)
print '\t'.join([first_str, second_str, str(sim_score)])
执行脚本run.sh
执行:
结果:
shell终端做快速计算:
]# echo $[60000*2/16]
]# echo $((60000*2/16))