☰
Python知识图谱与图神经网络电影推荐:KGCN项目完整运行与避坑指南
2026/10/12 21:09:55 网站建设 项目流程

简介:基于Python的知识图谱与图神经网络(KGCN)电影推荐系统完整源码,定位为高分毕设项目,面向高校毕业设计及课程设计场景,适合需要实现推荐算法与图模型结合的开发者参考。压缩包共32个文件,以21个Python脚本为核心,辅以dat格式数据集、txt说明及readme等文档,整体仅12.69MB,结构清晰便于定位。项目采用ml-1m数据集,在python3.8、tensorflow2.3.8环境下,运行main.py即可训练生成KCGN.h5权重,再通过test.py完成预测,流程覆盖数据预处理、知识图谱构建、KGCN层设计、模型训练与评测等完整环节。代码模块划分明确,附带README说明,可直接复现实验,有助于深入理解知识图谱与图神经网络的融合思路,也便于在此基础上进行改进与二次开发。目前已有490人学习下载,适合推荐系统方向的本科生与研究生作为项目蓝本。

1. 基于Python的知识图谱与图神经网络电影推荐:这份资源能跑多远

毕业设计里选推荐系统方向的人,多半是冲着「知识图谱 + 图神经网络」这个组合来的。可真正打开开源项目,很多人在 Python 环境这一步卡住,连一次完整的训练都没跑过。这份基于 Python 的知识图谱和图神经网络电影推荐项目,用 ml-1m 数据集垫底,要求 Python 3.8、TensorFlow 2.3.8,目标是打开项目直接运行 main.py 生成 KGCN.h5,再运行 test 得到预测结果。它把知识图谱构建、图神经网络训练和评估验证串成完整链路,适合正在做推荐方向课程设计、毕业设计的人。下面按拆包顺序写清楚:代码结构、数据流向、运行步骤和翻车点。

2. 项目全景:ml-1m 数据集、KGCN 模型与代码包装配关系

2.1 技术栈与运行环境:为什么是 Python 3.8 + TensorFlow 2.3.8

不少人在 python 安装这一步翻车。不是不会装,而是版本选错。这个项目明确要求 python=3.8、tensorflow=2.3.8,这是图神经网络项目里很常见的稳定组合。TensorFlow 2.3 的 tf.keras 已经成熟,KGCN 这种以 Embedding 查询和邻域聚合为主的模型,用 2.x 的 API 写起来比 1.x 顺手很多;而 Python 3.8 又能兼容 pandas、numpy 的大部分版本,不至于在数据处理库上再折腾一轮。

如果你电脑里已经是 python 3.10 或 3.11,我的建议是别硬用,单独开一个 3.8 虚拟环境的代价,比后面改代码的代价低得多。常见做法是:

conda create -n kgcn python=3.8 conda activate kgcn pip install tensorflow==2.3.8

装好后执行 python -c "import tensorflow as tf; print(tf.version)" 确认版本。这里有一个容易踩的坑:如果机器上有多个 Python 环境,pip 可能装到了别的地方,所以装依赖前先用 which python 和 which pip 确认路径一致,再看一遍 import 结果,这能省掉后面至少一小时的排查时间。

另外注意,TensorFlow 2.3 对 GPU 的支持已经并回主包,不用单独装 tensorflow-gpu。网上很多教程还在让你装 tensorflow-gpu,那是 1.x 时代的习惯,照做反而会装出一个和项目代码不兼容的版本。真正要处理的 GPU 问题是 CUDA 和 cuDNN 版本匹配,如果训练时看不到 GPU 加速,大概率是底层的这套东西没对上,TensorFlow 自动退回 CPU 了,这事后面避坑章节会细说。

2.2 文件结构拆解:从一个入口到一条完整训练链路

解开压缩包,我习惯先把目录看清,再双击 main.py,不然报错时根本不知道去哪里找原因。这份项目的代码分三块:data 目录负责数据读取和知识图谱构建,KGCN 目录负责模型定义与训练,根目录的 main.py、train.py 负责把整条链路串起来。web 目录里的 app.py 和 win.py 是给可视化或 Web 展示准备的,初次跑通阶段可以先不管。压缩包里还有个新建文本文档.txt,通常是作者留下的笔记,先打开看一眼,这里面可能记录着依赖版本或路径修改记录。

关键文件整理成一张表,后面调试时按表找文件,能省不少时间:

