吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6327|回复: 57
收起左侧

[Python 原创] 从零开始构建简易AI问答系统

  [复制链接]
恋丶你的语 发表于 2023-3-19 16:34
本帖最后由 恋丶你的语 于 2023-3-24 23:14 编辑

一、非正文部分
    现在ChatGPT特别火爆,他可以帮助我们的工作带来许多的便捷。在此之前我很早就想拥有自己的AI,哪怕是最简单的那种,奈何,大学我选了财务管理专业(高风险低收益{:1_908:} ),在梦想的道路上越跑越远。{:1_889:} 。在大二偶然之间了解到了财务数据分析这块的知识,然后我开始的我得Python半吊子学习,啥都学学,如今我已大四,还有几个月就要毕业,对未来挺焦虑的,于是我静下心来,用自己这段时间所学的知识来尝试完成自己的小愿望,于是就有了这篇文章。大佬勿喷,业余学习
二、基本思路
    我的想法是一个可以能够自我学习会计知识并可以问答的程序,但是我没有那么多时间去整理这些相关的资料,于是让他直接获取百度百科的数据。基本思路如下:
      1、爬取百度百科相关词条的网页内容,可以使用Python中的爬虫框架,例如Scrapy或BeautifulSoup等。
      2、对网页内容进行自然语言处理和数据清洗,将有用的信息提取出来,并存储在数据库或本地文件中。
      3、使用机器学习算法,如神经网络、随机森林等对得到的数据进行训练。
      4、开发一个问答系统,将用户问题输入进去,然后将输入的问题与训练好的模型匹配,以便回答用户问题。
    当然,这个项目具体实现上还有很多需要考虑的细节,比如如何避免数据爬取被反爬虫,如何处理查询不到的问题等等,不过这个只是一个简易的AI就不考虑那么多,而且我知识量也不够。
三、代码部分
  3.1然后根据思路写出基本的代码,然后在根据思路进行调整:
[Python] 纯文本查看 复制代码
# 导入需要用到的库
import requests
from bs4 import BeautifulSoup
import jieba
from gensim.models.word2vec import Word2Vec
import numpy as np
import pandas as pd
from sklearn.svm import SVC
from sklearn.metrics.pairwise import cosine_similarity

# 爬虫部分:爬取百度百科的网页内容,并进行数据清洗和预处理
def get_wiki_content(keyword):
    url = 'https://baike.baidu.com/item/' + keyword
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    content = soup.find_all(class_="para")
    content_list = []
    for para in content:
        para = para.get_text().strip()
        if para:
            content_list.append(para)
    full_content = ''.join(content_list)
    return full_content

# 分词和向量化部分:使用jieba对爬取的数据进行分词,然后使用Word2Vec模型将分词结果转化为词向量
class Word2VecVectorizer:
    def __init__(self):
        self.word2vec = None

    def fit(self, sentences):
        w2v = Word2Vec(sentences=sentences, size=256, min_count=5, workers=4)
        self.word2vec = dict(zip(w2v.wv.index2word, w2v.wv.vectors))

    def transform(self, sentences):
        vectors = []
        for sentence in sentences:
            sentence_vec = []
            for word in sentence:
                if word in self.word2vec:
                    sentence_vec.append(self.word2vec[word])
            if len(sentence_vec) > 0:
                sentence_vec = np.mean(sentence_vec, axis=0)
            else:
                sentence_vec = np.zeros(256)
            vectors.append(sentence_vec)
        return np.array(vectors)

# 机器学习部分:使用SVM算法对文本向量训练模型,并使用余弦相似度计算输入问题与已知问题的相似度
class QuestionAnswerSystem:
    def __init__(self):
        self.vectorizer = None
        self.clf = None
        self.question_vectors = None
        self.answer_vectors = None
        self.df = None

    def fit(self, questions, answers):
        self.vectorizer = Word2VecVectorizer()
        self.vectorizer.fit(questions)
        self.question_vectors = self.vectorizer.transform(questions)
        self.answer_vectors = self.vectorizer.transform(answers)
        self.clf = SVC(kernel='linear', probability=True)
        self.clf.fit(self.question_vectors, range(len(questions)))

    def ask(self, question, n=5):
        question = list(jieba.cut(question))
        question_vec = self.vectorizer.transform([question])[0]
        probas = self.clf.predict_proba([question_vec])[0]
        top_n = np.argsort(probas)[-n:]
        sims = cosine_similarity([question_vec], self.question_vectors[top_n])[0]
        best_match = np.argmax(sims)
        return self.df.iloc[top_n[best_match]]['answer']

