SCF:搭建智能客服/問答機器人

在實際生產生活中,咱們常常會遇到別人問咱們問題,並且這個問題是常見的,那麼咱們就會感到很煩躁:爲啥總有人問類似的問題?再仔細冷靜一下:咱們可不能夠作一個機器人,他能夠自動回答一些問題?今天本文,就經過簡單的方法,在SCF上部署一個問答機器人/智能客服,來爲各位有需求的小夥伴,解決實際問題,固然,這篇文章也算是拋磚引玉。一方面,擴展一下你們使用SCF的思路,另外一方面溫故一下如何打包的方法,最後也嘗試使用新的觸發方法:雲API觸發。mysql

準備階段

首先,咱們要有一個數據庫,存儲咱們的問答系統,我這裏在騰訊雲購買一個雲數據庫(MySQL),並創建表和字段等信息:算法

而且插入幾個問題:sql

而後,經過本地編寫代碼,進行測試:數據庫

讀取數據庫:api

def getAllDataFromDB(connection):
    cursor = connection.cursor()
    cursor.execute("""SELECT * FROM robot""")
    results = cursor.fetchall()
    data = [eve['question'] for eve in results]
    return data
    
connection = pymysql.connect(host="",
                                 user="",
                                 password="",
                                 port=int(),
                                 db="MyScfTest",
                                 charset='utf8',
                                 cursorclass=pymysql.cursors.DictCursor)
questions = getAllDataFromDB(connection)
connection.close()複製代碼

使用gensim庫,利用TFIDF算法來進行文本類似度計算,jieba進行分詞,整理爲指定格式->gensim庫將要對比的文檔經過doc2bow轉化爲稀疏向量->再經過models中的tf-idf將語料庫進行處理->特徵值和稀疏矩陣類似度創建索引->最後的到類似結果。bash

代碼以下:app

def getAnswerList(sentence,questions,count=4):
    documents = []
    for eve_sentence in questions:
        tempData = " ".join(jieba.cut(eve_sentence))
        documents.append(tempData)
    texts=[[word for word in document.split()] for document in documents]
    frequency=defaultdict(int)
    for text in texts:
        for word in text:
            frequency[word]+=1
    dictionary=corpora.Dictionary(texts)
    new_xs=dictionary.doc2bow(jieba.cut(sentence))
    corpus=[dictionary.doc2bow(text)for text in texts]
    tfidf=models.TfidfModel(corpus)
    featurenum=len(dictionary.token2id.keys())
    sim=similarities.SparseMatrixSimilarity(tfidf[corpus],num_features=featurenum)[tfidf[new_xs]]
    tempList = [(sim[i], questions[i]) for i in range(1,len(questions))]

    tempList.sort(key=lambda x:x[0],reverse=True)
    if len(tempList) >= count:
        return tempList[0:count]
    else:
        return tempList複製代碼

這裏面的思路是,進行類似度獲取,而後根據類似度,進行排序,類似度最高的在前面,最低的放到最後。而後傳入的sentence是提出的問題,傳入的questions是問題列表,count是返回類似度最高的問題的個數。假如說,數據庫有20個問題,那麼我在進行了問題的類似度分析以後,會獲得一個類似度大小的列表,我對列表排序以後,選擇前count個問題返回給用戶。函數

完整代碼:工具

import jieba,pymysql
from gensim import corpora,models,similarities
from collections import defaultdict

def getAllDataFromDB(connection):
    cursor = connection.cursor()
    cursor.execute("""SELECT * FROM robot""")
    results = cursor.fetchall()
    data = [eve['question'] for eve in results]
    return data

def getDataFromDB(connection,question):
    cursor = connection.cursor()
    cursor.execute("""SELECT * FROM robot WHERE question = '%s'"""%question)
    results = cursor.fetchall()
    data = [(eve['question'],eve['answer']) for eve in results]
    return data

def getAnswerList(sentence,questions,count=4):
    documents = []
    for eve_sentence in questions:
        tempData = " ".join(jieba.cut(eve_sentence))
        documents.append(tempData)
    texts=[[word for word in document.split()] for document in documents]
    frequency=defaultdict(int)
    for text in texts:
        for word in text:
            frequency[word]+=1
    dictionary=corpora.Dictionary(texts)
    new_xs=dictionary.doc2bow(jieba.cut(sentence))
    corpus=[dictionary.doc2bow(text)for text in texts]
    tfidf=models.TfidfModel(corpus)
    featurenum=len(dictionary.token2id.keys())
    sim=similarities.SparseMatrixSimilarity(tfidf[corpus],num_features=featurenum)[tfidf[new_xs]]
    tempList = [(sim[i], questions[i]) for i in range(1,len(questions))]

    tempList.sort(key=lambda x:x[0],reverse=True)
    if len(tempList) >= count:
        return tempList[0:count]
    else:
        return tempList