路径职责说明
main.py项目主入口加载数据、训练模型、导出权重文件
train.py训练流程和 main.py 配合,训练逻辑拆分在这里
test.py / testkg.py预测阶段加载 KGCN.h5 输出推荐结果
data/ds/data_process.py原始数据处理把 .dat 文件转成模型可读的索引
data/kg/kg_loader.py知识图谱加载读取实体、关系三元组
create_kg.py知识图谱构建生成实体映射和关系映射
KGCN/layer.pyKGCN 核心层实现邻域采样与特征聚合
KGCN/model.py模型结构定义 embedding、聚合层和输出层
KGCN/data2csv.py数据转 csv方便检查中间结果
utility/evaluation.py评估指标AUC、ACC、F1
utility/gpu_memory_growth.pyGPU 显存设置按需增长,避免 OOM
utility/common.py / decorator.py公共函数时间统计、日志装饰等

拆包时注意,testkg.py 和 test.py 作用不一样,testkg 更像调试工具,做单样本推理,后面进阶部分我会单独讲。对新手来说,只要盯住 main.py → train.py → test.py 这条主链路,其他文件都是辅助,别一开始就被文件数量吓住。

2.3 数据格式:users.dat、ratings.dat、movies.dat 到底长什么样

ml-1m 是 MovieLens 1M 数据集的简称,里面用::做分隔符。ratings.dat 每行是user_id::movie_id::rating::timestamp,movies.dat 每行是movie_id::title::genres,users.dat 每行是user_id::gender::age::occupation::zip-code。别看后缀是 .dat,其实本质是文本文件。

第一个常见错误就是拿 pandas.read_csv 直接读,默认分隔符根本不对。正确做法是指定分隔符和列名:

import pandas as pd ratings = pd.read_csv( "data/ds/ratings.dat", sep="::", names=["userId", "movieId", "rating", "timestamp"], engine="python" )

这段代码里 sep="::" 是关键,engine="python" 是因为分隔符不是单个字符时,底层 C 引擎解析不稳定。列名要以项目源码里 data_process.py 真正引用的为准,别照抄。跑之前先打印 ratings.head(),确认前几行能切出正确的列,这一步能挡住后面一半的数据类报错。

2.4 知识图谱构建:实体、关系与三元组的生成

知识图谱在这类项目里不是把整张电影图谱都搬进来,而是抽取和推荐场景相关的实体及关系。常见做法是电影当实体,类型、导演、演员当属性或关系,用户行为也参与构成关系。create_kg.py 做的事,就是把这些关系整理成三元组,比如 (电影A, 类型, 喜剧),然后建立实体和关系的索引,供后续模型读取。

data/kg/kg_loader.py 负责加载这些三元组。它读进去之后,KGCN 模型才能在每个训练批次里做邻域采样。这里有一个关键认知:图神经网络训练时不会一次把整个图谱塞进 GPU,而是围绕目标节点采样固定数量的邻居。比如设定邻居数 neighbor_num=8,就只取每个实体周围的 8 条关系参与聚合。这样训练时的内存消耗可控,也是项目能在普通笔记本上跑通的关键。理解这条数据链路后,再回去看 main.py,就会清楚每个变量在等什么数据,而不是对着报错瞎猜。

3. 把项目跑通:从创建知识图谱到生成 KGCN.h5

3.1 环境预检:版本、路径、数据完整性

拿到项目后先别急着运行。我拆过的项目里,一半以上的失败发生在三个点上:Python 版本不对、TensorFlow 版本不对、数据文件缺失。

python --version pip show tensorflow

如果 Python 是 3.8 但 TensorFlow 显示的是 1.15 或 2.9,那就不是这套代码要的环境。KGCN 模型代码里用到 tf.keras 的接口,不同大版本的 API 差异很大,硬跑会出现找不到某个模块的报错。解决方式按前面说的,单独建环境重新装依赖,别在旧环境上修修补补。

数据完整性检查放第二位。ml-1m 解压后,data/ds 目录里必须有 users.dat、ratings.dat、movies.dat 三个文件,缺一个后期必报 FileNotFoundError。有些下载源会把文件打包进二级目录,解开后路径不对,同样报错。检查方式很简单:

ls -la data/ds/

然后确认 create_kg.py 里引用的路径和实际路径一致。常见做法是进入项目根目录后用相对路径运行,别在别的目录下执行脚本,否则文件路径全都对不上。

3.2 构建知识图谱:先跑 create_kg.py 还是直接跑 main.py

