Python3深度学习库Keras/TensorFlow打造自己的聊天机器人

聊天机器人(ChatRobot)的概念我们并不陌生,也许你曾经在百无聊赖之下和Siri打情骂俏过,亦或是闲暇之余与小爱同学谈笑风生,无论如何,我们都得承认,人工智能已经深入了我们的生活 。目前市面上提供三方api的机器人不胜枚举:微软小冰、图灵机器人、腾讯闲聊、青云客机器人等等,只要我们想,就随时可以在App端或者web应用上进行接入 。但是,这些应用的底层到底如何实现的?在没有网络接入的情况下,我们能不能像美剧《西部世界》(Westworld)里面描绘的那样,机器人只需要存储在本地的“心智球”就可以和人类沟通交流,如果你不仅仅满足于当一个“调包侠”,请跟随我们的旅程,本次我们将首度使用深度学习库Keras/TensorFlow打造属于自己的本地聊天机器人,不依赖任何三方接口与网络 。
首先安装相关依赖:
pip3 install Tensorflowpip3 install Keraspip3 install nltkpip3 install pandas然后撰写脚本test_bot.py导入需要的库:
import nltkimport sslfrom nltk.stem.lancaster import LancasterStemmerstemmer = LancasterStemmer()import numpy as npfrom keras.models import Sequentialfrom keras.layers import Dense, Activation, Dropoutfrom keras.optimizers import SGDimport pandas as pdimport pickleimport random这里有一个坑,就是自然语言分析库NLTK会报一个错误:
Resource punkt not found正常情况下,只要加上一行下载器代码即可
import nltknltk.download('punkt')但是由于学术上网的原因,很难通过Python/ target=_blank class=infotextkey>Python下载器正常下载,所以我们玩一次曲线救国,手动自己下载压缩包:
https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/packages/tokenizers/punkt.zip解压之后,放在你的用户目录下即可:
C:Usersliuyuetokenizersnltk_datapunktok,言归正传,开发聊天机器人所面对的最主要挑战是对用户输入信息进行分类,以及能够识别人类的正确意图(这个可以用机器学习解决,但是太复杂,我偷懒了,所以用的深度学习Keras) 。第二就是怎样保持语境,也就是分析和跟踪上下文,通常情况下,我们不太需要对用户意图进行分类,只需要把用户输入的信息当作聊天机器人问题的答案即可,所这里我们使用Keras深度学习库用于构建分类模型 。
聊天机器人的意向和需要学习的模式都定义在一个简单的变量中 。不需要动辄上T的语料库 。我们知道如果玩机器人的,手里没有语料库,就会被人嘲笑,但是我们的目标只是为某一个特定的语境建立一个特定聊天机器人 。所以分类模型作为小词汇量创建,它仅仅将能够识别为训练提供的一小组模式 。
说白了就是,所谓的机器学习,就是你重复的教机器做某一件或几件正确的事情,在训练中,你不停的演示怎么做是正确的,然后期望机器在学习中能够举一反三,只不过这次我们不教它很多事情,只一件,用来测试它的反应而已,是不是有点像你在家里训练你的宠物狗?只不过狗子可没法和你聊天 。
这里的意向数据变量我就简单举个例子,如果愿意,你可以用语料库对变量进行无限扩充:
intents = {"intents": [{"tag": "打招呼","patterns": ["你好", "您好", "请问", "有人吗", "师傅","不好意思","美女","帅哥","靓妹","hi"],"responses": ["您好", "又是您啊", "吃了么您内","您有事吗"],"context": [""]},{"tag": "告别","patterns": ["再见", "拜拜", "88", "回见", "回头见"],"responses": ["再见", "一路顺风", "下次见", "拜拜了您内"],"context": [""]},]}可以看到,我插入了两个语境标签,打招呼和告别,包括用户输入信息以及机器回应数据 。
在开始分类模型训练之前,我们需要先建立词汇 。模式经过处理后建立词汇库 。每一个词都会有词干产生通用词根,这将有助于能够匹配更多用户输入的组合 。
for intent in intents['intents']:for pattern in intent['patterns']:# tokenize each word in the sentencew = nltk.word_tokenize(pattern)# add to our words listwords.extend(w)# add to documents in our corpusdocuments.append((w, intent['tag']))# add to our classes listif intent['tag'] not in classes:classes.append(intent['tag'])words = [stemmer.stem(w.lower()) for w in words if w not in ignore_words]words = sorted(list(set(words)))classes = sorted(list(set(classes)))print (len(classes), "语境", classes)print (len(words), "词数", words)


推荐阅读