# 主程序部分:调用以上函数完成问答系统的搭建
if __name__ == '__main__':
    # 爬取需要用到的数据
    wiki_content = get_wiki_content('会计')
    # 对数据进行预处理
    questions = ['什么是会计', '什么是账户', '什么是分录', '什么是财务报表']
    answers = ['会计是什么', '账户是什么', '分录是什么', '财务报表是什么']
    # 训练问答系统
    qas = QuestionAnswerSystem()
    qas.fit(questions, answers)
    qas.df = pd.DataFrame({'question': questions, 'answer': answers})
    # 进行测试
    while True:
        question = input('请输入你的问题:')
        if question == 'bye':
            break
        answer = qas.ask(question)
        print('答案为:', answer)

3.2 加入神经网络模型
   我们可以发现他只能回答一些基础的问题。然后我们在此基础上加入神经网络模型进一步完善它。于是我使用预训练的语言模型(如BERT)来对问题和答案进行编码,然后将编码后的结果输入到一个神经网络中进行分类。代码如下,其中使用Hugging Face库来加载BERT模型。
[Python] 纯文本查看 复制代码
#  导入需要用到的库
import requests
from bs4 import BeautifulSoup
import jieba
import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
import torch
from transformers import BertTokenizer, BertModel
from torch.utils.data import TensorDataset, DataLoader
import torch.nn.functional as F

# 爬虫部分:爬取百度百科的网页内容,并进行数据清洗和预处理
def get_wiki_content(keyword):
    url = 'https://baike.baidu.com/item/' + keyword
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    content = soup.find_all(class_="para")
    content_list = []
    for para in content:
        para = para.get_text().strip()
        if para:
            content_list.append(para)
    full_content = ''.join(content_list)
    return full_content

# 编码器部分:使用预训练的BERT模型来对文本进行编码
class BertEncoder:
    def __init__(self):
        self.tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
        self.model = BertModel.from_pretrained('bert-base-chinese')
        self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    def encode(self, sentence):
        input_ids = torch.tensor([self.tokenizer.encode(sentence, add_special_tokens=True)], dtype=torch.long).to(self.device)
        with torch.no_grad():
            outputs = self.model(input_ids)
            encoded = outputs[0][:, 0, :].cpu().numpy()
        return encoded

# 神经网络部分:使用全连接层对文本向量训练模型,并使用余弦相似度计算输入问题与已知问题的相似度
class QuestionAnswerSystem:
    def __init__(self):
        self.encoder = None
        self.clf = None
        self.question_vectors = None
        self.answer_vectors = None
        self.df = None

    def fit(self, questions, answers):
        self.encoder = BertEncoder()
        self.question_vectors = self.encoder.encode(questions)
        self.answer_vectors = self.encoder.encode(answers)
        self.clf = torch.nn.Sequential(torch.nn.Linear(768, 256),
                                        torch.nn.ReLU(),
                                        torch.nn.Linear(256, len(questions)),
                                        torch.nn.Softmax())
        self.clf.to(self.encoder.device)
        train_data = TensorDataset(torch.tensor(self.answer_vectors, dtype=torch.float32), torch.tensor(range(len(questions)), dtype=torch.long))
        train_loader = DataLoader(train_data, batch_size=32)
        criterion = torch.nn.CrossEntropyLoss()
        optimizer = torch.optim.Adam(self.clf.parameters(), lr=1e-3)
        num_epochs = 5
        for epoch in range(num_epochs):
            for inputs, labels in train_loader:
                inputs, labels = inputs.to(self.encoder.device), labels.to(self.encoder.device)
                outputs = self.clf(inputs)
                loss = criterion(outputs, labels)
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()

    def ask(self, question, n=5):
        question_vec = self.encoder.encode(question)
        inputs = torch.tensor(question_vec, dtype=torch.float32).to(self.encoder.device)
        outputs = self.clf(inputs)
        probas = F.softmax(outputs, dim=1).detach().cpu().numpy()[0]
        top_n = np.argsort(probas)[-n:]
        sims = cosine_similarity([question_vec], self.question_vectors[top_n])[0]
        best_match = np.argmax(sims)
        return self.df.iloc[top_n[best_match]]['answer']

# 主程序部分:调用以上函数完成问答系统的搭建
if __name__ == '__main__':
    # 爬取需要用到的数据
    wiki_content = get_wiki_content('会计')
    # 对数据进行预处理
    questions = ['什么是会计', '什么是账户', '什么是分录', '什么是财务报表']
    answers = ['会计是什么', '账户是什么', '分录是什么', '财务报表是什么']
    # 训练问答系统
    qas = QuestionAnswerSystem()
    qas.fit(questions, answers)
    qas.df = pd.DataFrame({'question': questions, 'answer': answers})
    # 进行测试
    while True:
        question = input('请输入你的问题:')
        if question == 'bye':
            break
        answer = qas.ask(question)
        print('答案为:', answer)

    我们利用BERT模型来对问题和答案进行编码,然后使用全连接层对编码后的文本向量进行分类。这样的神经网络效果较好,可以更准确地回答问题。但是,由于BERT模型比较复杂,因此训练和推断速度都比较慢,需要耐心等待。
3.3 添加将训练结果保存到excel文件中的功能
   为了实现将训练结果保存到Excel文件中的功能,我们可以使用pandas库。在下面的代码中,我们对问答系统类(QuestionAnswerSystem)进行一些改进,添加了一个新的方法 save_result_to_excel。这个方法接受一个Excel文件名作为参数,并将问题和答案保存到该文件中。在方法中,我们将DataFrame类型的数据转换为Excel文件,并将其保存在指定的文件名中。下面是修改后的代码:
[Python] 纯文本查看 复制代码
# 导入需要用到的库
import requests
from bs4 import BeautifulSoup
import jieba
import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
import torch
from transformers import BertTokenizer, BertModel
from torch.utils.data import TensorDataset, DataLoader
import torch.nn.functional as F

# 爬虫部分:爬取百度百科的网页内容,并进行数据清洗和预处理
def get_wiki_content(keyword):
    url = 'https://baike.baidu.com/item/' + keyword
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    content = soup.find_all(class_="para")
    content_list = []
    for para in content:
        para = para.get_text().strip()
        if para:
            content_list.append(para)
    full_content = ''.join(content_list)
    return full_content

# 编码器部分:使用预训练的BERT模型来对文本进行编码
class BertEncoder:
    def __init__(self):
        self.tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
        self.model = BertModel.from_pretrained('bert-base-chinese')
        self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    def encode(self, sentence):
        input_ids = torch.tensor([self.tokenizer.encode(sentence, add_special_tokens=True)], dtype=torch.long).to(self.device)
        with torch.no_grad():
            outputs = self.model(input_ids)
            encoded = outputs[0][:, 0, :].cpu().numpy()
        return encoded

# 神经网络部分:使用全连接层对文本向量训练模型,并使用余弦相似度计算输入问题与已知问题的相似度
class QuestionAnswerSystem:
    def __init__(self):
        self.encoder = None
        self.clf = None
        self.question_vectors = None
        self.answer_vectors = None
        self.df = None

    def fit(self, questions, answers):
        self.encoder = BertEncoder()
        self.question_vectors = self.encoder.encode(questions)
        self.answer_vectors = self.encoder.encode(answers)
        self.clf = torch.nn.Sequential(torch.nn.Linear(768, 256),
                                        torch.nn.ReLU(),
                                        torch.nn.Linear(256, len(questions)),
                                        torch.nn.Softmax())
        self.clf.to(self.encoder.device)
        train_data = TensorDataset(torch.tensor(self.answer_vectors, dtype=torch.float32), torch.tensor(range(len(questions)), dtype=torch.long))
        train_loader = DataLoader(train_data, batch_size=32)
        criterion = torch.nn.CrossEntropyLoss()
        optimizer = torch.optim.Adam(self.clf.parameters(), lr=1e-3)
        num_epochs = 5
        for epoch in range(num_epochs):
            for inputs, labels in train_loader:
                inputs, labels = inputs.to(self.encoder.device), labels.to(self.encoder.device)
                outputs = self.clf(inputs)
                loss = criterion(outputs, labels)
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()

    def ask(self, question, n=5):
        question_vec = self.encoder.encode(question)
        inputs = torch.tensor(question_vec, dtype=torch.float32).to(self.encoder.device)
        outputs = self.clf(inputs)
        probas = F.softmax(outputs, dim=1).detach().cpu().numpy()[0]
        top_n = np.argsort(probas)[-n:]
        sims = cosine_similarity([question_vec], self.question_vectors[top_n])[0]
        best_match = np.argmax(sims)
        return self.df.iloc[top_n[best_match]]['answer']

    # 新增方法:将问答结果保存到Excel文件中
    def save_result_to_excel(self, filename='qa_result.xlsx'):
        df_result = self.df.copy()
        df_result.columns = ['Question', 'Answer']
        df_result.to_excel(filename, index=False)