项目描述里说打开项目直接运行 main.py,但对第一次运行的人,我一般会建议先手动执行 create_kg.py。原因在于,图神经网络的训练依赖知识图谱三元组,如果图谱构建这一步失败,main.py 会卡在数据加载阶段,报错信息还不直观。

python create_kg.py

这个脚本做完后会生成实体和关系的映射文件,有的版本体现为新生成的 .pkl 或 .json,有的直接写进内存。怎么看成功没成功?看运行日志最后几行,出现 save complete 或 kg done 之类字样,说明成功。如果直接抛 traceback,大概率是评分数据里存在空值或非法字符,回 data_process.py 打印中间结果排查。

还需要注意一点:create_kg.py 构建的图谱规模取决于数据量,ml-1m 有 100 万条评分记录,生成的三元组可能在几十万到百万量级。如果机器内存只有 8G,构建过程会慢,这是正常的,不是死机。盯住任务管理器或 htop 看内存变化,如果内存持续快速增长且不回落,才是真正的内存问题。

3.3 运行 main.py:训练过程到底发生了什么

create_kg 跑通之后,回到项目根目录执行:

python main.py

main.py 的训练循环通常有这几个阶段:读取评分数据和图谱数据,建立 user、item 的 ID 索引,初始化 KGCN 模型,然后按 batch 把样本喂进去做邻域采样和梯度更新。运行过程中,你会看到类似这样的日志:

epoch: 1, loss: 2.3124, auc: 0.7231 epoch: 2, loss: 1.9587, auc: 0.7512

loss 下降是正常信号,auc 提升说明模型在学东西。如果 loss 从第一轮就抖动稳住不降,先别急着调模型,回数据处理环节确认评分是否归一化、数据划分是否正确。这里最常见的误用是把全部数据直接丢进训练,没有划分 train/valid/test,导致训练完连评估都做不了。

训练完成后会生成 KGCN.h5 文件。原项目描述里写的文件名是 KCGN.h5,这个拼写看起来像是笔误,实际以代码里 model.save 的路径为准。这个文件就是训练好的模型权重,HDF5 格式,test 脚本加载它就够用了。注意:如果训练过程加了 checkpoint 回调,可能还会生成中间的 .h5 或 .ckpt 文件,那些是辅助文件,最终以 main.py 末尾保存的那个为准。

3.4 运行 test:读取 KGCN.h5 做预测

模型生成后,执行项目里对应的测试脚本:

python test.py

test.py 会加载前面保存的 KGCN.h5,对测试集的用户—物品对进行预测,输出评分或排序结果。不少人在这里发现预测结果出不来,常见原因是 KGCN.h5 的路径写死在了 test.py 的 load_model 参数里,如果实际文件名是 KCGN.h5 而代码写的是 KGCN.h5,就加载失败。这时候改代码里的路径,别去改文件名,因为 model.save 和 load_model 保持同一个名字,才不容易出错。

test 阶段还要注意批次大小。训练时的 batch_size 和测试时的可以不一样,但如果显存不够,测试时同样会 OOM。我一般会在测试脚本里把 batch_size 调到训练时的一半,速度会慢一点,但对结果没有影响。跑完测试脚本,项目主流程就算完整走通了,剩下的工作全在调参和换数据上。

4. 避坑与常见问题排查:从环境报错到结果失效

4.1 现象:Python 3.8 环境里 import tensorflow 直接报错

现象:用 conda 新建了 Python 3.8 环境,也执行过 pip install tensorflow==2.3.8,但 import tensorflow 时提示 module not found 或 dll load failed。

原因:最常见的是 pip 装到了别的 Python 环境。conda 激活环境后,终端里的 which python 和 which pip 如果指向不同路径,pip install 会把包装进非当前环境。另一个原因是 Windows 上缺少 Microsoft Visual C++ Redistributable 运行库,TensorFlow 在 Python 3.8 下会出现 DLL load failed 的报错。

解决:第一步跑 which python 和 which pip,确认都在 kgcn 环境目录下;第二步在 Python 里执行 import sys; print(sys.executable) 看解释器路径。如果 pip 路径不对,用 python -m pip install tensorflow==2.3.8 强制绑定当前解释器。如果 DLL 报错依旧,检查系统变量里有没有 VC++ 运行库,到微软官网装对应版本即可。

4.2 现象:训练时显存爆掉,程序直接被杀

现象:运行 main.py 后,训练刚开始或第一个 epoch 结束时进程被杀,或者直接报 CUDA out of memory。

