Nov 12, 2018
search engine
搜索引擎
将服务器存储内容与用户检索内容匹配,并相应匹配结果
爬虫
将网页爬取到本地服务器。
- 获取原始文档:Nutch,jsoup,heritrix
- 创建文档对象 数据结构: Document{DocId, Field{fileName:fileName}, Filed{fileContent:fileContent}, Filed{fileTitle:fileTitle}}
- 分析文档 提取单词、将字母转为小写、去除标点符号、去除停用词 每个单词为一个Term:Term{Field, word},注意:不同的field的相同单词属于不同term
索引 – 反转列表(inverted list)
进行快速查找,目的高效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
wordId --- word --- file frequency --- inverted list(DocId ,frequercy, pos)
每个单词对应一个反转列表:在多少文档(url 文件名 引用)出现,是什么文档,出现次数,位置信息。
存储结构:hash存储,B+树存储
数据结构:文档ID到实际文档(Document Mananger), 每个单词属性(Term Dictionary), 存储文档属性
Term Dictionary:索引中单词与文档都为整形ID而不是字符串,ID与字符串映射由Term Dictionary维护;多少文档出现document frequency;文档中出现概率 = 文档总数/多少文档出现,为排序提供依据
创建索引:首先进行文档解析,不同文档对应不同解析器。
自然语言处理算法(分词(tokenzation), 词干提取(stemming),识别词性(part-of-speech tagging), n-gram模型创建,识别文档中命名体)
索引生成程序:
IndexFile* indexGenerator() {
while((file = filesStore->next()) != NULL){
filesScaner->scanToIndexMemory(file)
if (filesScaner->indexMemorySize() >= MAX_INDEX_MEMORY)
filesScaner->syncToInvertedBlock()
}
return filesScaner->mergeAllBlocks()
}
更新:
IndexFile* staticIndex = indexGenerator();
IndexFile* dynamicIndex;
while(true) {
if (filesStore->count() > MAX_FILES_NUM) {
dynamicIndex = indexGenerator()
}
sleep(24 * 60 * 60)
if (dynamicIndex->size() > MAX_DYNAMIC_SIZE)
update(staticIndex, dynamicIndex)
}
删除:
deleteSrcFile(fileName){
g_deleteList->add(fileName)
if (deleteList->count() > MAX_DELETE_LIST)
g_indexFile = regenerateIndex()
}
搜索:
search() {
result_list = m_indexFile->find(keyWord)
return sort(result_list - g_deleteList)
}
由此,GOOGLE推出了分布式计算框架MapReduce:将一个大任务分割多个小任务,下发给mapper计算中间结果,中间结果反馈给reducer程序继续处理,得到最终结果。
搜索
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
解析为树形结构:AND(TERM(word1), TERM(word2))
TERM将词组转为对应的反转列表
AND将反转列表转为分数列表,并对分数列表中文档id集合求交集,生成新的分数列表。每个文档分数 = 各个输入的分数列表乘积
OR文档集合做并集
NEAR(term1, term2),term1与term2相邻的文档
WINDOW(4,term1,term2),term1与term2相邻不超过4个的单词
WEIGHTED_SUM对分数加权和操作
multiple representation model:分别处理title,url,body
WEIGHTED_SUM(0.1, AND(url(iphone6), url(售价)),
0.2, AND(title(iphone6),url(售价)),
0.7, AND(body(iphone6), url(售价)))
Sequential Dependency Model:将不同方法生成解析树,最后加权求和
bag of words 匹配,即 AND(“iphone 6”, 售价);
N-gram 匹配,即 NEAR(“Iphone 6”, 售价)
短窗口匹配,即 WINDOW(8, “iphone 6”, 售价)
WEIGHTED_SUM(0.7, AND(“iphone 6”, 售价), 0.2, NEAR("Iphone 6”, 售价), 0.1 WINDOW(8, “iphone 6”, 售价) )
排序
1
2
3
4
5
6
7
score(doc, query)=f(IRscore(doc,query),PageRank(doc))
IRscore在文档中query在doc中的检索得分
tf-idf(term frequency–inverse document frequency)
单词-文档组合都对应一个tf-idf:tf:该文档中该单词出现数量,df:含有该单词的文档数量,idf:一个文档含有该单词概率倒数,消除常用词干扰
tf-idf=tf*totalDocCount/df,为避免文档中刻意罗列关键词,还需引入PageRank
PageRank文档级别得分:对网页重要程度进行打分,A链接指向B,A链接重要,B链接的重要程度也会增加.