基于知识图谱的电影知识问答系统:训练TF-IDF 向量算法和朴素贝叶斯分类器、在 Neo4j 中查询
基于知识图谱的电影知识问答系统:训练TF-IDF 向量算法和朴素贝叶斯分类器、在 Neo4j 中查询
1.项目介绍
- 训练 TF-IDF 向量算法和朴素贝叶斯分类器,预测用户文本所属的问题类别
- 使用分词库解析用户文本词性,提取关键词
- 结合关键词与问题类别,在 Neo4j 中查询问题的答案
- 通过 Flask 对外提供 RESTful API
- 前端交互与答案展示
2.项目实操教学
2.1 数据集简介
{
"introduction_by_movie": [
"nm简介",
"nm剧情简介",
"nm的内容是什么",
"nm讲了什么",
"nm讲了什么故事",
"nm演了什么",
"nm的故事梗概是什么",
"nm的剧情简介是什么",
"nm的内容简介是什么",
"nm的剧情介绍是什么",
"nm的情节是什么",
"nm的主要情节是什么"
],
"rating_by_movie": [
"nm的评分是多少",
"nm得了多少分",
"nm的评分有多少",
"nm的评分",
"nm得分是多少",
"nm的分数是",
"nm电影分数是多少",
"nm电影评分",
"nm评分",
"nm的分数是多少",
"nm这部电影的评分是多少"
],
"release_date_by_movie": [
"nm上映时间",
"nm定档时间",
"nm的上映时间是什么时候",
"nm的首映时间是什么时候",
"nm什么时候上映",
"nm什么时候首映",
"最早什么时候能看到nm",
"nm什么时候在影院上线",
"什么时候可以在影院看到nm",
"nm什么时候在影院放映",
"nm什么时候首播"
],
2.2 用户词典
Forrest Gump nm
Kill Bill: Vol. 1 nm
英雄 nm
Miami Vice nm
Indiana Jones and the Temple of Doom nm
卧虎藏龙 nm
Pirates of the Caribbean: At World's End nm
Kill Bill: Vol. 2 nm
The Matrix Reloaded nm
The Matrix Revolutions nm
Harry Potter and the Chamber of Secrets nm
Harry Potter and the Prisoner of Azkaban nm
Harry Potter and the Goblet of Fire nm
Harry Potter and the Order of the Phoenix nm
The Last Emperor nm
Harry Potter and the Half-Blood Prince nm
花样年华 nm
2046 nm
Lethal Weapon 4 nm
Hannibal Rising nm
TMNT nm
무사 nm
Anna and the King nm
满城尽带黄金甲 nm
2.3 环境依赖
jieba
neo4j
python-dotenv
scikit-learn
flask
flask-cors
gunicorn
2.4 部分代码展示
import os
from neo4j import GraphDatabase
class Database:
"""
Neo4j 数据库访问层。
管理数据库连接的生命周期,并提供查询接口。
"""
def __init__(self):
uri = os.environ["DATABASE_URI"]
user = os.environ["DATABASE_USER"]
password = os.environ["DATABASE_PASSWORD"]
try:
self._driver = GraphDatabase.driver(uri, auth=(user, password))
self._session = self._driver.session()
except Exception as e:
raise Exception("数据库连接失败") from e
def close(self):
try:
self._session.close()
self._driver.close()
except Exception as e:
raise Exception("数据库断开失败") from e
def find_one(self, query: str, **parameters):
result = self._session.run(query, parameters).single()
return result.value() if result else None
def find_many(self, query: str, **parameters):
return self._session.run(query, parameters).value()
if __name__ == "__main__":
import dotenv
dotenv.load_dotenv()
database = Database()
genres = database.find_many(
"""
MATCH (m:Movie)-[BELONGS_TO]->(g:Genre)
WHERE m.name = $movie_name
RETURN g.name
""",
movie_name="卧虎藏龙",
)
database.close()
print(genres)
import json
import os
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
TRAIN_DATASET_PATH = os.path.join("data", "train.json")
jieba.setLogLevel("ERROR")
def normalize(sentence: str):
return " ".join(jieba.cut(sentence))
class BaseClassifier:
"""
底层分类器。
使用 TF-IDF 向量化文本,然后使用朴素贝叶斯预测标签。
"""
def __init__(self):
self._vectorizer = TfidfVectorizer()
self._classifier = MultinomialNB(alpha=0.01)
def _train(self, x: list, y: list):
X = self._vectorizer.fit_transform(x).toarray()
self._classifier.fit(X, y)
def _predict(self, x: list):
X = self._vectorizer.transform(x).toarray()
return self._classifier.predict(X)
class Classifier(BaseClassifier):
"""
问题分类器。
根据问题中出现的关键词,将问题归于某一已知类别下。
"""
def __init__(self):
BaseClassifier.__init__(self)
questions, labels = Classifier._read_train_dataset()
self._train(questions, labels)
def classify(self, sentence: str):
question = normalize(sentence)
return self._predict([question])[0]
@staticmethod
def _read_train_dataset():
with open(TRAIN_DATASET_PATH, "r", encoding="utf-8") as fr:
train_dataset: dict[str, list[str]] = json.load(fr)
questions = []
labels = []
for label, sentences in train_dataset.items():
questions.extend([normalize(sentence) for sentence in sentences])
labels.extend([label for _ in sentences])
return questions, labels
if __name__ == "__main__":
classifier = Classifier()
while True:
sentence = input("请输入问题:").strip()
label = classifier.classify(sentence)
print(f"问题分类:{label}")
2.5 运行项目
在 backend 目录下添加环境变量文件 .env。
# Neo4j 数据库地址
DATABASE_URI=
# Neo4j 用户名
DATABASE_USER=
# Neo4j 密码
DATABASE_PASSWORD=
启动后端服务。
cd backend
gunicorn app:app
在 frontend 目录下添加环境变量文件 .env。
# 后端服务地址
VITE_API_BASE_URL=
启动前端服务。
cd frontend
npm build
npm preview
3.技术栈
3.1数据库
3.2核心 QA 模块
3.3后端
3.4前端
TypeScript
Preact
Tailwind CSS
pnpm
Vite
ESLint
Prettier
码源链接跳转见文末
更多优质内容请关注公号&知乎:汀丶人工智能;会提供一些相关的资源和优质文章,免费获取阅读。
基于知识图谱的电影知识问答系统:训练TF-IDF 向量算法和朴素贝叶斯分类器、在 Neo4j 中查询的更多相关文章
- 使用LSTM做电影评论负面检测——使用朴素贝叶斯才51%,但是使用LSTM可以达到99%准确度
基本思路: 每个评论取前200个单词.然后生成词汇表,利用词汇index标注评论(对 每条评论的前200个单词编号而已),然后使用LSTM做正负评论检测. 代码解读见[[[评论]]]!embeddin ...
- 贝叶斯--旧金山犯罪分类预测和电影评价好坏 demo
来源引用:https://blog.csdn.net/han_xiaoyang/article/details/50629608 1.引言 贝叶斯是经典的机器学习算法,朴素贝叶斯经常运用于机器学习的案 ...
- 知识图谱+Recorder︱中文知识图谱API与工具、科研机构与算法框架
目录 分为两个部分,笔者看到的知识图谱在商业领域的应用,外加看到的一些算法框架与研究机构. 文章目录 @ 一.知识图谱商业应用 01 唯品金融大数据 02 PlantData知识图谱数据智能平台 03 ...
- 基于知识图谱的APT组织追踪治理
高级持续性威胁(APT)正日益成为针对政府和企业重要资产的不可忽视的网络空间重大威胁.由于APT攻击往往具有明确的攻击意图,并且其攻击手段具备极高的隐蔽性和潜伏性,传统的网络检测手段通常无法有效对其进 ...
- 知识图谱里的知识存储:neo4j的介绍和使用
一般情况下,我们使用数据库查找事物间的联系的时候,只需要短程关系的查询(两层以内的关联).当需要进行更长程的,更广范围的关系查询时,就需要图数据库的功能. 而随着社交.电商.金融.零售.物联网等行 ...
- TF/IDF(term frequency/inverse document frequency)
TF/IDF(term frequency/inverse document frequency) 的概念被公认为信息检索中最重要的发明. 一. TF/IDF描述单个term与特定document的相 ...
- 文本分类学习(三) 特征权重(TF/IDF)和特征提取
上一篇中,主要说的就是词袋模型.回顾一下,在进行文本分类之前,我们需要把待分类文本先用词袋模型进行文本表示.首先是将训练集中的所有单词经过去停用词之后组合成一个词袋,或者叫做字典,实际上一个维度很大的 ...
- darktrace 亮点是使用的无监督学习(贝叶斯网络、聚类、递归贝叶斯估计)发现未知威胁——使用无人监督 机器学习反而允许系统发现罕见的和以前看不见的威胁,这些威胁本身并不依赖 不完善的训练数据集。 学习正常数据,发现异常!
先说说他们的产品:企业免疫系统(基于异常发现来识别威胁) 可以看到是面向企业内部安全的! 优点整个网络拓扑的三维可视化企业威胁级别的实时全局概述智能地聚类异常泛频谱观测 - 高阶网络拓扑;特定群集,子 ...
- tf idf公式及sklearn中TfidfVectorizer
在文本挖掘预处理之向量化与Hash Trick中我们讲到在文本挖掘的预处理中,向量化之后一般都伴随着TF-IDF的处理,那么什么是TF-IDF,为什么一般我们要加这一步预处理呢?这里就对TF-IDF的 ...
- 基于TF/IDF的聚类算法原理
一.TF/IDF描述单个term与特定document的相关性TF(Term Frequency): 表示一个term与某个document的相关性. 公式为这个term在document中出 ...
随机推荐
- Linux day4:查看文件属性信息 inode和block 硬链接和软链接 inux系统时间 虚拟机克隆 linux定时任务 paramiko模块 公钥私钥
目录 文件属性信息 存储数据相关 inode block 访问文件原理 链接信息 硬链接 软链接 linux系统时间 虚拟机克隆 链接克隆和完整克隆 克隆之后的配置 linux定时任务 定时任务软件 ...
- 视频云AI时代,穿越市场第一,想象更多
国际权威数据公司IDC发布<中国视频云市场跟踪(2023 H1)>报告:自2018年至今,阿里云持续保持中国视频云整体市场第一,整体市场占比达24.4%. 01 第一之外,低谷之上 近期, ...
- SpringMVC — 数据响应 / 获取请求参数
SpringMVC的数据响应方式 页面跳转 直接返回字符串 通过ModelAndView对象返回 回写数据 直接返回字符串 返回对象或集合 页面跳转 方式一.返回带有前缀的字符串: 转发:forwar ...
- KB专题:区间DP专辑
自从多校后心憔悴啊,发现DP还是太水了,有一场的区间DP竟然不会做,咳,果然是赤裸裸的水军. 花了几天时间写了几道区间DP的题目,大部分都是水题,然后和以前的合并起来就是KB区间DP这个8 + 1道题 ...
- 题解 [HDU6746] Civilization(贪心+模拟)
来源:2020 年百度之星·程序设计大赛 - 初赛一 一道贪心 + 细节模拟题 题意很简单,这里不详细写了 观察题目,\(n\) 只有 500 ,可以 \(n \times n\) 枚举每个位置作为起 ...
- Problem 330A - Cakeminator (思维)
330A. Cakeminator https://codeforces.com/problemset/problem/330/A 题意很容易理解:给定一块蛋糕区域,但蛋糕上有几个不能吃的草莓,大胃王 ...
- 【每日一题】1. tokitsukaze and Soldier (优先队列 + 排序)
题目链接:Here 思路:这道题很容易看出来是考察 优先队列(priority_queue) 和 sort . 对于容忍人数越高的人来说,团队人数低也更能做到: for i = 0 to n - 1: ...
- watch监听对象遇坑
当以下数据,有一个变化,就重新调接口. formInline: { needTrain: '', trainResult: '', userNameS ...
- P1765
和那道题一样,这次用的getchar,结果对了可是洛谷评测WA了,换成scanf单个字符,结果还是WA了,换成直接getline读入整个字符串就对了. 可见读入单个字符的方式有可能出现各种小错,尤其是 ...
- C#从字符创中分离文件路径、文件名及扩展名
效果图 代码如下 private void btn_Openfile_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialo ...