基于知识图谱的脑卒中人机对话系统

使用技术

采用html5与flask联合,flask作为服务端框架,html5作为前端框架。前后端交互采用Ajax实现,用户、管理员信息储存在MySQL数据库里,日常性对话使用aiml实现,脑卒中相关内容存储在neo4j数据库内。

代码地址

使用方法

按照人机对话.py文件内的注释将代码补全,开启neo4j服务后,运行人机对话.py,在浏览器中输入127.0.0.1:5000进入登录页面,登录账户密码存储在MySQL数据库中,自行建表,保持数据库名、表名与代码中的名字相同(修改哪个随意)。因为设计的较为简单,neo4j中只有症状和对应的概率。

前端实现

前端界面有:登陆界面、管理员界面、用户界面、增删改界面。

HTML文件一览

以管理员界面代码index.html为例进行说明:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
    <link rel="stylesheet" href="static/Login1Style.css" type="text/css" />
    <script type="text/javascript">
        var str1,str2,str3,str4;
        function valid1()
        {
            str1=document.getElementById("useracc").value;
            str2=document.getElementById("userpwd").value;
            if(str1==""||str2=="")
            {
                alert("你还没有输入内容");
                return 2;
            }
            else
            {
                return 1;
            }
        }
        function valid2()
        {
            str3=document.getElementById("adminacc").value;
            str4=document.getElementById("adminpwd").value;
            if(str3==""||str4=="")
            {
                alert("你还没有输入内容");
                return 2;
            }
            else
            {
                return 1;
            }
        }
        function sendmessage1()
        {
            var a=valid1();
            if(a==2) 
                return false;
            else
            {
                document.getElementById("formid").submit();
                return true;
            }
        }
        function sendmessage2()
        {
            var a=valid2();
            if(a==2) 
                return false;
            else
            {
                document.getElementById("formid").submit();
                return true;
            }
        }
        </script>
</head>
<body>
    <form action="/" method="post" id="formid" >
        <div class="container">
            <div id="f" class="front" >
                <div class="contents">
                    <h3 onclick="change1()">USER LOGIN</h3>
                    <input class="text" type="text" name="useracc" id="useracc" align="center"><br><br>
                    <input class="text" type="password" name="userpwd" id="userpwd" align="center"><br><br>
                    <input class="bto" type="submit" name="Login" value="Login" align="center" onclick="sendmessage1()">
                </div>
            </div>
            <div id="b" class="back">
                <div class="contents">
                    <h3 onclick="change2()">ADMIN LOGIN</h3>
                    <input class="text" type="text" name="adminacc" id="adminacc" align="center"><br><br>
                    <input class="text" type="password" name="adminpwd" id="adminpwd" align="center"><br><br>
                    <input class="bto" type="submit" name="Login" value="Login" align="center" onclick="sendmessage2()">
                </div>
            </div>
        </div>
    </form>
</body>

<script type="text/javascript">
    function change1(){
        var front=document.getElementById("f");
        var back=document.getElementById("b");
        front.style.transform="rotateY(-180deg)";
        back.style.transform="rotateY(0deg)";
    }
    function change2(){
        var front=document.getElementById("f");
        var back=document.getElementById("b");
        front.style.transform="rotateY(0deg)";
        back.style.transform="rotateY(180deg)";
    }
</script>
</html>

效果预览图

管理员界面

管理员所具有的权限有增、删、改、查(即对话功能),点击添加信息、修改信息、删除信息分别跳转至对应界面。输入问题,点击发送按钮进行对话,对话功能采用aiml与neo4j知识图谱实现,点击发送后前端将输入内容传入后端,后端路由进行处理。

@app.route('/index', methods=['POST', 'GET'])
def index():
    if request.method == 'POST':
        question = request.form['question']
        result = funsearch(question)
        return render_template('index.html', result=result)
    else:
        return render_template('index.html')