原因:项目里的 gpu_memory_growth.py 没被调用。TensorFlow 默认在启动时申请几乎全部 GPU 显存,和别人共用一张卡时特别容易冲突。KGCN 的邻域采样也耗显存,采样数越大开销越大。

解决:确认 main.py 或 train.py 里 import 并调用了 utility/gpu_memory_growth.py 的函数。如果没有,在 main.py 开头加:

from utility.gpu_memory_growth import init_gpu_memory_growth init_gpu_memory_growth()

加完还爆,就把 batch_size 从 256 降到 128,或者把邻居采样数从 8 降到 4。图神经网络的显存占用和邻居数近似成正比,降邻居数是最快见效的手段,代价是模型能看到的图结构信息变少,效果可能略降。

4.3 现象:KGCN.h5 生成后预测结果没有区分度

现象:test 脚本跑完,预测评分全是一个固定值,或者所有候选电影得分几乎一样,推荐排序完全失效。

原因:训练根本没收敛。打印训练日志,如果 loss 从头到尾在一个值附近震荡,说明模型没有学到有效特征。常见原因有两个:一是评分没做归一化,KGCN 输出层是 sigmoid 或线性层,输入评分范围 1-5 和激活函数不匹配;二是训练轮数太少,loss 还没掉下来就保存了模型。

解决:先看训练日志,loss 是否单调下降。如果不是,回数据处理环节确认评分经过归一化。如果归一化后还不动,把 epochs 从 20 提高到 50。还有一个细节,很多版本把评分预测当回归任务处理,输出层是 sigmoid,predict 之后还要把概率乘以 5 还原成 1-5 评分。test 脚本里的解码方式要和模型输出层对应上,否则结果全是 0 到 1 之间的小数,看着就像没有区分度。

4.4 现象:dat 文件读取报 UnicodeDecodeError 或列数不一致

现象:data_process.py 在读 ratings.dat 时报 decode 错误,或者切分后列数不对。

原因:ml-1m 数据集里的电影标题和用户信息包含特殊字符,Windows 默认读文件用 GBK 编码,遇到 UTF-8 字符直接崩。列数不一致则是因为分隔符不对,有些下载版本里::可能是单冒号,或者某行数据里多了一个冒号。

解决:读取时显式指定 encoding="utf-8" 或 "latin-1"。某些版本的 ml-1m 里用户邮编字段存在空值,读进来变成 NaN,处理时统一 dropna。如果是分隔符问题,先打印前几行看实际格式,再决定 sep 参数。配合 KGCN/data2csv.py 把数据导成 csv 对照检查,比盯着异常栈猜快得多。

4.5 现象:导入模块时报 cannot import name

现象:运行项目时提示 from KGCN.layer import xxx 失败,找不到某个类或函数。

原因:文件路径和模块名大小写不一致,或者 Python 的 import 路径没有包含项目根目录。Windows 文件系统不区分大小写,但 Linux 和 macOS 区分,KGCN 目录和 kgcn 目录是两回事。这个问题在把项目从 Windows 挪到服务器上跑的时候特别常见。

解决:在 main.py 开头把项目根目录加进模块搜索路径:

import os, sys sys.path.append(os.path.dirname(os.path.abspath(__file__)))

然后检查所有 import 语句里的目录名是否和实际一致。跨平台部署时,先统一文件夹大小写,能避免大部分这类问题。

5. 替换成自己的数据集:从 ml-1m 到自建数据的改造要点

5.1 自建评分表怎么转成 ratings.dat 的格式

如果毕设要用自己的数据,第一步是转格式。别想着改代码适配自己的表格,先把自己的数据转成项目能读的格式,改动更小,不容易两边同时出错。需要准备三个文件:ratings.dat 保存用户对物品的评分,movies.dat 保存物品信息,users.dat 保存用户信息,分隔符统一用::。

假设你有一个 csv,列是 userId、movieId、rating、timestamp,转换命令:

python -c " import pandas as pd df = pd.read_csv('my_ratings.csv') with open('data/ds/ratings.dat', 'w') as f: for row in df.itertuples(): f.write(f'{row.userId}::{row.movieId}::{row.rating}::{row.timestamp}\n') "

这个命令的关键在分隔符拼接,:: 前后不能有多余空格。写完用 head 检查前几行,确保输出形如 1::1::5::978300760。如果自己的数据没有 timestamp 字段,统一填 0,模型不使用时间特征就不影响训练。注意 userId 和 movieId 必须是整数,字符串类型的 ID 在建立索引时容易按字典序排错,导致训练样本错乱。

