石鳳貴
(馬鞍山師范高等專科學校軟件工程系,馬鞍山243041)
互聯網是一個龐大的知識庫,在浩瀚的知識庫中,我們如何索取所需知識?搜索引擎完成了這個任務。百度搜索是全球最大的中文搜索,擁有全球最大的中文網頁庫,網頁數量每天以萬級的速度增長。百度提供的服務包括百度網頁、百度知道、百度貼吧等。搜索引擎大多以關鍵詞的方式檢索信息,不能清晰地理解用戶的要表達的意圖,返回結果是網頁的集合,需要用戶進行二次篩選。對于傳統的自動問答系統需要建立一個非常龐大的知識庫,這個成本相當大。我們可以充分發揮搜索引擎和自動問答的各自優點,有機結合。
本文結合自然語言處理技術和網絡爬蟲技術,利用百度網頁搜索功能,構建自動問答系統。將互聯網作為自動問答系統的知識庫,通過爬蟲技術利用百度搜索對用戶問題進行檢索,根據檢索結果構建語料庫,利用自然語言處理技術對檢索結果進行答案提取,從而將答案返回給用戶。
自然語言處理(Natural Language Processing,簡稱NLP)是計算機科學領域與人工智能領域中的一個重要方向,研究人與計算機之間用自然語言進行有效通信,融語言學、計算機科學、數學于一體的科學。問答系統(Question Answering,簡稱QA)是自然語言處理領域的一個重要應用,具有非常高的使用價值。
問答系統模型[1]分為四層,分別為用戶層、問題理解層、檢索層、數據層:
用戶層:即UI 層,提供用戶輸入問題,顯示系統返回的答案。
問題理解層:系統的核心層,負責問題的理解,包括分詞、停用詞處理、計算相似度。
檢索層:負責內容爬取、答案檢索,包括信息檢索、答案抽取。
數據層:知識庫,處理數據庫,主要包括專業詞典庫、停用詞庫、同義詞庫、領域本體庫、《知網》本體、QA集、互聯網。
問答系統模型如圖1 所示。
(1)分詞
詞是表達句子意思的最小單位。中文語句結構復雜,相對于英文沒有明顯的標記,不像英文具有明顯的分界符。分詞是語句理解的基礎和關鍵。常用的方法主要有:基于字典分詞算法、向匹配法、基于統計的分詞算法、基于理解的分詞算法[2]。本文采用jieba 中文分詞工具進行分詞。
(2)FAQ
FAQ 庫(Frequently Asked Question)是把用戶經常提出的問題和對應的答案預先保存起來,檢索時首先從FAQ 中檢索與用戶問題相關的問題,從而返回問題的答案。基于FAQ 的問答系統執行效率和準確度相對都比較高,同時也容易實現,比較適合應用于針對特定領域應用的問答系統。
本文為非特定領域應用,借助FAQ 思想,利用爬蟲技術爬取標題和摘要,構造問題答案集。
(3)問題分析
問題分析是問題理解的基礎,只有科學的分析用戶提出的問題才能準確的理解用戶問題。問題分析需要通過一定的算法分析,包括問題預處理、分詞、關鍵詞提取、消除停用詞、詞性標注等[3]。
(4)信息檢索
信息檢索方式包括搜索引擎檢索、數據庫檢索。廣泛使用的搜索引擎有百度、Google、360 搜索等。數據庫檢索需要通過人工整理建立特定數據庫,建立索引,選擇排序算法進行排序。信息檢索的主要目的是通過搜索獲取大量文檔,返回與問題相關的數據集。
字是構成中文句子的最小單位,詞語表達句子的含義,是句子語義和句法的基本單位。因此,需要通過計算詞語的相似度來計算句子的相似度,詞語的相似度也應結合其應用背景。詞語相似度計算包含兩類:一類是基于大規模語料庫;一類是基于語義詞典,如《知網》、《同義詞詞林》。
句子相似度由句子間語義上的匹配度反映,句子相似度計算就是計算兩個句子在語義上的吻合度,值的大小決定相似程度,取值為[0,1],值越大說明越相似,反之越不相似。句子相似度計算可以分為:
(1)基于關鍵詞計算:提取句子中的關鍵詞,根據詞的詞頻和詞性對句子中的詞進行處理。
(2)基于語義依存計算:深層次分析句子的句法結構,根據依存關系計算計算相似度。
(3)基于語義分析計算:構建語義知識庫,利用知識庫計算句子中詞的相似度,從而計算句子的相似度。
(4)編輯距離的相似度計算:分析兩個詞語轉變成相同詞語需要的最小步驟。
本文根據句子的詞向量的余弦值來計算句子的相似度。
本文分詞采用jieba 分詞,相似度計算采用Word2Vec 詞向量模型,答案語料庫采用網絡爬蟲構建,系統開發工具采用Python。系統的實現引入了深度學習算法思想。