# 主程序部分:调用以上函数完成问答系统的搭建
if __name__ == '__main__':
    # 爬取需要用到的数据
    wiki_content = get_wiki_content('会计')
    # 对数据进行预处理
    questions = ['什么是会计', '什么是账户', '什么是分录', '什么是财务报表']
    answers = ['会计是什么', '账户是什么', '分录是什么', '财务报表是什么']
    # 训练问答系统
    qas = QuestionAnswerSystem()
    qas.fit(questions, answers)
    qas.df = pd.DataFrame({'question': questions, 'answer': answers})
    # 将结果保存到Excel文件中
    qas.save_result_to_excel('qa_result.xlsx')
    # 进行测试
    while True:
        question = input('请输入你的问题:')
        if question == 'bye':
            break
        answer = qas.ask(question)
        print('答案为:', answer)

在主程序部分中,新增了一行代码 qas.save_result_to_excel('qa_result.xlsx'),将问答结果保存到Excel文件中。可以将文件名设置为自己喜欢的名称,并在文件保存位置执行该代码。执行完毕后,在指定的文件夹中会生成一个名为 qa_result.xlsx 的文件,其中包含了训练结果的问题和答案。
3.4 想要更好的学习,我们需要对该程序在对话过程中就对数据进行数据标注和检验
   实现问答系统的数据标注和检验功能,我们需要对 QuestionAnswerSystem 进行一些改进。
   首先,为了方便用户对答案进行标注,我们需要在 ask 方法中添加一个新参数 is_correct,用于接收用户对答案是否正确的标注。我们还需要将问题、答案和标注组成的列表存储到 df 属性中,以便后续使用。
   其次,我们可以新增一个方法 check_accuracy,用于计算问答系统的准确率。该方法会基于已标注数据计算平均准确率,并将准确率打印出来。同时,我们也可以通过 save_result_to_excel 方法保存标注后的结果到Excel文件中。下面是修改后的代码:
[Python] 纯文本查看 复制代码
# 导入需要用到的库
import requests  # 发送网络请求的模块
from bs4 import BeautifulSoup  # 从bs4模块中导入BeautifulSoup类,用于解析HTML文档
import jieba  # 中文分词库
import numpy as np  # 用于科学计算的库
import pandas as pd  # 用于数据处理和分析的库
from sklearn.metrics.pairwise import cosine_similarity  # 余弦相似度计算函数
import torch  # PyTorch深度学习框架
from transformers import BertTokenizer, BertModel  # 预训练的BERT模型和分词器
from torch.utils.data import TensorDataset, DataLoader  # 数据集和数据加载器
import torch.nn.functional as F  # 神经网络相关的函数和工具

# 爬虫部分:爬取百度百科的网页内容,并进行数据清洗和预处理
def get_wiki_content(keyword):
    url = 'https://baike.baidu.com/item/' + keyword  # 构造百度百科的URL链接
    response = requests.get(url)  # 发送GET请求并获取响应对象
    soup = BeautifulSoup(response.text, 'html.parser')  # 用html.parser解析HTML文档
    content = soup.find_all(class_="para")  # 查找class属性为"para"的标签
    content_list = []
    for para in content:
        para = para.get_text().strip()  # 获取标签中的文本内容
        if para: # 如果文本内容非空
            content_list.append(para)  # 将其添加到列表中
    full_content = ''.join(content_list)  # 将列表中的所有段落合并成一个完整的字符串
    return full_content  # 返回完整的百科内容

