一.信息檢索方式
(1)線性掃描
計(jì)算機(jī)對(duì)于文檔內(nèi)容檢索有多種可能的方式,如直接從頭遍歷至尾端,根據(jù)我們輸入的關(guān)鍵詞提取內(nèi)容。
這類檢索方式與我們?nèi)祟愰喿x的習(xí)慣相同,因此實(shí)現(xiàn)簡(jiǎn)單且很容易被接受。
若問你《三國演義》中是否存在’舌戰(zhàn)群儒’這一詞語,我們常常會(huì)選擇瀏覽全文從中找出匹配的詞語。
而從《三國演義》中提取出關(guān)鍵詞 , 通過現(xiàn)代計(jì)算機(jī)不會(huì)花費(fèi)太長時(shí)間;
但假如目標(biāo)是世界文學(xué)合集呢?企業(yè)一年的財(cái)務(wù)報(bào)告呢?又或者是現(xiàn)代信息世界產(chǎn)生的規(guī)模更大的文檔集。
盡管計(jì)算機(jī)算力強(qiáng)大,線性掃描的信息檢索方式也僅僅只能夠用于處理小文本。
(2)詞項(xiàng)—文檔關(guān)聯(lián)矩陣
于是產(chǎn)生了詞項(xiàng)—文檔關(guān)聯(lián)矩陣,我們利用空閑的算力,在計(jì)算機(jī)內(nèi)部提前構(gòu)建矩陣。
三國演義 | 紅樓夢(mèng) | 水滸傳 | 西游記 | 悟空傳 | |
---|---|---|---|---|---|
孫悟空 | 0 | 0 | 0 | 1 | 1 |
賈寶玉 | 0 | 1 | 0 | 0 | 0 |
當(dāng)我們輸入關(guān)鍵詞孫悟空時(shí),將《西游記》《悟空傳》兩個(gè)文檔作為結(jié)果返回。
這樣的方式大大提高了檢索速度
詞項(xiàng)是索引的單位 而文檔則是返回的結(jié)果。
從行來看,能夠得到對(duì)應(yīng)詞項(xiàng)的文檔向量;從列來看,則獲取文檔的詞項(xiàng)向量。
當(dāng)然這類方式也存在較大的不足 如上述我所舉例的表格 能夠看見矩陣中0值占比極高
在造成負(fù)擔(dān)的同時(shí) 也極大地減緩了檢索速度。
(3)倒排索引
對(duì)數(shù)據(jù)結(jié)構(gòu)有一定涉獵的同學(xué)應(yīng)該很快就能想到優(yōu)化方式——稀疏數(shù)組。
我們建立詞項(xiàng)詞典與倒排記錄表 從而完成對(duì)文檔的高效檢索。
詞項(xiàng)詞典 | 倒排記錄表 |
---|---|
孫悟空 | 4—>5 |
賈寶玉 | 2 |
倒排索引的兩個(gè)部分。詞典部分往往放在內(nèi)存中,而指針指向的每個(gè)倒排記錄表則往往存放在磁盤上。
二.倒排索引實(shí)現(xiàn)及常用語料處理方式
(1) 實(shí)現(xiàn)目標(biāo)
讀取文本文件 對(duì)不同的單行文檔 進(jìn)行詞條化及歸一化,
關(guān)注標(biāo)點(diǎn)符號(hào)的去重 停用詞的篩選以及大小寫的轉(zhuǎn)化。
建立倒排索引/詞項(xiàng)字典。
(2) 完整代碼
import re
import string
from stop_words import get_stop_words
from nltk.stem.porter import PorterStemmer
# 列表去重
def unique(word_list):
return list(dict.fromkeys(word_list))
# 移除停用詞
def stop_word(token):
en_stop = get_stop_words('en')
stopped_tokens = [i for i in token if i not in en_stop]
return stopped_tokens
# 詞干提取
def stem_extracting(stopped_tokens):
p_stemmer = PorterStemmer()
texts = [p_stemmer.stem(i) for i in stopped_tokens]
return texts
# Porter stemmer 并不是要把單詞變?yōu)橐?guī)范的那種原來的樣子,
# 它只是把很多基于這個(gè)單詞的變種變?yōu)槟骋环N形式!換句話說,
# 它不能保證還原到單詞的原本,也就是"created"不一定能還原到"create",
# 但卻可以使"create" 和 "created" ,都得到"creat" !
def incidence_matrix(text, docID):
# 目的:
# 傳入一段文本及其文檔號(hào)
# 獲取其詞項(xiàng)列表
# 1.清除英文標(biāo)點(diǎn)符號(hào)
punctuation_string = string.punctuation
lines = re.sub('[{}]'.format(punctuation_string), " ", text)
# 2.將英文文本內(nèi)容切片
lsplit = lines.split()
# 3.大小寫轉(zhuǎn)換
for num in range(len(lsplit)):
lsplit[num] = lsplit[num].lower()
# 4.移除停用詞 詞干提取
# lsplit = stem_extracting(stop_word(lsplit))
# 5.去重并轉(zhuǎn)字典
lsplit_dic = dict.fromkeys(lsplit)
# 6.記錄文檔號(hào)
for word in lsplit_dic.keys():
lsplit_dic[word] = [docID]
return lsplit_dic
def read_file(filename):
result = {}
count = 0
with open(filename, 'r') as file_to_read:
# 以只讀形式打開該文件
while True:
# 以行為單位進(jìn)行讀取
lines = file_to_read.readline()
# 當(dāng)某行內(nèi)容為空時(shí) 停止讀取
if len(lines) == 0:
break
count = count + 1
lsplot = incidence_matrix(lines, count)
result = dic_zip(result, lsplot)
# 關(guān)閉文件讀取
file_to_read.close()
return result
def dic_sort(a_dic):
b_dic = dict.fromkeys(sorted(a_dic))
for word in b_dic.keys():
b_dic[word] = a_dic[word]
return b_dic
# 不同文檔字典 同一詞項(xiàng)合并
def dic_zip(a_dic, b_dic):
# 將b_dic并入a_dic中
for word in b_dic.keys():
if a_dic.get(word, None):
a_dic[word].extend(b_dic[word])
else:
a_dic[word] = b_dic[word]
return a_dic
def show_dic(a_dic):
# 文檔頻率可用于做查詢優(yōu)化
tplt = "{0:^10}\t{1:{3}^10}\t{2:^40}"
print(tplt.format("詞項(xiàng)", "文檔頻率", "倒排記錄", chr(12288)))
for word in a_dic.keys():
print(tplt.format(word, len(a_dic[word]), str(a_dic[word]), chr(12288)))
def main():
# 讀取filename下的英文文本文件 將每一行作為單獨(dú)的文本
# 建立倒排索引。
filename = './Reverse_Index_Word2.txt'
matrix = dic_sort(read_file(filename=filename))
show_dic(matrix)
if __name__ == '__main__':
main()
(3) 運(yùn)行結(jié)果
可以讀取更大規(guī)模的文檔,此處選取小文本是為了便于展示。文章來源:http://www.zghlxwxcb.cn/news/detail-476495.html
歸一化的處理被我注釋掉了 需要時(shí)可以刪除#符號(hào)。文章來源地址http://www.zghlxwxcb.cn/news/detail-476495.html
#讀入的文檔
new home sales top forecasts
home sales rise in july
increase in home sales in july
july new home sales rise
# 運(yùn)行結(jié)果
"D:\Program Files\Python\python.exe"
詞項(xiàng) 文檔頻率 倒排記錄
forecasts 1 [1]
home 4 [1, 2, 3, 4]
in 2 [2, 3]
increase 1 [3]
july 3 [2, 3, 4]
new 2 [1, 4]
rise 2 [2, 4]
sales 4 [1, 2, 3, 4]
top 1 [1]
Process finished with exit code 0
到了這里,關(guān)于搜索引擎:常用信息檢索方式介紹與倒排索引實(shí)現(xiàn)(Python)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!