def funsearch(question):
    response = ''
    aq = AnalysisQuestion()
    ga = Get_answer()
    print(question)
    index, params = aq.analysis(question)
    x = str(params).replace(',', '').replace(' ', '').replace(
        '[', '').replace(']', '').replace("'", '')
    print(index, params)
    message = "ㅤ"+question+"ㅤ"
    if(index == 14):
        if('查询天气:' not in question and '计算:' not in question):
            response = alice.respond(message).replace(' ', '')
        elif('计算:' in question):
            count(question)
            response = alice.respond(message)
        elif('查询天气:' in question):
            weather(question)
            response = alice.respond(message).replace(' ', 'n'+"ㅤ")
    elif(index == 0):
        query = "match(n:Ncz) where n.symptom='{}' return  n.symptom;".format(x)
        non = ga.graph.run(query)
        print(non)
        non = str(non)
        print(non)
        if(x in non):
            answers = ga.get_data(index, params)
            for ans in answers:
                response = '该症状得脑卒中得概率为:'+str(ans[0])
        else:
            response = '暂无该症状'
    elif(index == 1):
        z = []
        query = "match(n:Ncz) where n.probability='{}' return  n.probability;".format(
            x)
        non = ga.graph.run(query)
        print(non)
        non = str(non)
        print(non)
        if(x in non):
            answers = ga.get_data(index, params)
            print(answers)
            for ans in answers:
                print(ans)
                z.append(str(ans[0]))
            response = '该概率对应的症状有:'+str(z).replace(',', '、').replace(
                ' ', '').replace('[', '').replace(']', '').replace("'", '')
        else:
            response = '暂无该概率'
    elif(index == 2):
        z = []
        answers = ga.get_data(index, params)
        print(answers)
        for ans in answers:
            print(ans)
            z.append(str(ans[0]))
        x = str(z).replace(',', '、').replace(' ', '').replace(
            '[', '').replace(']', '').replace("'", '')
        if(x != ''):
            response = '能引发脑卒中的症状有:'+x
        else:
            response = '暂无数据'
    elif(index == 3):
        answers = ga.get_data(index, params)
        print(answers)
        non = str(answers)
        params = str(params).replace(',', '').replace(
            ' ', '').replace('[', '').replace(']', '').replace("'", '')
        if(params in non):
            response = params+'会引发脑卒中'
        else:
            response = params+'不会引发脑卒中'
    res = response
    return res

因为设计的较为简单,这里就不详细说明了,主要就是使用装饰器对方法进行路由设置请求地址,在下方定义函数,一个路由对应一个函数。

