1. 为什么这个选题值得做:从“显示度”和“工作量”两个维度拆解
每年到了毕业设计开题季,我都能看见大量同学在古诗词、推荐系统、情感分析这几个方向上犹豫不决。有的选了纯前端可视化,被导师批“没有技术深度”;有的选了传统推荐算法,结果答辩时被问“你的创新点在哪里”直接卡壳。这套以“Django + DeepSeek大模型 + 知识图谱 + 古诗词情感分析”为核心的组合方案,恰好把这几个问题一次性解决掉。
先聊选这题的核心逻辑。古诗词天然自带文本数据、朝代标签、诗人信息、情感倾向四个维度,非常适合用来做知识图谱和情感分析的载体。跟电商推荐、新闻推荐相比,古诗词数据量适中——你不用处理上亿条用户行为日志,一张表几千上万条诗词就能做出完整的推荐链路,这对毕业设计来说反而是优势:工作量可管控,又能在答辩时把“数据清洗—模型构建—系统实现”的完整过程讲清楚。
其次,这个题目把大模型、知识图谱、推荐算法、前后端开发全占了。导师关注的核心是“工作量饱满+技术栈完整”,Django负责业务系统,DeepSeek负责情感判断和语义理解,知识图谱负责实体关系组织,推荐模块负责个性化输出,可视化负责结果呈现。五条线交叉在一起,无论是开题报告、中期检查还是最终答辩,都有足够多的内容可以讲。
再说这个方案的显示度。传统古诗词系统做得最多的就是“按题目搜诗、按作者筛诗、按朝代列表”,最多加个关键词模糊匹配。但你这套系统出来的是什么效果?用户搜索“李白的离别诗”,推荐结果能给出“李白与杜甫的送别诗对比”“与《黄鹤楼送孟浩然之广陵》情感相似的作品”;点开一首诗,页面旁边能看到诗人关系图谱、情感倾向变化曲线、同时代关联作品。这种呈现方式在答辩现场会让评委眼前一亮——因为大家已经看腻了千篇一律的CRUD系统。
当然,选题是个好选题,但实现起来坑也不少。接下来我把这套系统的完整构建过程拆开讲,从技术选型、数据清洗、模型调用,到知识图谱落地、推荐逻辑设计、可视化呈现,再到我实测过程中踩过的真实坑,一次性说明白。
2. 整体架构与技术选型:一次性把每层技术栈的选型理由讲透
2.1 四层架构:从数据层到展示层的职责划分
这套系统我推荐按照数据层、服务层、模型层、展示层四层来组织。这不是为了架构而架构,而是为了让你在写论文和画系统架构图时有清晰的层次逻辑,也方便后续独立替换某一个模块。
数据层负责三类数据:诗词文本数据、诗人与朝代元数据、用户行为数据。诗词数据可以从开源数据集或爬虫获取,核心字段包括题目、正文、注释、译文、赏析、诗人ID、朝代ID。用户行为数据则来自你在Django中设计的用户表、收藏表和浏览记录表,这些数据会直接进入推荐算法。
服务层用Django实现,提供RESTful API接口,处理前端页面请求、用户管理、诗词检索、推荐结果调度。Django自带的Admin后台对于管理诗词数据和用户数据非常方便,在毕设答辩演示时,用它来展示数据管理能力也很加分。
模型层是本系统的核心亮点,包含三个模型组件:DeepSeek大模型接口(负责情感分析、语义相似度计算、文本向量化)、知识图谱模块(负责实体识别和关系抽取)、推荐算法模块(负责个性化推荐)。
展示层使用前端框架配合ECharts实现可视化大屏和交互页面。这里注意,不要用Django的模板渲染做复杂图表,建议前后端分离,用Ajax异步加载数据,ECharts负责图表呈现。
2.2 为什么选Django而不是Flask或Spring Boot
很多人问,毕设做系统为什么非要用Django,Flask不是更轻量吗?这个问题我在实际开发中体会很深。
Django最大的优势是“自带的Admin管理后台和ORM,能帮你省下至少一周的开发时间”。诗词数据有几十个字段,用Flask你得自己写完整的后台管理页面,而Django的Admin可以基于模型定义自动生成增删改查界面。配合数据迁移机制,改表结构的时候不会把数据搞乱。另一层考虑是答辩时导师对Django的熟悉度更高,代码里Model、View、Serializer的清晰分层容易被挑出亮点。
有人建议用Spring Boot,但从我的经验看,毕设阶段用Java做这种项目有两层阻力:一是开发节奏慢,写实体类、Mapper、Service要花大量时间;二是部署环境重,答辩演示容易在环境配置上翻车。Python生态在数据清洗和模型调用上天然更顺滑——你处理古诗词文本用的是Pandas,调用大模型用的是Python SDK,前后逻辑贯穿一致,减少跨语言切换的认知负担。
2.3 DeepSeek大模型在系统里的三个具体定位
大模型在毕设系统里很容易沦为“为了用而用”——比如随便接个问答接口就说自己用了大模型。为了避免这个尴尬,我建议把DeepSeek的能力精准嵌入到三个具体位置:
第一个是情感分析。古诗情感分析如果要走传统机器学习路线,需要手工标注大量训练数据并且做文本向量化,对于毕设来说工作量非常大。而DeepSeek可以直接通过Prompt实现判断,同时输出情感类别和情感强度。实测下来,对古诗词这种语义凝练的文本,大模型的判断准确率明显优于基于词典的传统方法。
第二个是语义相似度计算。传统推荐系统通常用词频向量或TF-IDF算文本相似度,但古诗词存在大量共同意象——比如“月”“酒”“离别”,在用词上有重合但表达意境不同。DeepSeek生成的语义向量能捕捉“《静夜思》和《月下独酌》的精神共鸣”,这是传统方法很难做到的。
第三个是知识图谱的实体关系抽取辅助。传统知识图谱构建需要制定关系类型,而DeepSeek可以从诗词文本中自动抽取“诗人—作品”“诗人—诗人”“作品—意象”三元组,大幅降低手工整理成本。
2.4 知识图谱存储选型:图数据库与Django的协同
知识图谱的存储通常有两个选择:用Neo4j图数据库单独存,或者用关系型数据库加图谱表结构模拟。我的建议是:如果你时间充足,用Neo4j;如果时间紧张,用Django自带的SQLite/MySQL加表结构也能实现所有核心功能。
用Neo4j的好处是查询和可视化直观——写Cypher查询“找所有与李白有关联的诗人”只需要一行语句,Neo4j的浏览器界面还能直接展示图谱连接关系,用于答辩演示效果特别好。缺点是你需要单独部署一个Neo4j服务,在数据同步和事务一致性上要多花工夫。
用关系型数据库实现图谱的做法也很实用:建三张核心表——实体表、关系表、实体关系映射表。实体表存诗人、作品、意象、朝代,关系表存关联类型,映射表存关联关系。推荐算法通过多表Join实现,系统部署简单,适合整体打包。
提示:针对毕业设计,我个人的折中方案是——用Django的SQLite存业务数据,用Neo4j存图谱数据,两者通过API层连接。这样论文里可以画出完整的系统架构图,答辩时既有图数据库的亮点,又不至于因为数据同步问题影响系统稳定性。
3. 古诗词数据集处理:比模型更磨人的环节,我的清洗方案
3.1 数据从哪来:来源渠道与法律合规提醒
古诗词数据集的获取渠道主要有几个:公开的GitHub仓库、在线诗词网站、古籍数字化项目的开源数据。有些同学直接用爬虫猛抓某个网站,这个做法我不推荐——一是法律法规层面有风险,二是抓下来的数据噪声大,字段混乱,清洗要花好几天。
相对成熟的做法是找一个字段较整齐的开源古诗词数据集作为基底,包含朝代、作者、题目、正文、注释、译文、赏析等字段。拿到后先做数据集拆分:一部分用于构建图谱,一部分用于情感分析和推荐。
要提醒的是,论文中一定要在“数据来源”章节写明数据获取方式和引用说明,这是答辩老师很容易关注的点。
3.2 清洗流程:去除噪声、补全缺失、统一格式
古诗词数据清洗是整个项目中最容易翻车的地方,我列一个标准流程:
第一,去除空值和重复项。用Pandas把无标题、无正文、无作者的记录全部过滤,按“标题+作者”去重。重复项在诗词数据里远比想象中多——同一首诗在不同朝代选本里的文字出入会产生重复条目。
第二,朝代字段统一。古诗词数据集中“唐代”和“唐朝”、“宋”和“宋代”会混着出现,需要做映射表统一处理。这个字段后面要用于朝代筛选和图表展示,不统一会导致可视化出现多个重复的柱子。
第三,生僻字和异体字清洗。古诗词正文中繁体字、异体字混用非常常见,需要先用OpenCC等工具做繁简转换,再处理异体字。同时很多诗句有文本识别错误,比如把“长”识别成“长”,这类噪声必须人工抽查修正。
第四,赏析字段的截断与清洗。有些数据集里的赏析是从百科复制过来的,带有大量HTML标签、版权说明甚至广告信息,需要用正则表达式统一清洗,保留内容正文。
清洗之后,建议按朝代、作者、诗词数量做一轮统计,看看数据分布是否均匀。比如“唐代多大诗人,诗词数量动辄几千首,而有些朝代可能只有个位数”,这种分布不均会影响后续推荐效果,需要在数据说明中给出合理解释。
3.3 数据入库:Django模型设计与索引优化
数据清洗完就要入库了,Django里建议建立这样几个核心模型:Poetry(诗词)、Poet(诗人)、Dynasty(朝代)、UserProfile(用户扩展信息)、Favorite(收藏)、Rating(评分)、EntityRelation(图谱关系)。
关键是索引设计——诗词检索如果用“标题模糊搜索”,不走索引的话千万级数据也能扛,但一旦数据量大,或者你后续要支持“按朝代+作者+情感倾向”复合筛选,就需要给Django模型的字段加上db_index=True。我实测中遇到过一个情况,当时一个搜索接口在数据量约两万条时响应已经接近3秒,加完索引后降到了200毫秒以内。
另一个入库时容易忽略的点是文本字段的存储选择。古诗正文和赏析都是长文本,MySQL里建议用TextField映射到LongText,不要用CharField限制长度,否则入库时直接报错。如果你用的是SQLite,则没有这个问题,但要注意SQLite在并发写入上性能有限,不建议在生产答辩演示时频繁做批量导入操作。
4. 情感分析模块:从Prompt设计到多模型对比的完整实现
4.1 Prompt设计:如何让DeepSeek稳定输出结构化情感结果
古诗词情感分析用大模型实现,核心在Prompt设计。我刚开始测试时出现过一次很好笑的翻车:我让模型“判断这首诗的情感”,结果模型输出一大段赏析文字,虽然有情感判断但没有结构化字段,程序根本没法解析。后来我把Prompt改成了严格限定输出的格式才算稳定。
我的做法是设计一个固定的任务模板,要求模型输出JSON格式的结果,包含三个字段:sentiment(情感类别)、intensity(情感强度)、reason(判断依据)。大致格式是这样的:
你是一个专业的中国古诗词情感分析专家。请分析下面这首古诗的情感倾向。 要求: 1. 从以下类别中选择最合适的一个:思乡、离别、壮志、愁绪、闲适、怀古、其他 2. 给出情感强度,范围1-5,1为最弱,5为最强 3. 用一句话说明判断理由 请严格按照如下JSON格式输出,不要输出任何多余内容: {"sentiment": "类别", "intensity": 数字, "reason": "一句话理由"} 古诗标题:{title} 古诗正文:{content}这里有个细节:在输出格式前先给一个“示例”,效果比直接描述JSON结构更好。另外要把“不要输出多余内容”写进Prompt,否则模型偶尔会附加解释文字,导致JSON解析失败。我在批处理几千首诗时,大约5%的返回会因为格式问题解析失败,所以代码里要加一个容错逻辑:解析失败就重试一次,并自动降低模型温度参数。
4.2 调用逻辑:批量处理与并发限流策略
情感分析模块在系统里需要批量处理整库的诗词数据,因为推荐和可视化需要全量情感标签。如果你是一首一首地调用DeepSeek接口,效率很低,而且容易触发限流。
我的方案是写一个独立的批处理脚本,用线程池并发调用,每首诗词的请求间隔控制在200毫秒左右,处理两万条数据大约需要两个小时。但毕设系统演示时,推荐和详情页面临时调用单首诗词的情感分析,响应时间要控制在3秒内——这部分可以做成异步任务,用Django的Celery处理,分析完通过WebSocket通知前端展示。
还有一个实战小技巧:情感分析结果不用每次实时计算,入库时一次性算好,存在数据库字段里,再在前端显示时直接读取。否则每次用户点开一首诗,后台都要重新调用模型接口,费用和时间成本都不可控。第一次分析入库,之后走缓存,这是大模型类毕设系统的通用优化手段。
4.3 多模型交叉验证:不要让答辩变成大模型“独角戏”
为了在论文和答辩中提高技术含量,我强烈建议不要只依赖大模型一个渠道出情感标签,而是引入多种方法交叉验证。
我用过最高效的交叉验证方案是:用情感词典基线方法(比如大连理工大学情感本体库,加上古诗词领域情感词表),先做一轮基于规则的初判,再把DeepSeek的结果和词典结果进行一致性比对。两者结论一致的比例大概在七成左右。剩余不一致的情况,我人工抽查了一部分,发现大模型的判断更贴合语境——比如“举头望明月”里的“望”不表达情绪,但词典可能把“望”标成中性,大模型能结合上下文理解思念之情。
这种“规则基线+大模型+人工抽检”的三级体系,在论文实验章节能画出漂亮的对比图,在答辩时也更有说服力。导师如果问“你的情感分析准确率是多少”,你至少可以说“以人工标注50首为基准,大模型结果的情感类别准确率约86%,强度误差平均在0.6以内,均优于词典基线”。有实测数据支撑,比一句“效果很好”强得多。
5. 知识图谱构建:三元组设计、Neo4j实现与查询实践
5.1 实体与关系建模:图谱不是越复杂越好
知识图谱的实体和关系设计要和你系统里的功能紧密结合,不要为建图谱而建图谱。我在设计这套系统时,核心围绕三条查询链路展开:
- 用户搜“李白的诗有什么” → 查询诗人节点及其关联的作品节点
- 用户查看某一首诗详情 → 展示该诗的诗人、朝代的关联信息
- 用户点击“相似诗词” → 根据共享意象或共同诗人,递归查找关联作品
基于此,我设计了四类实体:Poet(诗人)、Poetry(作品)、Dynasty(朝代)、Image(意象)。意象是很关键的一类实体——像“月”“酒”“柳”“雁”这些高频意象,是连接不同诗作的重要桥梁。
关系类型设计上,我定义了五种:属于(作品→诗人)、处于(诗人→朝代)、描写(作品→意象)、同期(诗人→诗人,表示同朝代的联系)、化用(作品→作品,表示诗句间存在用典或化用关系)。其中“同期”和“化用”是答辩的亮点关系,因为在传统的翻页查诗系统里,这两个维度完全体现不出来。
5.2 Neo4j导入与Cypher查询实践
数据入库走Neo4j有两种方式:一种是用Neo4j的Cypher语句直接CREATE节点和关系,适合数据量小的情况;另一种是用neo4j-import工具或Python的py2neo库批量导入,适合数据量几万条以上的情况。
我推荐用py2neo写批量导入脚本,因为Django和Neo4j之间需要一个桥梁层管理连接池。核心代码大致长这样:
from py2neo import Graph, Node, Relationship graph = Graph("bolt://localhost:7687", auth=("neo4j", "password")) # 批量创建诗人节点 for poet in poets: node = Node("Poet", name=poet["name"], dynasty=poet["dynasty"]) graph.create(node) # 创建作品节点并与诗人建立关联 for poetry in poetries: poet_node = graph.nodes.match("Poet", name=poetry["poet"]).first() poetry_node = Node("Poetry", title=poetry["title"], content=poetry["content"]) rel = Relationship(poetry_node, "属于", poet_node) graph.create(rel)批量导入时注意一个性能问题:每创建一条关系就调用一次graph.create,会非常慢。两万条数据需要十几分钟,后来我改用graph.begin()开启事务,批量提交,速度提升了近10倍。
查询层接口用Cypher写成函数,Django视图层调用。典型查询比如“找李白的代表作并返回关联意象”:
MATCH (p:Poet {name: '李白'})-[:属于]-(poem:Poetry)-[:描写]->(image:Image) RETURN poem.title, image.name LIMIT 20这个查询结果会直接提供给前端图谱可视化。注意图谱查询接口要设置超时时间,防止遍历复杂度太高时页面卡死。对于毕设级别数据量(几千到两万),Neo4j的响应时间通常都能控制在几百毫秒内。
5.3 图谱在推荐系统里的两种玩法
图谱不能只躺在数据库里,要真正发挥作用。我在推荐模块里用了两种玩法:
第一种是基于图谱路径的关联推荐。当用户查看一首诗时,程序查找和当前作品共享至少一个意象的其他作品,再按照共享意象数量排序。这种推荐叫“意象共鸣推荐”,实验结果里点击率明显高于基于作者的简单关联。
第二种是基于多跳关系发现隐性关联。比如用户看一首诗,图谱查询发现该诗的作者曾经和另一位诗人有“同期”关系,那么这位同期诗人的代表作就会被推荐出来。这种“二度关联”效果很好——用户会觉得系统非常“懂”,因为推荐结果里往往有他完全没听说过但确实有文化关联的作品。
这里有个注意事项:图谱查询遍历深度不建议超过三跳,否则会造成响应延迟,而且推荐结果相关度会急剧下降。我在实际调试中就遇到过查询四跳关系时,Neo4j返回了一大堆弱相关数据,前端图谱乱成一团,后来把查询限制到三层,效果立刻好了很多。
6. 推荐系统设计:当大模型语义向量遇上图谱关联
6.1 传统推荐在古诗词场景里的局限
如果直接用协同过滤做古诗词推荐会遇到两个典型问题。第一个是数据稀疏——用户收藏和评分行为很少,尤其是毕设系统刚上线时几乎没什么用户行为数据,推荐列表全是默认值,相当于没做个性化。第二个是文本相似度不等于精神相似——两首词表面用词高度重合,但一首写相思一首写壮志,传统TF-IDF计算会把它们打成“高度相似”,推荐结果就很离谱。
因为这两层原因,我为这套系统设计了三路并行推荐融合方案:行为协同过滤、图谱关联推荐、大模型语义推荐。协同过滤管“喜欢相似诗的人还喜欢什么”,图谱管“和当前诗有文化关联的作品”,大模型语义推荐管“表达意境接近的作品”。
6.2 大模型语义向量与混合推荐融合逻辑
大模型语义推荐的做法是调用DeepSeek的Embedding能力,将每首诗的正文转换成语义向量,存入数据库后,推荐时计算查询向量与库内向量的余弦相似度,返回Top N。
这里要注意,古诗词文本太长时直接Embedding效果会稀释关键信息。我做了个实验:全诗直接向量化,和“取前四句+核心意向词组合”再向量化,语义推荐效果的准确率差了将近10%。所以在预处理阶段,我做了一个TextRank关键词抽取,把诗的核心内容浓缩成几个关键词组合,再送给Embedding,效果要好得多。
融合推荐时,我给三路结果分配权重:行为协同过滤权重0.3,图谱关联权重0.3,大模型语义权重0.4。因为系统初期行为数据太少,大模型语义应该作为主要驱动力。等用户行为多了,再通过简单的加权滑动调整,让行为权重大一些。
融合完成后,还要做一步去重和重排。比如同一个诗人的代表作品出现了很多次,直接展示就显得单调,需要按作者多样性做一下分散。这一步我没用太复杂的MMR算法,直接用简单的“同作者最多保留两首”规则解决。
6.3 冷启动与个性化探索的取舍
毕设答辩时,导师很可能会追问:“用户行为数据这么少,你的协同过滤怎么冷启动?”
我的回答思路是:在系统冷启动阶段,推荐主逻辑完全依赖图谱关联和大模型语义推荐,协同过滤只做辅助。用户登录后首次访问首页,系统会推荐“情感倾向偏思乡和壮志的经典作品”——这由用户注册时的偏好选择决定。用户有任何浏览或收藏行为后,推荐结果实时调整。
为了让个性化有真实感,我还在系统里加了一个“探索”机制:推荐列表里固定有20%的作品来源于低热度作品,从长尾里选。这个设计在展示时很有看头——推荐结果里有冷门但有价值的作品,会让人感觉系统“有品位”,而不是只推人人都知道的名篇。
7. Django后端集成:业务表设计、API接口与批量调用框架
7.1 用户行为表模型与防重设计
用户行为是整个推荐模块的数据燃料。我在Django里设计了一套行为记录机制,涵盖浏览和收藏两类行为。设计时我特别强调了一个字段:行为权重。一首诗被用户打开详情页,计1分;被收藏,计5分;在推荐结果里直接点击,额外加2分。这个权重直接影响推荐排序,表结构里必须有score字段。
还有一点,防重逻辑一定要做。用户短时间内反复刷新同一首诗,不应该产生大量重复记录。我用“用户ID+诗词ID+行为类型+日期”做唯一约束,每天每种行为只计一次,既避免脏数据,也减少调用压力。
7.2 核心API接口设计
后端需要提供的核心接口大概有七组:
- 诗词检索接口
/api/poetry/search?keyword=&dynasty=&sentiment= - 详情接口
/api/poetry/{id}返回诗词原文、注释、赏析、情感分析结果 - 推荐接口
/api/recommend/{user_id}?limit=20 - 图谱接口
/api/graph/{poetry_id}返回以该诗为核心的关联图谱数据 - 情感统计接口
/api/analytics/emotion_overview用于可视化大屏 - 诗人画像接口
/api/poet/{id}/profile返回该诗人的创作风格和情感分布 - 用户行为上报接口
/api/user/behavior接收浏览收藏数据
每个接口都用Django Rest Framework实现,序列化器统一处理输出格式。这里有个经验:图谱接口的返回数据量要控制,一次性把所有关联节点下发给前端,会导致页面渲染卡顿,建议服务端先返回首层关联,前端展示后再按需请求第二层。
7.3 批量调用DeepSeek的事务管理与失败重试
毕设系统不像企业级应用有完善的异步消息队列,所以在批量调用大模型时需要自己实现一套简化版的失败补偿机制。
我的做法是写一个调用服务类,内部维护待分析队列,每个任务有状态字段:pending、success、failed。批处理脚本启动时扫描所有pending和failed的任务,执行调用,成功后更新状态,失败则记录错误原因并重试,连续失败三次则标记为dead。这套机制实现简单,但保护效果非常明显——我批量分析两万首诗词时,最终只有约1%的数据因为文本异常无法分析,其余全部入库。
还有一点需要提前设计好:模型接口的API Key管理。毕业设计代码会被打包发给别人,密钥硬编码在里面等于泄露。我建议把密钥放在独立的配置文件中,通过环境变量读取,提交代码时把配置文件加入.gitignore。这个细节在论文“系统安全性”一节能加分。
8. 可视化大屏与前端交互:让数据自己讲故事
8.1 核心图表选型:从诗词情感分布到诗人关联关系
可视化是毕设答辩中“吸睛值”最高的部分,所以我花了不少精力选图表类型。整套可视化分为三张大屏:全局总览、诗人画像、作品详情。
全局总览里放五类图表:
第一张是朝代—诗词数量堆叠柱状图,按朝代展示不同情感类别的诗词数量占比。这张图用ECharts的堆叠柱状图实现,在答辩时可以直观看出唐诗中“壮志”情感显著高于其他朝代。
第二张是情感倾向雷达图,把全部诗词按七个情感类别统计占比,画成雷达图。因为七个维度其实可以压缩成四个主要维度,雷达图显得很紧凑。
第三张是热门意象气泡图,统计高频意象在全部诗词中的出现次数,用散点气泡图展示,气泡大小代表频次,横纵坐标可以设计为诗人数量和朝代分布。
第四张是诗人作品量排行横向条形图,展示前十位诗人及其作品数量。这里有讲究:查询结果要按量倒序,但前端展示可以做成“试一下”的交互效果,点击柱条进入对应诗人的画像页。
第五张是核心关系图谱力导向图,展示指定诗人或作品的关系网络。用的还是ECharts的graph类型,数据来自Neo4j接口返回的实体关系三元组。
8.2 前端交互设计:点击节点下钻,让图谱“活”起来
图谱光画出来是没有生命力的,一定要能交互。我的设计是:页面加载时展示以当前作品为核心的一跳关系网络;用户点击任意诗人节点,前端向图谱接口发送二次请求,返回该诗人的更多关联作品,动态扩展图谱;用户点击任意作品节点,右侧浮层展示该作品的核心信息和情感分析结果。
这个交互逻辑要注意两点:一是请求要防抖,避免用户连续点击时产生大量并发请求;二是图谱在扩展时,要注意新旧节点去重,否则同一个诗人节点会在画布上出现两次——这个问题我当时调试了很久,最后用节点的唯一ID做合并才解决。
8.3 答辩演示环境的可视化注意事项
可视化在答辩演示时的效果和开发环境里差别很大,我曾见过不少同学在实验室里调试的图表五颜六色,一到投影仪上就变成一团模糊。所以有几个细节一定提前处理好:
第一,图表配色使用高对比度方案,避免浅色底配浅色系,投影仪上一片白茫茫。第二,字体大小要上调,小标题不小于16像素,数据标注不小于14像素,否则后排评委看不清。第三,准备好离线模式下的静态快照,万一答辩现场网络不稳定,大模型接口挂了可视化也要能跑——从数据库里读缓存数据就可以。这三条是我几次答辩观看下来总结出来的血泪经验。
9. 项目展示与答辩材料配合:代码之外,如何让工作量被看见
9.1 开题报告与中期检查的“工作量呈现”技巧
很多同学技术做完了,但开题报告写得像流水账,中期检查被导师批“没有进展”。根据我审过多次类似项目的经验,在材料里强调三件事就够了:
一是数据规模,比如“共清洗入库古诗两万余首,覆盖隋唐宋元明清等多个朝代,构建诗人实体约八百位”。二是技术链条,重点写清楚“数据预处理→大模型增强→知识图谱构建→多路推荐融合→可视化呈现”的完整链路。三是实验对比,把词典基线、传统推荐、大模型方案做效果对比。这些内容放到开题报告的“研究内容与技术路线”一节,显示度立刻不一样。
9.2 答辩PPT的高效内容结构
答辩PPT不需要把代码贴进去,更不需要把每一个接口讲一遍,重点是四个部分:
第一,研究背景与意义:用数据说明古诗词数字化的现状。第二,系统核心功能演示:现场演示搜索、详情、推荐、图谱、可视化,每项控制在30秒内。第三,技术难点与创新点:突出DeepSeek的情感分析结果、图谱关联推荐、三路融合方案、可视化大屏四个亮点。第四,实验与效果:展示数据分析对比图。
PPT页数控制在15-18页,讲解时间控制在8-10分钟,留5分钟给评委提问。我见过很多同学PPT做了四五十页,结果前20页都在讲SSM框架、B/S架构,评委早就走神了。演示环节永远比PPT重要,开场直接把图谱可视化跑起来,是最抓眼球的做法。
9.3 演示环境准备的最后清单
临到答辩前一天,我建议你按这个清单检查环境:
- Django服务能否在演示笔记本本地启动,不要依赖实验室服务器
- 有没有启动Neo4j数据库,URL和密码是否正确
- 前端页面使用的CDN资源是否打包到本地,或者预下载了离线版本
- DeepSeek的API Key是否配置好,剩余调用额度是否足够
- 预先准备20首常见诗词的演示数据,确保搜索和推荐结果能精准命中
- 把系统要演示的页面提前都开着,并随手准备一份手动输入的情感分析测试数据,防止网络接口临时抽风
这六项里最容易掉链子的是CDN资源——实验室网络一波动,ECharts图表就白屏。把所有静态资源下载到本地static目录,是最稳妥的方案。
10. 开发过程中的高频“坑”:我用自己的踩坑经验给你排雷
10.1 文本编码与数据处理层的问题
古诗词数据最容易出问题的是编码。从GitHub下载的数据集很可能是UTF-8和GBK混合编码,直接读取Pandas会报错,处理办法是用encoding="utf-8", errors="ignore"做兜底。更隐蔽的问题是半角和全角标点混用,会导致关键词检索时明明有结果但搜索为空,我最后统一做了半全角转换才解决。
还有一处非常影响推荐质量:停用词表。古诗词里的“之”“乎”“者”“也”很容易被当成正常词处理,我构建意象提取时先过滤了这轮停用词,再考虑“月”“杨柳”“孤舟”这类真正的意象词。如果没做这一步,知识图谱里的意象实体会被高频虚词污染,整个图谱的可解释性大打折扣。
10.2 DeepSeek接口调用的异常处理
我在批量调用时遇到的反馈异常,给我留下了两个深刻的教训。第一个是调用超时和限流问题:批量任务跑久了,接口会开始报错或响应变慢。不能只靠重试解决,必须加上指数退避——每失败一次,下次等待时间翻倍,最大等待两分钟。直接连续快速重试反而会让限流更严重。
第二个是Prompt注入风险。这不只是被动防御,我在测试集里发现有些诗词文本包含异常内容,可能导致模型输出格式混乱。所以调用前我先做一轮文本清理——移除控制字符、特殊符号、超长内容,再放入Prompt。这套预处理流程能显著减少格式异常的返回结果。
10.3 前端图谱渲染的性能优化
ECharts的graph类型在大数据量下很容易卡顿。两千个节点时,拖拽和缩放就开始掉帧;五千节点时,页面基本没法操作。我的优化方案是分层加载:首层只渲染与当前作品直接关联的节点,控制在50个以内;用户展开节点时,每次最多追加20个新节点。这样交互流畅度可以稳定在30帧以上。
另一个小坑是中文节点标签的显示宽度。诗人名和作品名长短不一,ECharts默认标签可能互相遮挡,需要设置标签的formatter函数控制显示长度,超长用省略号。这些小细节做得好不好,直接影响答辩时评委的第一观感。
10.4 缓存策略与数据一致性
系统里热度最高的接口(比如首页推荐)每次计算都是全库扫描加模型调用,如果不做缓存,用户体验会很差。我的做法是给推荐接口加了一层简单缓存,缓存有效期设计为5分钟,用户行为更新后再主动失效对应缓存。图谱接口也做了同样的处理——因为Neo4j查询本身很快,但组装JSON给前端仍然有开销,缓存能省掉这部分重复计算。
但要注意一个一致性陷阱:用户在收藏一首诗后,立刻刷新首页,推荐应该发生变化。如果你只做了5分钟缓存,用户会看到推荐没变,导致怀疑系统“假推荐”。所以我额外做了行为触发式的缓存更新——用户发生收藏行为时,主动删除该用户的推荐缓存,下次请求实时计算。这种做法在数据量小、用户量少的毕设场景里非常实用,不需要引入Redis,Django的cache框架就能完成。
11. 最后的个人体验与一些建议
整套系统从数据清洗、模型调用、图谱构建到可视化呈现,差不多需要六到八周的全职时间,其中数据处理和异常调试占掉的比重往往被严重低估。
我个人的体会是,这个题目真正的价值不在于某一个技术点用得有多深,而在于你把大模型、知识图谱、推荐系统、可视化四个模块像一个真正的产品一样串在了一起。答辩评委看到的不只是“会调用模型接口”,而是你具备把多个异构技术整合进一个完整系统的工程能力——这种能力在就业市场上比单一框架熟练度更值钱。
如果你准备采用这个方案,我的最后一个建议是:无论时间多紧张,一定要留出一周专门做演示准备和讲解排练。代码写得再好,演示时慌乱、图谱打不开、推荐结果不相关,都是非常吃亏的。提前把演示路径固定好——从搜索一首熟悉的诗开始,展开图谱,展示情感分析结果,切换到可视化大屏,演示推荐列表,每一步控制在几十秒内,反复走三遍以上。答辩这种事,充分准备和临场发挥的差距,往往比努力本身还大。