5.2 调整 KGCN 参数:层数、邻居数和 embedding 维度

换数据之后需要重新调参。KGCN 在项目里的核心参数有三个:图卷积层数、每个实体的邻居采样数、embedding 维度。不建议一次性全改,出了问题不知道是哪一项导致的。先保证小数据量能跑通,再逐步增加参数。

# KGCN/layer.py 或 model.py 里通常有这些参数 embedding_size = 64 # 特征向量维度 n_neighbor = 8 # 邻域采样数量 n_iter = 2 # 图卷积迭代层数

embedding_size 影响模型容量,数据量小时 64 足够,数据过万时再调到 128 或 256。n_neighbor 影响显存和训练速度,8 是安全值,加到 16 会明显变慢但不一定更好。n_iter 是 KGCN 层数,2 到 3 层效果最好,再深容易过平滑,所有节点特征趋同,推荐结果没有区分度。调参时记下一组 baseline,每次只改一个参数,用 evaluation.py 算的指标做对比,比凭感觉调高效得多。

5.3 用 evaluation.py 做指标校验:AUC、ACC、F1 怎么读

这份项目里 utility/evaluation.py 提供评估指标,主要关注三个:AUC、ACC、F1。AUC 衡量排序能力,AUC 0.7 以上说明推荐结果有区分度;ACC 是准确率,但要看正负样本比例,如果正负样本失衡,ACC 虚高很正常;F1 在正负样本不均时比 ACC 更可信。

我一般会在 test 之后单独跑一步评估:

python utility/evaluation.py

或者直接在代码里调用评估函数:

from utility.evaluation import cal_metrics auc, acc, f1 = cal_metrics(labels, preds) print(f"auc={auc:.4f}, acc={acc:.4f}, f1={f1:.4f}")

这里有个容易搞错的地方:labels 和 preds 必须是同一批测试样本,且 preds 如果是连续概率,算 ACC 前要先用阈值 0.5 把概率转成 0/1;算 AUC 则不需要转,直接用原始概率。很多人把连续概率和 0/1 标签直接比较,得出的 ACC 低得离谱,其实不是模型差,是评估方式错了。

5.4 常见误用:没有划分验证集就训练

训练推荐系统不是把全部数据丢进去死磕。最常见的误用是不划分验证集。模型训练时见过所有评分,报告出来的指标虚高,答辩时一问数据划分就露馅。标准做法是把数据集按 8:1:1 切分,训练集用于梯度更新,验证集用于选参数,测试集用于最终评估。

main.py 或 train.py 里通常已经内置划分比例,运行前确认默认值是按时间切还是按随机方式切。按时间划分更贴近真实推荐场景,按随机划分更简单,但对时间敏感的数据会有信息泄漏。毕设答辩时,能说清楚用哪种划分方式,比单纯报一个很高的 AUC 更能拿分。

6. 进阶技巧:用 testkg.py 做单样本推理,验证推荐结果可解释

testkg.py 是项目里一个单独的脚本,和 test.py 的区别在于它做单样本级别的推理。test.py 通常加载测试集批量出结果,testkg.py 更像调试工具:你指定一个用户和一个候选物品,它单独返回这条样本的预测得分。这个脚本在答辩演示时很实用,能现场展示推荐逻辑。

使用套路是先确认模型路径,然后直接跑:

python testkg.py --user_id 1 --movie_id 100

如果 testkg.py 写成硬编码、没留命令行参数,那就直接改脚本里相应的 user_id 和 movie_id 两个变量,把预测结果打印出来。单样本推理的价值在于,你可以对比两个候选物品的差异:同一个用户换一部电影,分数是否变化;两个关联度高的电影,分数差异是否小。这能反过来校验知识图谱构建是否合理。如果两个明显不相关的电影得分一样,说明图谱里的关系没有发挥作用,需要回 create_kg.py 检查三元组质量,很多情况下是关系类型太少,导致邻域聚合时所有节点拿到相近的特征。

另外一个好处是,单样本推理跑得快,适合做参数对比实验。调 embedding 维度或邻居数之后,先用单个样本验证前向传播无误,再跑完整测试集。我自己的习惯是每次改动模型结构后,先对同一对 user-item 跑一次 testkg.py,确认输出没有报错再去跑完整评估,避免训练半小时后才发现模型结构写错。从那以后我每次跑这个项目都会强制走一遍 testkg.py 单样本验证流程,先花 30 秒确认模型能正常推理,再花 10 分钟跑完整测试集,希望这个习惯能帮到你少走弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询