前面六篇博客主要探究了QG(Question Generation)任务的基本策略、评价指标;描述了我的初步探索;以及给出了数据处理的方法以及训练模型的构建方法;最后针对训练好的模型生成“问答对”;最后对生成的“问答对”用一个分类模型评价有效性,并过滤掉无效问答对:
- 博客1:基本策略
- 博客2:评价指标、初步探索
- 博客3:训练数据和预测数据预处理的部分
- 博客4:模型的构建
- 博客5:生成“问答对”
- 博客6:问答对有效性过滤(基于文本分类任务)
- 博客7:用问题库检索服务
一、问题库的检索
1.1 检索的输入与输出
由于这个项目需要和整体的QA系统进行交互,QG模块预生成问题作为检索的一大重要部分,需要充当后端,为前端提供检索服务。
对于已经生成的问题库,我采用Lucene对生成的问题检索,具体来讲,它的输入输出如下:
输入:
- 用户的query(用户主动提问)
- 用户上下文信息
输出:
- 列表包含问答对以及其所在的上下文
1.2 检索的实现
首先构建索引,构建索引的方式:
- 我先创建了分词器,然后将索引写入到相应的磁盘空间上,写之前要清除上一次写入的数据。
- 需要注意的是,创建query所用的分词器必须和生成索引所用的query相同。
public class IndexManager{
static Similarity perFieldSimilarities = new PerFieldSimilarityWrapper() {
public Similarity get(String name) {
return new BM25Similarity();
}
};
public void createIndex() throws Exception{
// 采集数据
QAPairsReader reader = new QAPairsReader();
List<QAPairs> qaPairsList = reader.readQAPairsList();
// 文档集合
List<Document> docList = new ArrayList<Document>();
for (QAPairs pair: qaPairsList) {
// 创建文档对象
Document document = new Document();
// 创建域对象并且放入文档对象中
document.add(new TextField("question", pair.getQuestion(), Field.Store.YES));
document.add(new StoredField("context", pair.getContext()));
document.add(new StoredField("answer", pair.getAnswer()));
// 将文档对象放入到文档集合中
docList.add(document);
}
// 创建分词器
Analyzer analyzer = new IKAnalyzer();
// 创建Directory目录对象, 目录对象表示索引库的位置
String test_path = "/Users/chenshichu/Lucence_Index2";
String save_path = "/Users/chenshichu/Documents/陈世初/大学/大三下学期/项目实训/后端部署/src/main/resource";
Directory dir = FSDirectory.open