圖1
大數據時代,人類社會的數據正處于急速增長。數據蘊含了巨大的價值,無論是對個人工作和生活還是企業發展和創新商業模式都有著很大的幫助。數據從何而來?需要從網絡獲取。要獲取全面、有效、準確的數據,不可能靠人工獲取,應由程序從信息的海洋——互聯網抓取。這個從互聯網抓取數據的程序就是網絡爬蟲。爬蟲爬取的數據,根據需要做進一步的分析挖掘[5]。
本文語料庫直接利用網絡爬蟲通過百度網頁搜索獲取,同時為了有效應對網站反爬蟲,使用Chrome 瀏覽器的headless 模式實現。Headless 模式就是在無界面模式下運行瀏覽器。
中文分詞是中文自然語言處理的第一步,一個優秀的分詞系統取決于足夠的語料和完善的模型。很多機構都會開發和維護自己的分詞系統,本文使用一款完全開源、簡單易用的分詞工具——jieba 中文分詞。
中文分詞的模型主要分為兩大類:基于規則和基于統計,jieba 分詞結合了基于規則和基于統計兩類方法,同時jieba 提供了3 中分詞模式。jieba 支持分詞、關鍵詞提取、詞性標注、自定義分詞詞典和停用詞詞典。文本分詞后就可以制作詞向量[4]。
計算機只能識別和計算數字,傳入模型計算的數據只能是數字或向量,處理自然語言時首先就要進行數據預處理即符號數學化。最初一般采用One-Hot 獨熱編碼,但沒有考慮詞的含義和詞之間的關系。最常見、效果比較好的就是詞向量Word2Vec。
(1)語言模型
詞向量是在訓練詞語言模型的同時得到的。要想從自然語言文本中學習有效信息,需要從自然語言文本中統計并建立一個語言模型。這里介紹的是從大量未標注的普通文本數據中無監督的學習出詞向量。
(2)數據格式化處理
分詞完成后,如果文本規模較大,分詞結果應保存為文件,如果較小可以直接制作詞向量。制作詞向量前,需要將數據處理成gensim 可以處理的格式:
方法1:直接處理成列表嵌套的數據格式,如[[第一句分詞],[第二句分詞],…]。
方法2:利用gensim.models.word2vec 模塊中Line-Sentence、PathLineSentences、Text8Corpus 類讀取分詞結果文件,生成一個迭代對象,封裝的內容是分詞后的詞列表。
本文語料為動態語料,同時規模較小,因此采用方法1 格式化數據。
(3)訓練詞向量模型
word2vec.Word2Vec (sentences=None, size=100, window=5,min_count=5)
sentences:就是上面的準備好的數據,可以是簡單的list 或這個是其他幾個方法生成的可迭代對象。size:生成詞向量的大小,也就是特征向量的維數。window:一個詞上下文的最大關聯距離,即上下文幾個詞對這個詞有影響。
min_count:忽略詞頻小于這個值的詞;還有一些學習率等參數。
使用jieba 中文分詞工具進行分詞。
def tokenizer(sentence):
words_cut=jieba.cut(sentence,cut_all=False)
return list(words_cut)#返回分詞結果
根據用戶問題爬取相應資源,構建問題-答案語料。
Step1:爬蟲打開百度首頁,將用戶問題輸入到搜索框后執行搜索
def spider(driver,keyword_q): #driver:瀏覽器,keyword_q:用戶輸入的問題
#打開百度首頁
driver.get("https://www.baidu.com")
time.sleep(2)
#獲取輸入框
inputKeyWord = driver.find_element_by_xpath('//*[@id="kw"]')
inputKeyWord.send_keys(keyword_q)#輸入搜索內容
#獲取”百度一下”按鈕
submit_baidu = driver.find_element_by_xpath('//*[@id="su"]')
submit_baidu.click()#單擊按鈕
Step2:解析爬取結果首頁,構建問題-答案語料
#driver:瀏覽器,wordlists_question_cut:保存問題-答案對中問題分詞
def parse(driver,wordlists_question_cut):
#解析標題-摘要代碼段,過濾搜索結果中關于廣告的主題
內容
title_abstracts = driver.find_elements_by_xpath('//*[@class="result c-container"]')
title_abstracts.extend (driver.find_elements_by_xpath ('//*[@class="result-op c-container xpath-log"]'))
#解析keyword-abstract 對
for title_abstract in title_abstracts:
#解析出標題代碼塊
#解析出標題鏈接
#構造含有鏈接的標題即Q
#對標題內容即Q 進行分詞并保存
#解析摘要代碼塊,然后解析文本內容
#保存問題-答案對
return 問題答案集
def trainModel(modelname,train_corpus_words_cut):
#設置模型參數
size=400 #每個詞的向量維度
window=5 #詞向量訓練時的上下文掃描窗口大小,窗口為5 就是考慮前5 個詞和后5 個詞
min_count=1 #設置最低頻率,默認是5,如果一個詞語在文檔中出現的次數小于5,那么就會丟棄
workers = multiprocessing.cpu_count()# 訓練的進程數,默認是當前運行機器的處理器核數。
model=word2vec.Word2Vec()#訓練模型
return model
計算用戶問題與問答答案集中問題的向量夾角余弦值來計算他們的相似度。
def calSimilarity_Q(model,wordlist_Qask_cut,wordlists_Q_cut):
similarity_Qs={} #保存Q 的相似度,便于后面檢索答案
for wordlist_Q in wordlists_Q_cut:
similarity = model.n_similarity (wordlist_Qask_cut,wordlist_Q)
Q_text="".join(wordlist_Q)#將Q 分詞結果還原為Q 內容
similarity_Qs[Q_text]=similarity
return similarity_Qs
def search_A(similarity_Qs,Q_As):
#按照字典similarity_Qs 的value 值(相似度)降序,
#取Top5
#遍歷問題答案集,如果檢索到就返回檢索結果
return 檢索結果

圖2

圖3
本文對問答系統相關技術進行了分析,構建了問答系統模型,介紹了系統實現所使用的網絡爬蟲、jieba中文分詞、Word2Vec 詞向量等關鍵技術,給出了系統實現的詳細算法,最后提供了系統使用效果。從運行效果來看,能很好地滿足用戶的需求。