# 编码器部分:使用预训练的BERT模型来对文本进行编码
class BertEncoder:
    def __init__(self):
        self.tokenizer = BertTokenizer.from_pretrained('bert-base-chinese') # 调用BERT分词器
        self.model = BertModel.from_pretrained('bert-base-chinese')  # 调用BERT模型
        self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')  # 判断是否可用GPU

    def encode(self, sentence):  # 对句子进行编码
        input_ids = torch.tensor([self.tokenizer.encode(sentence, add_special_tokens=True)], dtype=torch.long).to(self.device)  # 将句子转换成ID序列,并放到GPU上
        with torch.no_grad(): # 关闭梯度计算,以节省内存和加速计算
            outputs = self.model(input_ids)  # 输入句子,得到BERT模型输出
            encoded = outputs[0][:, 0, :].cpu().numpy()  # 取第1个输出,取第1行,即CLS对应的向量,将其从GPU上取回并转换为NumPy数组
        return encoded

# 神经网络部分:使用全连接层对文本向量训练模型,并使用余弦相似度计算输入问题与已知问题的相似度
class QuestionAnswerSystem:
    def __init__(self):
        self.encoder = None
        self.clf = None
        self.question_vectors = None
        self.answer_vectors = None
        self.df = None  # 保存问答结果的DataFrame

    def fit(self, questions, answers): # 训练神经网络模型
        self.encoder = BertEncoder()  # 初始化编码器
        self.question_vectors = self.encoder.encode(questions)  # 编码所有问题
        self.answer_vectors = self.encoder.encode(answers)  # 编码所有答案
        self.clf = torch.nn.Sequential(torch.nn.Linear(768, 256), # 全连接层1,输入大小为768,输出大小为256
                                        torch.nn.ReLU(),  # ReLU激活函数
                                        torch.nn.Linear(256, len(questions)),  # 全连接层2,输入大小为256,输出大小为问题数量
                                        torch.nn.Softmax()) # Softmax函数,用于分类
        self.clf.to(self.encoder.device)  # 将模型放到GPU上
        train_data = TensorDataset(torch.tensor(self.answer_vectors, dtype=torch.float32), torch.tensor(range(len(questions)), dtype=torch.long))  # 构造训练数据集
        train_loader = DataLoader(train_data, batch_size=32)  # 构造数据加载器,每次读取32个样本
        criterion = torch.nn.CrossEntropyLoss() # 定义损失函数为交叉熵
        optimizer = torch.optim.Adam(self.clf.parameters(), lr=1e-3)  # 使用Adam优化器,并设置学习率为0.001
        num_epochs = 5  # 训练轮数为5轮
        for epoch in range(num_epochs):  # 进行多轮训练
            for inputs, labels in train_loader: # 按批次读取数据
                inputs, labels = inputs.to(self.encoder.device), labels.to(self.encoder.device)  # 将数据放到GPU上
                outputs = self.clf(inputs) # 输入数据,得到模型输出结果
                loss = criterion(outputs, labels) # 计算损失值
                optimizer.zero_grad() # 将梯度清零,以免累加影响下一次更新
                loss.backward()  # 反向传播计算梯度
                optimizer.step() # 更新权重

    def ask(self, question, n=5, is_correct=None): # 回答问题
        question_vec = self.encoder.encode(question)  # 对输入问题进行编码
        inputs = torch.tensor(question_vec, dtype=torch.float32).to(self.encoder.device)  # 将编码后的问题放到GPU上
        outputs = self.clf(inputs)  # 输入问题向量,得到模型输出结果
        probas = F.softmax(outputs, dim=1).detach().cpu().numpy()[0]  # 对输出结果进行softmax处理,并将其从GPU上取回并转换为NumPy数组
        top_n = np.argsort(probas)[-n:]  # 取最大的n个概率对应的下标
        sims = cosine_similarity([question_vec], self.question_vectors[top_n])[0]  # 计算输入问题与已知问题的相似度
        best_match = np.argmax(sims)  # 找到最相似的问题
        if is_correct is not None:   # 如果需要记录问答结果
            self.df = self.df.append({'question': question, 'answer': self.df.iloc[top_n[best_match]]['answer'], 'is_correct': bool(is_correct)}, ignore_index=True)  # 将记录添加到DataFrame中
        return self.df.iloc[top_n[best_match]]['answer']  # 返回最匹配的答案

    # 新增方法:将问答结果保存到Excel文件中
    def save_result_to_excel(self, filename='qa_result.xlsx'):
        df_result = self.df.copy() # 复制一份问答结果
        df_result.columns = ['Question', 'Answer', 'Is Correct']  # 重命名列名
        df_result.to_excel(filename, index=False)  # 将结果保存到Excel文件中,不保存索引

    # 新增方法:检验问答系统的准确率
    def check_accuracy(self):
        accuracy = self.df['is_correct'].mean() # 计算平均准确率
        print('问答系统的准确率为: {:.2f}%'.format(accuracy*100))  # 输出准确率

