阿鲲的博客 主修软件工程和算法模型,极客成长中

多功能工具包(聊天机器人)

2019-03-20
jktian

阅读:


项目地址

1 TODO (DONE)

  1. 重构代码,易扩展性

  2. 加入数据库存储

  3. 爬虫优化:尝试scrapy框架

  4. 推荐算法设计

2 问题以及解决

2.1 字体显示问题

  • linux中的python无法正常显示中文。

​ $ cp *.ttf /usr/share/fonts/TTF

​ $ fc-list grep

​ $ fc-cache -fv # 刷新,f表示force, v表示view

  • 查看python安装路径

​ python交互环境下:

​ $ import sys

​ $ sys.path

​ catfish搜索 从anaconda入手搜索

​ 一步步$ ls $ subl3 查看源码文件

  • 包可能存在的目录

    /opt/anaconda/lib

    ~/.conda/envs/python36/lib/python3.6/site-packages

    /home/jktian/.conda/envs/python36/lib/python3.6/tkinter/font.py

# 查看tkinter支持的字体
from tkinter import *
import tkinter.font as tkFont
root = Tk()
print(tkFont.families())
  1. 给linux系统安装中文字体,并找到字体文件的具体位置
  2. 希望在python-tkinter的库函数中直接按照文件名调用字体;未找到代码实现,即使找到了tkinter的源代码
  3. 通过tkinter提供的函数,找到支持的系统字体(即当前平台可用的字体),并筛选出支持中文的字体
    font_list = ['sampige','likhan','orya','akrutimal2','droid naskh shift alt','gurbanibolilite','pothana2000','tscu_comic','malotf','tscu_times','sagar','padmaa','akaash'] # 不完全
    

    summary

  4. 不同的图形函数库对跨平台的支持性不同,要选择合适的库进行图形界面的开发。 - 可选项:python:tkinter, pyqt
  5. 对于字体的支持。不仅要操作系统支持,还要图形函数库的支持,所以只有.ttf文件是不够的

扩展

类比tkinter:css中引入外部字体,使用任意外部字体文件。通过@font-face. 字体文件后缀.TTF/EOT/SVG

css支持引入外部字体文件,但tkinter函数库不支持 在“现代”Linux上 ,有2级字体支持: 第一种是 “native”X支持, 第二个是由图形工具包提供的使用(Qt与KDE,但我认为OpenOffice和FireFox使用Gtk)。 不幸的是,tk - 因此Tkinter - 只看到X处的字体水平,而不是Qt / Gtk水平。

2.2 几个批量操作(自动化)

  1. 批量创建函数(无问题,每一个函数确实是不同的)
  2. 批量将按钮和函数关联(由于执行顺序问题,所有按钮都关联到最后一个函数,因为改变了self, 动态类型就是这样)

    解决方案: - 不要在一个消息类中创建所有联系人。要创建一个联系人类,每个联系人作为一个实例。 - 本质:类和对象的关系,选择使用要谨慎

  3. 抽象出联系人类,继承类有Bolt,People,Translator,MovieRecomm类 问题:按钮的转换有问题,由于联系人类是Msg类的成员变量,无法访问并修改Msg类的其他成员变量,所以按钮的对应函数无法正常工作,即无法完成切换联系人功能

    • 矛盾点:想要批量操作,逻辑清晰。但作用域存在问题
    • 解决方案:将Msg类的实例(即self)传入Msg的成员变量Connector类中,则Connector类可以对Msg实例进行修改

      summary

      - 面向接口编程。先定义接口,假设底层函数已经写好
      

2.3 数据库 & 智能回复算法设计

jieba概览

  • 分词模式。精确,全、搜索引擎
  • 关键词以及其权重提取
  • 词性标注-基于分词

    目标

    1. 数据库预处理。得到对应输入和输出,以及其分词以及词性标注
输入 输出 输入分词 输出分词
你是谁 我是你 [(你,n),] [(我,n),]
  1. 用户输入数据。分词
    • 方案一(已实现):对输入分词,找到和先验输入的距离,根据距离前几的输出以及词性,进行混合输出(每个词性中随机挑选某个输入)。
      • 难点:灵活度很大,一句话的组成成分很复杂,可以是动宾短语,可以是整句。词性的组合是难点。
      • 理论依据:根据现实中对方的应答,做出回复
      • 此处对所有词性的顺序打乱,是否输出按照概率,输出哪一个词按照概率。没有考虑具体如何成句(考虑到网上聊天的随意性,好像此处假设合理)
    • 方案二(不合适):数据库预处理,得到新表。对得到的输出句子的重复数目进行统计,挑选前几名,根据词性进行混合
    • 方案三(已实现):直接根据输入,和对方的所有输出进行距离计算,算出距离最小的。理论依据:对话的内容相关即可。之后可以根据词性进行混合
      • 只能在原有的输出中原样输出
(词语,词性) 可能的输出句子

问题:真实的聊天记录不是问答式的,不是单向的,在整个上下文中,问答角色的确立是模糊的。所以很难根据输入确定输出。直接按照名字和话语列表为一行,然后按照周围的其他角色当做回复 |姓名|输入|输入分词|

summary

  1. 按照框架,搭脚手架
  2. 根据不同的方案,比对结果
  3. 理论依据:对话的内容相关即可。之后可以根据词性进行混合

后续研究方向

一个句子的构成是多种多样的,可以由不同类型以及不同顺序的词性构成,但又存在顺序规律,不是完全随机的。需要在几个固定模式下进行随机,效果会更好。未考虑相邻词的联系

数据库选择 & 基本使用

  • SQLite: 适合桌面端和移动端,轻量级,可嵌入
  • MySQL: 服务器端,支持高并发访问,占用的内存大
    1. 登录
    2. 选择数据库

      $ show databases $ use database_name

    3. 选择查看表

      desc table_name 查看表结构 在Python中操作数据库时,要先导入数据库对应的驱动,然后,通过Connection对象和Cursor对象操作数据。数据以.db形式存储,读取文件用建立连接的方式。最后conn要提交,关闭

python字符串和列表的转换

数据库中,需要保存分词结果,是一个内部为元组的列表,只能先转换为字符串,然后取出后转换为列表,普通的分隔符无效,需要设置特殊的分隔符。

  • 字符串==》list: str.split(‘’) , 直接用list()是按单个字符划分
  • 列表==》字符串: ““.join(list), 直接用str()会把[]包含进去

3 最终改动

消息记录的存储

在class_msg.py中的sendmsg函数中,即和发送按钮关联的命令函数中,添加数据库的插入操作,紧跟两个窗口显示消息的操作之后。

智能回复

  • 之前是随机数输出,文件操作
  • 现在把文件中的内容存储在数据库中。以xiaochen_and_me数据表为例,改动class_conn_people.py中的auto_reply()函数,对fin_msg进行赋值操作

    此处并未修改,仍然为随机数输出,但在database_about/intell_reply.py中,做了详细的说明,代码已跑通,有三种算法模式供选择


上一篇 linux-manjaro

Comments

Content