def putQuestion(question):
    connection = pymysql.connect(host="",
                                     user="",
                                     password="",
                                     port=int(),
                                     db="MyScfTest",
                                     charset='utf8',
                                     cursorclass=pymysql.cursors.DictCursor)
    questions = getAllDataFromDB(connection)
    answers = [getDataFromDB(connection,eve[1]) for eve in getAnswerList(question,questions,count=2)]
    connection.close()
    return answers

sentence = "怎麼觸發SCF?"
print(putQuestion(sentence))複製代碼

測試結果:測試

能夠看到,在問題列表:

咱們一共有5個問題,這5個問題,和"怎麼觸發SCF?"類似度最高的問題前兩個是:那些事件能夠觸發SCF函數以及SCF支持那些語言。能夠看出,獲得的結果是相似的。

這個項目在實際生產中,能夠是這樣:

你問客服機器人一個問題,機器人給你一個回答,而後下面會說:更多類似問題:巴拉巴拉一堆。

上SCF階段

函數進行打包,這裏要記住,必定要在SCF同樣的環境下打包才能夠:

CentOS + Python3.6

具體打包方法,能夠參考文章:cloud.tencent.com/developer/a…

打包以後,數據上傳:

這裏要說明的是,因爲函數上傳有大小限制,本函數上傳了COS,經過COS加載到SCF中,並設置了超時時間爲300s:

簡單測試,運行結果以下:

def main_handler(event, context):
    sentence = "怎麼觸發SCF?"
    return putQuestion(sentence)複製代碼

對main_handler進行修改:

首先定義測試模板:

而後修改:

def main_handler(event, context):
    sentence = context["question"]
    return putQuestion(sentence)複製代碼

完整代碼(已經刪除了我數據庫等敏感信息):

import jieba,pymysql
from gensim import corpora,models,similarities
from collections import defaultdict

def getAllDataFromDB(connection):
    cursor = connection.cursor()
    cursor.execute("""SELECT * FROM robot""")
    results = cursor.fetchall()
    data = [eve['question'] for eve in results]
    return data

def getDataFromDB(connection,question):
    cursor = connection.cursor()
    cursor.execute("""SELECT * FROM robot WHERE question = '%s'"""%question)
    results = cursor.fetchall()
    data = [(eve['question'],eve['answer']) for eve in results]
    return data

def getAnswerList(sentence,questions,count=4):
    documents = []
    for eve_sentence in questions:
        tempData = " ".join(jieba.cut(eve_sentence))
        documents.append(tempData)
    texts=[[word for word in document.split()] for document in documents]
    frequency=defaultdict(int)
    for text in texts:
        for word in text:
            frequency[word]+=1
    dictionary=corpora.Dictionary(texts)
    new_xs=dictionary.doc2bow(jieba.cut(sentence))
    corpus=[dictionary.doc2bow(text)for text in texts]
    tfidf=models.TfidfModel(corpus)
    featurenum=len(dictionary.token2id.keys())
    sim=similarities.SparseMatrixSimilarity(tfidf[corpus],num_features=featurenum)[tfidf[new_xs]]
    tempList = [(sim[i], questions[i]) for i in range(1,len(questions))]

    tempList.sort(key=lambda x:x[0],reverse=True)
    if len(tempList) >= count:
        return tempList[0:count]
    else:
        return tempList


def putQuestion(question):
    connection = pymysql.connect(host="",
                                     user="",
                                     password="",
                                     port=int(),
                                     db="MyScfTest",
                                     charset='utf8',
                                     cursorclass=pymysql.cursors.DictCursor)
    questions = getAllDataFromDB(connection)
    answers = [getDataFromDB(connection,eve[1]) for eve in getAnswerList(question,questions,count=2)]
    connection.close()
    return answers


def main_handler(event, context):
    sentence = context["question"]
    return putQuestion(sentence)複製代碼

目前,咱們的雲函數已經部署完成。

雲API觸發器

有些人對寫雲API的代碼有點一臉懵逼,可是別擔憂:

console.cloud.tencent.com/api/explore…

雲API的Explorer是一個能夠自動幫咱們寫代碼的工具,你們能夠經過這個工具,進行簡答的在線調試:

你們能夠看到,選擇好了對應的功能,咱們填寫好對應的參數,經過點擊在線調用->發送請求,得到到告終果。

此時咱們能夠點擊代碼生成:

咱們能夠看到系統爲咱們自動生成了Java、Python等6種語言的代碼,這些代碼是能夠放到項目中直接運行。也就是說,你能夠在本身的Node.js,.NET,Java等項目中,調用這個雲函數,而且得到結果。

總結

本文是經過一個簡單的算法,實現了簡單的問答機器人工具。主要涉及到了:

1: 打包函數,能夠參考文章中的地址

2:上傳代碼,能夠經過cos上傳

3:鏈接數據庫的Demo

4:使用雲API觸發

固然,SCF的應用場景還有不少,我也會在之後的文章中,更多的和你們分享它的使用場景。

相關文章
相關標籤/搜索