# 主程序部分:调用以上函数完成问答系统的搭建
if __name__ == '__main__':
    # 爬取需要用到的数据
    wiki_content = get_wiki_content('会计')
    # 对数据进行预处理
    questions = ['什么是会计', '什么是账户', '什么是分录', '什么是财务报表']
    answers = ['会计是什么', '账户是什么', '分录是什么', '财务报表是什么']
    # 训练问答系统
    qas = QuestionAnswerSystem()
    qas.fit(questions, answers)
    qas.df = pd.DataFrame({'question': questions, 'answer': answers})
    # 进行测试
    while True:
        question = input('请输入你的问题:')
        if question == 'bye':
            break
        is_correct = input('答案是否正确?(y/n)')
        if is_correct.lower() == 'y':
            is_correct = True
        elif is_correct.lower() == 'n':
            is_correct = False
        else:
            is_correct = None
        answer = qas.ask(question, is_correct=is_correct)
        print('答案为:', answer['answer'])
    # 检验准确率并保存标注后的数据到Excel文件中
    qas.check_accuracy()
    qas.save_result_to_excel('qa_result.xlsx')

    在主程序部分中,我们新增了两个输入提示,以便用户标注答案是否正确,同时也新增了两行代码来调用 check_accuracy save_result_to_excel 方法,以检验问答系统的准确率,并将标注后的结果保存到Excel文件中。现在,当运行程序并回答每个问题时,程序会提示你输入答案是否正确,你可以输入 "y" 或 "n" 来对答案进行标注。程序会将问题、答案和标注组成的记录存储到 df 属性中,并在每次执行 ask 方法时更新 df。执行 check_accuracy 方法时,程序将基于已标注数据计算准确率,并将其打印出来。执行 save_result_to_excel 方法时,程序将标注后的数据写入到Excel文件中以便后续使用。到此为止,我们的程序的一些功能也就基本实现了。当然还存在许多的问题,希望大家可以一起学习,一起进步。
四、最后的最后
   为了更好的让他学习方便,于是最后增加一个适配的Webj界面。要将该程序适配为web界面,需要使用web框架来搭建一个网站,并将问答系统集成到网站中。可以使用Python中的Flask框架。以下是实现步骤:
1、导入Flask和其他需要用到的库:
[Python] 纯文本查看 复制代码
from flask import Flask, render_template, request
import pandas as pd
from qa_system import QuestionAnswerSystem

其中qa_system.py文件是之前所提到的问答系统代码。
2、创建Flask应用:
[Python] 纯文本查看 复制代码
app = Flask(__name__)

3、加载问答系统:
[Python] 纯文本查看 复制代码
qas = QuestionAnswerSystem()
qas.fit(questions, answers)
qas.df = pd.DataFrame({'question': questions, 'answer': answers})

其中,questionsanswers是之前已经定义过的问题列表和答案列表。
4、创建路由函数:
[Python] 纯文本查看 复制代码
@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        question = request.form.get('question')
        is_correct = request.form.get('is_correct')
        if is_correct.lower() == 'y':
            is_correct = True
        elif is_correct.lower() == 'n':
            is_correct = False
        else:
            is_correct = None
        answer = qas.ask(question, is_correct=is_correct)
        return render_template('index.html', answer=answer['answer'])
    return render_template('index.html')

这个路由函数包含了两个请求方法:GETPOST。当用户访问网页时,会发送一个GET请求,会渲染index.html页面;当用户提交问题时,会发送一个POST请求,会通过问答系统获取答案,并将答案渲染到页面中。questionis_correct是从表单中获取的参数。
5、编写HTML模板:
  这里写了一个简单的模板作为参考,可以根据需求进行修改。