评论

  1. 孔孜亦
    2 年前
    2022-11-28 13:28:34

    请问 天气的api借口要花钱吗?

    • Avatar photo
      博主
      孔孜亦
      2 年前
      2022-11-28 13:38:35

      不花钱,我记得应该有2000次的试用次数。或者你可以在网上找一个其他人的http://www.tianqiapi.com/的天气api接口

    • 孔孜亦
      葱葱蓉蓉
      2 年前
      2022-11-29 13:14:46

      谢谢 那个我还想问一下,aiml文件具体是怎么用的?

    • Avatar photo
      博主
      孔孜亦
      2 年前
      2022-11-29 13:26:54

      你首先需要安装aiml库,pip install aiml

      import aiml
      alice_path = ' '  # 这里填你的aiml文件存放位置
      os.chdir(alice_path)
      alice = aiml.Kernel()
      alice.learn("startup.xml") # 这个startup.xml文件是启动入口,根据自己需要自行编辑
      alice.respond('LOAD ALICE') 
      
      # 上面的代码就是调用aiml文件的步骤
      

      加载完成后应该如图:


      查看图片



      这样应该就可以正常使用了。
      aiml语法和startup.xml相关写法自行百度吧,网上很多例子。

    • Avatar photo
      博主
      孔孜亦
      2 年前
      2022-11-29 13:46:46

      这是一个仅仅使用aiml的小demo,按照readme补全就可以使用了。
      demo地址 https://github.com/Ilry/knowledge-graph-demo

    • 孔孜亦
      葱葱蓉蓉
      2 年前
      2022-11-29 14:14:46

      感谢感谢 我比较菜,我还想问一下,html和python是怎么连接到一起的呀?然后我需要做的就是把代码补全,把我的数据都弄到neo4j中,然后在mysql中建立一个储存用户登录名和密码的数据库,就可以了对吗?

    • Avatar photo
      博主
      孔孜亦
      2 年前
      2022-11-29 14:38:32

      这里用的是python的flask库,具体可以在网上详细了解。
      h5和python的连接,简略的解释一下:
      以index.html为例。

      <form action="/index" method="post" id="formid" > # 第56行

      这里的action="/index"就是与python文件的装饰路由对应。

      @app.route('/index', methods=['POST', 'GET']) # 第168行

      两个'/index'相互对应,表明在index.html页面的前端操作对应@app.route('/index', methods=['POST', 'GET'])这个装饰路由下的def index():后端函数。其他的也是同理。
      这是比较简略的解释,可能有些不清晰,还是需要了解flask。
      至于使用,将neo4j与mysql两个数据库建好,代码补全就可以正常使用。
      提醒一下,因为语言处理的关系,你可能需要根据你的neo4j数据库对py文件中50到112行的内容进行修改。否则不能正确对你的neo4j数据库进行增删改查。

    • 孔孜亦
      葱葱蓉蓉
      2 年前
      2022-11-29 16:06:36

      谢谢谢谢谢 太感谢了

    • 孔孜亦
      葱葱蓉蓉
      2 年前
      2022-11-29 20:28:14

      我看您aiml里的count和weather都是空的,需要我添加吗?我在运行的时候会报错,
      报错内容:FATAL PARSE ERROR in file count.aiml:
      count.aiml:1:0: no element found
      FATAL PARSE ERROR in file weather.aiml:
      weather.aiml:1:0: no element found
      还有一个问题就是我在mysql中只用建立两个表去储存用户和管理员的名字和密码就行了吗?

    • Avatar photo
      博主
      孔孜亦
      2 年前
      2022-11-29 20:53:20

      这个两个文件无需添加内容。你需要查看一下file1 = open("weather.aiml", "w", encoding='utf-8') file2 = open("count.aiml", "w", encoding='utf-8')中是否有encoding='utf-8参数,大概在290、299行,demo是在77、100行。这两个文件内容是自动填入的,但是无编码参数会导致乱码。
      比如你输入计算:1+1,会回答问题的同时,在count.aiml文件中填充内容。
      之后运行就不会报这两个错误了。
      至于MySQL我使用的id、用户名、密码,三项(管理员、用户各一个表),id作为主键,你也可以使用名字作为主键,虽然不太合理。你只要保证表中的字段名与python的sql语句对应即可。

    • 孔孜亦
      葱葱蓉蓉
      2 年前
      2022-11-30 13:29:16

      encoding=’utf-8这个参数代码中都有,但是运行还是会报错,是因为python代码中50-112行关于neo4j的代码我没有进行修改导致的吗?
      我还不太理解50-112行的代码它具体想表达的意思是什么?所以我在修改的时候有点无从下手。

    • Avatar photo
      博主
      孔孜亦
      2 年前
      2022-11-30 13:49:06

      你报的什么错误?
      如果是

      FATAL PARSE ERROR in file count.aiml:
      count.aiml:1:0: no element found
      FATAL PARSE ERROR in file weather.aiml:
      weather.aiml:1:0: no element found

      请忽略,只要运行一遍,输入`计算:3*3`、`天气查询:北京`一类的格式后,再次运行,就没有该错误了。
      至于50-112行的作用是处理语句。因为人机对话,代码是无法理解自然语言的。
      举个例子,“熬夜是否会引发脑卒中”这一问句,对应'会引发' in question and '哪些症状' not in question这个分支。他会查询熬夜是否会引起脑卒中。如果询问“熬夜得脑卒中的概率”,会对应'脑卒中的概率' in question and '和' not in question去查询概率。
      如果不做处理,是理解不了“熬夜是否会引发脑卒中”、“熬夜得脑卒中的概率”的区别的。
      这段代码写的比较简略,只包含几个常用的句式。
      当然,你也可以选择固定的句式,来选择对应的语句,对数据库进行操作。

    • 孔孜亦
      葱葱蓉蓉
      2 年前
      2022-11-30 14:10:18

      以下是我运行后的结果:
      Paddle enabled successfully……
      FATAL PARSE ERROR in file count.aiml:
      count.aiml:1:0: no element found
      FATAL PARSE ERROR in file weather.aiml:
      weather.aiml:1:0: no element found
      Loading startup.xml…done (0.00 seconds)
      Loading books.aiml…done (0.00 seconds)
      Loading count.aiml…Loading games.aiml…done (0.00 seconds)
      Loading myaiml.aiml…done (0.00 seconds)
      Loading time.aiml…done (0.00 seconds)
      Loading weather.aiml… * Serving Flask app ‘脑卒中’

      • Debug mode: on
        WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
      • Running on all addresses (0.0.0.0)
      • Running on http://127.0.0.1:5000
      • Running on http://192.168.0.107:5000
        Press CTRL+C to quit
      • Restarting with stat
        Paddle enabled successfully……

      FATAL PARSE ERROR in file count.aiml:
      count.aiml:1:0: no element found
      FATAL PARSE ERROR in file weather.aiml:
      weather.aiml:1:0: no element found
      Loading startup.xml…done (0.00 seconds)
      Loading books.aiml…done (0.00 seconds)
      Loading count.aiml…Loading games.aiml…done (0.00 seconds)
      Loading myaiml.aiml…done (0.00 seconds)
      Loading time.aiml…done (0.00 seconds)
      Loading weather.aiml… * Debugger is active!

      • Debugger PIN: 142-855-529

      这个网址打开显示为:TemplateNotFound
      jinja2.exceptions.TemplateNotFound: Login1.html
      然后我看到python报错的地方有一个WARNING,于是我在网上找到了解决方法,但是运行后连网址都没有了,下面是修改后的运行结果:
      Paddle enabled successfully……
      FATAL PARSE ERROR in file count.aiml:
      count.aiml:1:0: no element found
      FATAL PARSE ERROR in file weather.aiml:
      weather.aiml:1:0: no element found
      Loading startup.xml…done (0.00 seconds)
      Loading books.aiml…done (0.00 seconds)
      Loading count.aiml…Loading games.aiml…done (0.00 seconds)
      Loading myaiml.aiml…done (0.00 seconds)
      Loading time.aiml…done (0.00 seconds)
      Loading weather.aiml…

    • Avatar photo
      博主
      孔孜亦
      2 年前
      2022-11-30 14:43:55
      Paddle enabled successfully......
      Loading startup.xml...done (0.00 seconds)
      Loading books.aiml...done (0.00 seconds)
      Loading count.aiml...
      FATAL PARSE ERROR in file count.aiml:
      count.aiml:1:0: no element found
      Loading games.aiml...done (0.00 seconds)
      Loading myaiml.aiml...done (0.00 seconds)
      Loading time.aiml...done (0.00 seconds)
      Loading weather.aiml...
      FATAL PARSE ERROR in file weather.aiml:
      weather.aiml:1:0: no element found
       * Serving Flask app '人机对话'
       * Debug mode: on
      WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
       * Running on all addresses (0.0.0.0)
       * Running on http://127.0.0.1:5000
       * Running on http://172.20.10.4:5000
      Press CTRL+C to quit
       * Restarting with stat
      Paddle enabled successfully......
      Loading startup.xml...done (0.00 seconds)
      Loading books.aiml...done (0.00 seconds)
      Loading count.aiml...
      FATAL PARSE ERROR in file count.aiml:
      count.aiml:1:0: no element found
      Loading games.aiml...done (0.00 seconds)
      Loading myaiml.aiml...done (0.00 seconds)
      Loading time.aiml...done (0.00 seconds)
      Loading weather.aiml...
      FATAL PARSE ERROR in file weather.aiml:
      weather.aiml:1:0: no element found
       * Debugger is active!
       * Debugger PIN: 133-731-390

      这是运行后,我这边的控制台输出,其中这个WARNING无需更改。所以对应修改请撤销。
      关于TemplateNotFound错误是后端无法找到h5文件,你需要确认三件事:
      1、对应的h5文件存在,
      2、h5所在文件夹名称为templates,
      3、templates文件夹与py文件平级。
      这个问题与python文件无关。

    • Avatar photo
      博主
      孔孜亦
      2 年前
      2022-11-30 14:49:09

      如果以上三点确认无误,但是该错误依旧产生,请尝试:
      app = Flask(__name__) #第13行
      修改为
      app = Flask(__name__,template_folder='templates')
      应该可以解决该问题。

    • 孔孜亦
      葱葱蓉蓉
      2 年前
      2022-12-02 10:11:14

      您好 我现在运行出来了,但只有一个登陆的页面,背景图片也没有显示出来,这是为什么呢?

    • Avatar photo
      博主
      孔孜亦
      2 年前
      2022-12-02 12:24:33

      你需要首先查看一下资源文件是否位置正常。
      资源文件应当如图所示,在static文件夹下。


      查看图片



      如果这里无误,需要根据控制台返回的信息进行判断问题原因。

      127.0.0.1 - - [02/Dec/2022 12:20:40] "GET /static/background.png HTTP/1.1" 200 -
      127.0.0.1 - - [02/Dec/2022 12:20:40] "GET /static/front-image.png HTTP/1.1" 200 -
      127.0.0.1 - - [02/Dec/2022 12:20:41] "GET /static/back-image.png HTTP/1.1" 200 -

      背景图片的响应应该返回这样的。你需要根据具体的响应码来判断问题原因。
      还有也有可能是浏览器原因,可以使用无痕浏览尝试。(概率较低)

    • 孔孜亦
      葱葱蓉蓉
      2 年前
      2022-12-02 13:39:00

      问题已经得到解决了,可是用户登陆完就没有后续了,并且只有这一个网址 http://192.168.0.107:5000/,我记得原来可以运行出来两个网址的呀

    • Avatar photo
      博主
      孔孜亦
      2 年前
      2022-12-02 13:44:51

      另一个是127.0.0.1:5000,这是固定的。
      用户登陆完没有后续是什么意思呢?能详细描述一下吗?是页面不跳转吗?
      如果是这样,你可以看一下是用户名、密码是否输入正确,字段名是否对应。
      并且控制台输出,可以分析出原因的。

    • RANKEYI
      葱葱蓉蓉
      2 年前
      2022-12-03 16:38:56

      您好,我想问一下,为什么运行完之后,已经有了用户登录的界面,但是登完之后它不跳转,还是停在用户登录那个界面呢。

    • Avatar photo
      博主
      RANKEYI
      2 年前
      2022-12-03 19:52:55

      这个一般是你用户名和密码没对上。
      如果在没有修改python文件中的sql语句的情况下,你建立的MySQL数据表字段不能随意建立。
      你可以按下面图片建立数据库:


      查看图片





      查看图片



      或者根据你的数据库表字段修改python文件中的sql语句。

  2. 孔孜亦
    2 年前
    2022-12-13 10:01:54

    非常感谢您,现在已经可以根据我的知识图谱开始回答问题了,非常感谢您耐心的解答。

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