FAQ
所謂FAQ(Frequently Asked Questions)問答娄帖,指的是通過構(gòu)建一個數(shù)量巨大的問題答案庫來作為語料庫桑驱,當輸入一個問題時鳖粟,通過計算該問題與語料庫中的所有問題的語義相似度缕贡,給出語義最相似的問題所對應(yīng)的答案曙强。兩個問題語義相似度的計算方法,有:余弦相似度涎拉、Jaccard相似度瑞侮、BM25相似度等。
Indexing
在AnyQ系統(tǒng)中鼓拧,索引(Indexing)模塊的作用是根據(jù)所給定的問題答案數(shù)據(jù)集半火,通過將其轉(zhuǎn)換為語義索引庫,從而提供檢索(Retrieval)季俩、匹配(Matching)模塊進行語義相似度計算钮糖,匹配出與所提問題最相似的答案。
添加語義索引
語義索引庫構(gòu)建 AnyQ/build/example/conf/
- 將灌庫文件faq_file(utf8編碼)轉(zhuǎn)換成Json格式酌住,在最初的AnyQ系統(tǒng)中店归,所提供的問題答案數(shù)據(jù)集位于
AnyQ/build/solr_script/sample_doc
阎抒。
{"question": "XXX", "answer": "XXX", "id": XXX}
cp -rp ../tool/solr ./solr_script
mkdir -p faq
python solr_script/make_json.py solr_script/sample_docs faq/schema_format faq/faq_json
- 對Json文本添加索引id:
awk -F "\t" '{print ++ind"\t"$0}' faq/faq_json > faq/faq_json.index
- 在anyq詞典配置dict.conf增加語義表示模型的插件:
dict_config{
name: "fluid_simnet"
type: "PaddleSimAdapter"
path: "./simnet"
}
- 在analysis.conf中增加query語義表示的插件:
analysis_method {
name: "method_simnet_emb"
type: "AnalysisSimNetEmb"
using_dict_name: "fluid_simnet"
dim: 128
query_feed_name: "left"
cand_feed_name: "right"
embedding_fetch_name: "tanh.tmp"
}
- 生成語義索引庫:
./annoy_index_build_tool example/conf/ example/conf/analysis.conf faq/faq_json.index 128 10 semantic.annoy 1>std 2>err
語義索引庫使用 AnyQ/build/example/conf/
- 把帶索引id的faq庫文件和語義索引庫放到anyq配置目錄下
cp faq/faq_json.index semantic.annoy example/conf
- 在dict.conf中配置faq庫文件的讀取
dict_config {
name: "annoy_knowledge_dict"
type: "String2RetrievalItemAdapter"
path: "./faq_json.index"
}
- 在retrieval.conf中配置語義檢索插件
retrieval_plugin {
name : "semantic_recall"
type : "SemanticRetrievalPlugin"
vector_size : 128
search_k : 10000
index_path : "./example/conf/semantic.annoy"
using_dict_name: "annoy_knowledge_dict"
num_result : 10
}
Analysis
問題分析模塊(Analysis)是整個系統(tǒng)中對輸入問題進行解析的第一個模塊。該模塊所完成的主要功能有:
- 對句子進行分詞娱节;
- 對分詞后的每個單詞進行詞性標注(POS)挠蛉;
- 將每個單詞進行詞向量表示祭示;
- 命名實體識別(NER)肄满。參考文章
但是,在最初的AnyQ系統(tǒng)中质涛,其僅實現(xiàn)了句子分詞及詞向量表示功能稠歉,并提供了相應(yīng)功能插件的配置。其他汇陆,例如POS和NER的功能需要用戶自行實現(xiàn)并添加怒炸。
添加分詞
用戶詞典
在策略插件中使用的詞典,需在 AnyQ/build/example/dict.conf
中配置毡代。當前系統(tǒng)的詞典插件主要包括以下幾種:
- 哈希詞典:HashAdapter<TYPE1, TYPE2>
- 干預(yù)詞典:String2RetrievalItemAdapter
- 切詞詞典: WordsegAdapter
- Paddle SimNet匹配模型詞典: PaddleSimAdapter
- Tensorflow模型詞典: TFModelAdapter
配置方式如下所示:
# 干預(yù)詞典
dict_config {
name: "rank_weights"
type: "String2FloatAdapter"
path: "./rank_weights"
}
# 切詞詞典
dict_config {
name: "lac"
type: "WordsegAdapter"
path: "./wordseg_utf8"
}
# paddle SimNet匹配模型詞典
dict_config{
name: "fluid_simnet"
type: "PaddleSimAdapter"
path: "./simnet"
}
分詞
在 AnyQ/build/example/analysis.conf
中可以增添query分析策略插件阅羹。當前系統(tǒng)的analysis插件主要包括以下幾種:
- 切詞:AnalysisWordseg
- query語義向量表示:AnalysisSimNetEmb
- query替換: AnalysisQueryIntervene
配置方式如下所示:
# 切詞
analysis_method {
name: "method_wordseg"
type: "AnalysisWordseg"
using_dict_name: "lac"
}
添加詞向量表示
句子分詞功能添加完畢后,要實現(xiàn)分好詞的每個單詞進行詞向量的表示教寂,需要在解析模塊的配置文件中(AnyQ/build/example/analysis.conf)添加相應(yīng)功能插件捏鱼,其格式如下:
# 語義向量
analysis_method {
name: "method_simnet_emb"
type: "AnalysisSimNetEmb"
using_dict_name: "fluid_simnet"
dim: 128
query_feed_name: "left"
cand_feed_name: "right"
embedding_fetch_name: "tanh.tmp"
}
Retrieval
輸入的問題通過分析模塊(Analysis)對問題進行分詞,詞向量表示等操作后酪耕,再輸入到問題檢索模塊(Retrieval)导梆,由該模塊將問題帶入到FAQ數(shù)據(jù)集中進行檢索,得到前N個候選問題迂烁。
該模塊目前所提供的問題檢索功能有:
- 基于關(guān)鍵詞的檢索(Term檢索看尼,TermRetrievalPlugin)
- 基于語義的檢索(SemanticRetrievalPlugin)
- 人工干預(yù)檢索(ManualRetrievalPlugin)
基于關(guān)鍵詞
基于關(guān)鍵詞的檢索,即根據(jù)已添加的數(shù)據(jù)集盟步,通過TF-IDF藏斩,為該數(shù)據(jù)集構(gòu)建倒排索引,當一個已經(jīng)分詞的問題輸入后却盘,匹配前N個候選問題狰域。
檢索模塊的配置路徑為 AnyQ/build/example/retrieval.conf
,通過在該文件中添加關(guān)鍵詞索引插件:
retrieval_plugin {
name : "term_recall_1"
type : "TermRetrievalPlugin"
search_host : "127.0.0.1"
search_port : 8900
engine_name : "collection1"
solr_result_fl : "id,question,answer"
solr_q : {
type : "EqualSolrQBuilder"
name : "equal_solr_q_1"
solr_field : "question"
source_name : "question"
}
num_result : 15
}
其中谷炸,solr_q是solr搜索服務(wù)器查詢的插件北专,該插件所提供的搜索類型(type)有:
- EqualSolrQBuilder:字段等于
- BoostSolrQBuilder:字段term加權(quán)
- ContainSolrQBuilder:字段包含關(guān)鍵詞
- SynonymSolrQBuilder:字段term同義詞
- DateCompareSolrQBuilder:日期字段比較
基于語義
基于語義的檢索,是由AnyQ中的SimNet模塊根據(jù)所提供數(shù)據(jù)集訓(xùn)練好后的模型旬陡,來對輸入問題(詞向量表示)與候選問題進行計算檢索拓颓。檢索模塊的配置路徑為 AnyQ/build/example/retrieval.conf
,通過在該文件中添加語義索引插件:
retrieval_plugin {
name : "semantic_recall"
type : "SemanticRetrievalPlugin"
vector_size : 128
search_k : 10000
index_path : "./example/conf/semantic.annoy"
using_dict_name: "annoy_knowledge_dict"
num_result : 10
}
Matching
通過檢索模塊(Retrieval)從索引庫中得到N個候選問題以后描孟,需要帶入到問題匹配模塊(Matching)驶睦,依次對每個候選問題與輸入問題計算其相似度砰左。對于同一個候選問題-輸入問題對來說,可以同時計算多種類型的相似度.
該模塊目前所提供的相似度計算功能有:
- 編輯距離相似度:EditDistanceSimilarity;
- Cosine相似度:CosineSimilarity
- Jaccard相似度: JaccardSimilarity
- BM25相似度: BM25Similarity
- Paddle SimNet匹配模型相似度: PaddleSimilarity
- Tensorflow匹配模型相似度: TFSimilarity
分詞
將候選問題與輸入問題帶入到問題匹配模塊(Matching)以后场航,為了能夠與輸入問題進行相似度計算缠导,首先需要對候選問題進行分詞,其配置路徑為: AnyQ/build/example/rank.conf
溉痢。
配置插件為:
# 對候選切詞
matching_config {
name : "wordseg_process"
type : "WordsegProcessor"
using_dict_name: "lac"
output_num : 0
rough : false
}
相似度計算
在該模塊中僻造,對候選問題與輸入問題進行相似度計算主要分為兩種:傳統(tǒng)的距離度量學(xué)習的方法(Cosine相似度、Jaccard相似度等)和深度學(xué)習的方法(語義相似度計算)孩饼。其配置路徑為: AnyQ/build/example/rank.conf
髓削。
配置插件為:
# Jaccard相似度
matching_config {
name : "jaccard_sim"
type : "JaccardSimilarity"
output_num : 1
rough : false
}
# Paddle SimNet匹配模型相似度
matching_config {
name: "fluid_simnet_feature"
type: "PaddleSimilarity"
using_dict_name: "fluid_simnet"
output_num : 1
rough : false
query_feed_name: "left"
cand_feed_name: "right"
score_fetch_name: "cos_sim_0.tmp"
}
# Tensorflow匹配模型相似度
matching_config {
name : "tf_qq_match"
type : "TFSimilarity"
using_dict_name: "tf_qq_match"
output_num : 1
rough : false
tfconf : {
pad_id : 0
sen_len: 32
left_input_name: "left"
right_input_name: "right"
output_name: "output_prob"
}
}
其中output_num表示該插件輸出的相似度值個數(shù),對于不輸出相似度的插件(如WordsegProcessor)镀娶,output_num應(yīng)配置為0; rough配置為true表示該相似度用于粗排立膛,反之則用于精排。
計算相似度需要先對候選切詞梯码,因此WordsegProcessor插件應(yīng)該配置在其他matching_config之前宝泵。
需要注意的是,在該模塊配置文件中轩娶,如果配置了多種相似度計算插件儿奶,則對于一個問題對來說,將對其分別計算相應(yīng)插件的相似度罢坝,最終得到多個相似度廓握,每一個相似度可看作該問題對的一個特征,這多個特征最終需要帶入到問題打分模塊(rank)來對該問題對進行綜合的打分嘁酿。
Ranking
在 AnyQ/build/example/rank.conf
中配置predictorc插件隙券,用于根據(jù)多個相似度對候選計算得分。當前系統(tǒng)的rank插件主要包括以下幾種:
- 線性預(yù)測模型: PredictLinearModel
- XGBoost預(yù)測模型: PredictXGBoostModel
- 特征選擇預(yù)測模型:PredictSelectModel
配置格式如下:
rank_predictor {
type: "PredictLinearModel"
using_dict_name: "rank_weights"
}