[HTML] 纯文本查看 复制代码
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>问答系统</title>
</head>
<body>
    <form method="post">
        <input type="text" name="question" placeholder="请输入你的问题" required>
        <input type="radio" name="is_correct" value="y" required>
        <label for="y">正确</label>
        <input type="radio" name="is_correct" value="n" required>
        <label for="n">错误</label>
        <button type="submit">提交</button>
    </form>
    {% if answer %}
    <p>{{ answer }}</p >
    {% endif %}
</body>
</html>

这个模板包含了一个表单,用户可以在这里输入问题。表单中还包含了两个单选框,用户在回答问题后可以选择是否正确。如果问答系统能够成功获取到答案,就会将答案渲染到页面中。
6、运行Flask应用:
[Python] 纯文本查看 复制代码
if __name__ == '__main__':
    app.run()

7、运行这个应用之后,通过浏览器访问网址http://127.0.0.1:5000/,即可看到刚才编写的页面。最终大功告成,最后希望大佬勿喷。


2023/3/24 23:10 重新编辑了下,新增内容就是每行都添加了注释,可以行大家更好的学习、理解和修改我创造的BUG(坏笑ing)

免费评分

参与人数 24威望 +1 吾爱币 +38 热心值 +23 收起 理由
nyazhou + 1 用心讨论,共获提升!
XiaoBai.Q.Q + 1 热心回复!
realdawei + 1 用心讨论,共获提升!
菜心 + 1 + 1 热心回复!
kkkukujiajia + 1 我很赞同!
jayx2023 + 1 + 1 热心回复!
韩天阳 + 1 + 1 我很赞同!
xibeimu + 1 + 1 楼主放出的代码用的python 版本几?是否已经运行跑通?谢谢
jcwoai + 1 我很赞同!
hiel + 1 + 1 用心讨论,共获提升!
sky673075465 + 1 + 1 用心讨论,共获提升!
shodow123 + 1 + 1 我很赞同!
√小飞 + 1 + 1 谢谢@Thanks!
ppkhw + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
echoaku + 1 + 1 我很赞同!
WZYang + 1 + 1 我很赞同!
二十瞬 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lishengde322 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
gzsklsskszngc + 2 + 1 我很赞同!
zt185 + 1 + 1 我很赞同!
jiajielj + 1 我很赞同!
isaly7 + 1 用心讨论,共获提升!
yanecc + 1 + 1 热心回复!
侃遍天下无二人 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

wzbAwxl 发表于 2023-3-19 18:57
真厉害啊 学到了
blueoceanwhale 发表于 2023-3-29 19:38
hijackking 发表于 2023-3-21 20:57
大神问下;
Traceback (most recent call last):
  File "D:\studyddd\dddd.py", line 106, in

这段代码报错的原因是在 Torch 的 TensorDataset 构造函数中,两个 tensor 的第一维大小不一致导致的。具体来说,代码的第 60 行中,使用了一个名为 answer_vectors 的成员变量构造了一个 torch.Tensor 对象,然后将这个对象和一个 long 类型的 torch.Tensor 对象构造成了一个 TensorDataset 对象。其中,第一个 tensor 的第一维大小为 self.answer_vectors 的行数,第二个 tensor 的第一维大小为 questions 的长度。由于这两个 tensor 的第一维大小不相等,所以就会报出 "Size mismatch between tensors" 的错误。

为了解决这个问题,你需要检查 self.answer_vectors 和 questions 的行数是否相等。如果不相等,你需要将它们转化为相同的大小。你可以使用 numpy 的 resize 函数来改变 self.answer_vectors 的大小,或者使用 pandas 的 DataFrame 类型将 questions 和 answers 整合在一起,然后再将它们转化为 tensor 类型。
满不懂 发表于 2023-3-19 19:23
dork 发表于 2023-3-19 20:48
收藏学习!
头像被屏蔽
juy 发表于 2023-3-19 21:05
提示: 作者被禁止或删除 内容自动屏蔽
a2523188267 发表于 2023-3-19 21:18
感谢,能打包一系列源码部署就好了
losidk 发表于 2023-3-19 21:24
被你的介绍感动到了,太厉害了
minizhur 发表于 2023-3-19 21:55
学习学习,我也正在学习
siliconxu 发表于 2023-3-19 22:56
感谢分享!如果能够对代码做更详细的解释那就更适合新手学习了。
zt185 发表于 2023-3-19 23:01
学习了,楼主真棒!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 17:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表