功能实现
jieba_userdict.py
读取本地数据集,获取作者和关键词,存储到本地userdict.txt文件中,用于后面jieba.load_userdict("…/data/userdict.txt"),可以从问句中提取出语料库里含有的关键词和作者名字,并赋予相应的词性,用于后面的模板匹配并且防止分词出错
process_question.py.py
处理问题的文件
主要功能:
- 初始化相关设置:读取词汇表,训练分类器,连接数据库
- 接收原始问题,对原始问题进行分词、词性标注等处理,对问题进行抽象
- 根据抽象后的问题选择对应模板,根据问题模板的具体类容,构造cql语句,并查询
question_template.py
- 在process_question.py.py使用,判断问题所属的模板,选择对应的处理
- 连接数据库,生成查询语句,返回结果
question_classification.py
利用朴素贝叶斯进行问题分类
主要代码
question_template.py.py
- get_question_answer
[‘word/flag’]和“问题模板编号 \t 问题模板”
定义了词列表和词性列表,根据这俩去调函数执行cql
def get_question_answer(self, question, template):
# 如果问题模板的格式不正确则结束
assert len(str(template).strip().split("\t")) == 2
# 得到模板id和模板的内容 ditc[1]=nm 文章关键词
template_id, template_str = int(str(template).strip().split("\t")[0]), str(template).strip().split("\t")[1]
self.template_id = template_id
self.template_str2list = str(template_str).split()
# 预处理问题
question_word, question_flag = [], []
# 构建词列表和词性列表
for one in question:
word, flag = one.split("/")
question_word.append(str(word).strip())
question_flag.append(str(flag).strip())
assert len(question_flag) == len(question_word)
self.question_word = question_word
self.question_flag = question_flag
self.raw_question = question
# 根据问题模板来做对应的处理,获取答案
answer = self.q_template_dict[template_id]()
return answer
- cql
# 通过nr找到作者名字,通过作者名字搜论文
def get_author_paper(self):
author_name = self.get_name("nr")
answers = self.getDatas.authorToPaper(author_name[0])
return answers
# 通过nm找关键词,通过关键词找论文
def get_keyword_paper(self):
keyword_list = self.get_name('ng')
answers = self.getDatas.keywordToPaper(keyword_list)
return answers
question_template.py
class Question():
def __init__(self):
# 初始化相关设置:读取词汇表,训练分类器,连接数据库
# 训练分类器
self.classify_model = Question_classify()
# 读取问题模板
with(open("../data/question_classification.txt", "r", encoding="utf-8")) as f:
question_mode_list = f.readlines() # 标签类别
self.question_mode_dict = {}
for one_mode in question_mode_list:
# 读取一行
mode_id, mode_str = str(one_mode).strip().split(":")
# 处理一行,并存入
self.question_mode_dict[int(mode_id)] = str(mode_str).strip() # 例如 ditc[1]=nm 文章关键词
# 创建问题模板对象,
self.questiontemplate = QuestionTemplate()
def question_process(self, question):
# 接收问题
self.raw_question = str(question).strip()
# 对问题进行词性标注,返回列表['word/flag']
self.pos_quesiton = self.question_posseg()
# 得到问题的模板“问题模板编号 \t 问题模板”
self.question_template_id_str = self.get_question_template()
# 查询图数据库,得到答案
self.answer = self.query_template()#隐藏了参数self.pos_quesiton和self.question_template_id_str
return (self.answer)
# 返回的result为列表,列表元素为’word/flag‘
def question_posseg(self):
jieba.load_userdict("../data/userdict.txt")
clean_question = re.sub("[\s+\.\!\/_,$%^*(+\"\')]+|[+——()?【】“”!,。?、~@#¥%……&*()]+", "", self.raw_question)
# 正则化后清理后的问题
self.clean_question = clean_question
# 对问题进行词性标注,每个分的词后还有一个标注的词性
question_seged = jieba.posseg.cut(str(clean_question))
result = []
question_word, question_flag = [], []
# 对分词词性后的对象分析
for w in question_seged:
temp_word = f"{w.word}/{w.flag}"
result.append(temp_word)
# 预处理问题
word, flag = w.word, w.flag
question_word.append(str(word).strip())
question_flag.append(str(flag).strip())
assert len(question_flag) == len(question_word)
self.question_word = question_word # 返回一个所有分的词的一个列表
self.question_flag = question_flag # 返回所有分词的词性列表
print(result)
return result
# 返回为“问题模板编号 \t 问题模板”问题模板编号有用,问题模板本身没用
def get_question_template(self):
# 抽象问题
for item in ['nr', 'nm', 'ng']:
while (item in self.question_flag):
ix = self.question_flag.index(item)
self.question_word[ix] = item # 将问题中对应作者,关键词的地方改为他的词性
self.question_flag[ix] = item + "ed"
# 将问题转化字符串
str_question = "".join(self.question_word)
print("抽象问题为:", str_question)
# 通过分类器获取问题模板编号
question_template_num = self.classify_model.predict(str_question)
print("使用模板编号:", question_template_num)
# 得到问题所属模板
question_template = self.question_mode_dict[question_template_num]
print("问题模板:", question_template)
question_template_id_str = str(question_template_num) + "\t" + question_template
return question_template_id_str
# 根据问题模板的具体类容,构造cql语句,并查询
def query_template(self):
# 调用问题模板类中的获取答案的方法
try:
answer = self.questiontemplate.get_question_answer(self.pos_quesiton, self.question_template_id_str)
except:
answer = "我也不知道啊!"
return answer