Python网络小说分析系统:从数据采集到推荐算法的毕业设计实践 1. 先搞清楚这个项目到底要做什么以及它适合谁如果你正在找计算机专业的毕业设计选题或者想做一个能体现数据分析、推荐算法和Web开发综合能力的项目这个“Python网络小说分析系统”是个不错的选择。它不是一个简单的增删改查系统而是把数据采集、算法应用、可视化展示串联起来的完整流程。这个项目最核心的价值在于它让你有机会在一个项目里把学校里学的几门课——比如Python编程、数据库、Web开发、机器学习——真正串起来用一遍。很多人做毕业设计容易陷入两个极端要么是纯理论算法没有界面和实际数据要么是纯管理后台没有算法深度。这个选题恰好能避开这两个坑。它适合几类人计算机、软件工程、数据科学相关专业的本科生需要一个有技术深度、能写进简历的毕业设计。想转行数据分析或后端开发的自学者通过一个完整项目来巩固Django、爬虫、数据分析库和基础机器学习算法的应用。对推荐系统感兴趣但不知道如何落地的初学者可以通过这个项目了解从数据到模型再到推荐结果的全链路。整个系统的骨架很清晰用Python爬虫或公开数据集获取网络小说数据用Django搭建Web系统来管理数据和用户用协同过滤算法给用户推荐小说最后用ECharts之类的前端库把分析结果做成可视化图表或大屏。深度学习部分通常是加分项比如用文本分类模型给小说打标签或者用神经网络优化推荐模型。2. 环境与工具准备别在第一步就卡住在开始写代码之前先把环境理顺。很多同学项目跑不起来问题都出在环境配置和版本冲突上。我建议按以下顺序准备每一步都确认无误再往下走。2.1 基础编程环境Python版本这是最重要的。不要用太老的版本如Python 2.7也别盲目追最新版可能某些库还不兼容。Python 3.8 或 3.9是目前最稳妥的选择绝大多数库的兼容性都很好。包管理工具强烈建议使用pip配合virtualenv或conda创建独立的虚拟环境。这能避免把你系统全局的Python环境搞乱。# 使用 virtualenv 的示例 python -m venv novel_analysis_env # 创建虚拟环境 # Windows 激活 novel_analysis_env\Scripts\activate # Linux/Mac 激活 source novel_analysis_env/bin/activate # 激活后安装核心包 pip install django4.2 # 指定一个稳定的Django版本代码编辑器VS Code 或 PyCharm 都可以。VS Code需要配置Python扩展PyCharm开箱即用。关键是熟悉调试和运行Django项目的操作。2.2 核心依赖库清单根据项目标题我们需要以下几类库。安装时注意版本兼容可以先用默认版本出问题再调整。1. Web框架与数据库Django: Web框架主体。mysqlclient或pymysql: 连接MySQL数据库如果不用SQLite的话。django-crispy-forms(可选): 让表单渲染更美观。2. 数据处理与分析pandas: 数据清洗、分析和处理的绝对核心。numpy: 数值计算基础pandas的依赖。jupyter(可选): 用于在浏览器里交互式地探索数据和调试分析代码非常方便。3. 数据可视化matplotlib: 基础绘图库生成静态图表。seaborn: 基于matplotlib统计图表更美观。pyecharts或echarts-for-python: 将ECharts的强大可视化能力集成到Python后端用于生成大屏所需的复杂图表。这是实现“大屏”效果的关键。4. 机器学习与推荐算法scikit-learn: 机器学习基础库里面包含了计算相似度的工具是实现协同过滤的基石。surprise(可选): 一个专注于推荐系统的Python库内置了多种协同过滤算法可以直接调用适合快速原型开发。gensim(可选): 如果涉及小说文本分析如主题提取会用到它。5. 深度学习如果标题中的“深度学习”是重点tensorflow或pytorch: 深度学习框架二选一。新手可以从TensorFlow 2.x开始它的Keras API更易上手。scikit-learn同样用于数据预处理。安装命令示例# 在激活的虚拟环境中一次性安装深度学习库较大可后续按需安装 pip install django pandas numpy matplotlib seaborn scikit-learn # 安装echarts支持 pip install pyecharts2.3 项目结构规划在开始django-admin startproject之前先想好目录结构。一个清晰的结构能让你后期开发事半功倍。novel_analysis_system/ # 项目根目录 ├── data/ # 存放原始数据、清洗后的数据、训练好的模型文件 │ ├── raw/ # 爬取的原始数据 │ ├── processed/ # 清洗后的数据 │ └── models/ # 保存训练好的协同过滤模型或深度学习模型 ├── novel_analysis/ # Django项目主目录 (startproject 生成) │ ├── __init__.py │ ├── settings.py # 配置文件数据库、静态文件等设置在这里 │ ├── urls.py # 项目总路由 │ └── wsgi.py ├── apps/ # 建议创建apps目录存放所有Django应用 │ ├── novel/ # 小说信息管理应用 │ │ ├── migrations/ │ │ ├── models.py # 定义小说、作者、类别等模型 │ │ ├── views.py # 处理小说列表、详情等请求 │ │ └── ... │ ├── user/ # 用户管理应用 │ │ ├── models.py # 定义用户模型可扩展Django自带User │ │ └── ... │ ├── recommendation/ # 推荐算法核心应用 │ │ ├── algorithms/ # 存放协同过滤等算法的Python脚本 │ │ ├── utils/ # 存放数据加载、模型保存等工具函数 │ │ └── views.py # 处理推荐请求的视图 │ └── visualization/ # 数据可视化应用 │ ├── views.py # 处理图表数据接口的视图 │ └── ... ├── static/ # 静态文件CSS, JS, 图片 ├── templates/ # 全局HTML模板 ├── manage.py └── requirements.txt # 项目依赖包列表这个结构的关键是把不同功能的代码模块化。recommendation和visualization作为独立app与核心业务novel和user解耦以后维护和扩展都方便。3. 数据从哪里来爬虫与数据清洗实战没有数据一切分析和推荐都是空谈。对于网络小说系统数据源是关键。3.1 数据获取方案选择方案一使用公开数据集最稳妥这是毕业设计的首选避免法律风险和爬虫技术门槛。可以去Kaggle、天池、以及一些科研机构的数据网站寻找“Book-Crossing”、“Goodbooks-10k”等图书评分数据集。虽然主题不是“网络小说”但数据结构和我们的需求用户-物品-评分完全一致你可以把“书籍”映射为“小说”。这能让你快速进入算法和系统开发阶段。方案二编写Python爬虫技术加分项如果决定爬虫务必遵守robots.txt控制请求频率并只用于学习研究。目标网站可以选择一些提供公开API或页面结构清晰的小说网站。爬虫核心步骤分析页面使用浏览器开发者工具F12查看小说列表页、详情页的HTML结构找到小说标题、作者、简介、分类、标签等信息的HTML标签和属性。请求与解析使用requests库发送HTTP请求获取网页用BeautifulSoup或lxml解析HTML提取所需数据。数据存储先将数据保存为CSV或JSON文件例如novels_raw.csv。应对反爬可能需要设置User-Agent、使用time.sleep()延时、处理Cookie甚至使用Selenium模拟浏览器动态网页。# 一个非常简化的爬虫示例框架 import requests from bs4 import BeautifulSoup import pandas as pd import time def scrape_novel_list(base_url, pages5): all_novels [] for page in range(1, pages1): url f{base_url}?page{page} headers {User-Agent: 你的浏览器User-Agent} try: resp requests.get(url, headersheaders, timeout10) resp.raise_for_status() # 检查请求是否成功 soup BeautifulSoup(resp.text, html.parser) # 根据实际页面结构解析这里是假设 novel_items soup.find_all(div, class_novel-item) for item in novel_items: novel { title: item.find(h2).text.strip(), author: item.find(span, class_author).text.strip(), category: item.find(a, class_category).text.strip(), # ... 其他字段 } all_novels.append(novel) time.sleep(1) # 礼貌延时避免对服务器造成压力 except Exception as e: print(f爬取第{page}页失败: {e}) continue return pd.DataFrame(all_novels) # 使用 # df_raw scrape_novel_list(https://example.com/novels) # df_raw.to_csv(data/raw/novels_raw.csv, indexFalse, encodingutf-8-sig)3.2 数据清洗与入库爬下来的原始数据通常很脏直接用来分析或训练模型效果会很差。清洗是必不可少的一步。常见清洗任务处理缺失值作者信息缺失是填充“未知”还是删除这条记录格式标准化分类标签可能有“玄幻”、“玄幻小说”、“奇幻”需要统一为“玄幻”。文本处理简介里的多余空格、特殊字符、HTML标签需要去除。去重根据小说标题和作者判断是否重复。构造评分数据如果你没有真实的用户-小说评分数据这是毕业设计最大的挑战。一个可行的办法是模拟生成。根据小说的热门程度假设爬取了点击量或收藏数、类别为模拟的用户生成评分。虽然不真实但足以演示协同过滤算法的工作流程。使用Pandas进行清洗import pandas as pd # 1. 加载数据 df pd.read_csv(data/raw/novels_raw.csv) # 2. 查看基本信息 print(df.info()) # 查看列类型和缺失值 print(df.head()) # 3. 处理缺失值 - 以作者为例 df[author].fillna(未知, inplaceTrue) # 4. 分类标准化 - 假设有个分类映射字典 category_map {玄幻小说: 玄幻, 奇幻文学: 奇幻, 武侠经典: 武侠} df[category] df[category].replace(category_map) # 5. 文本清洗 - 清理简介 import re def clean_text(text): if pd.isna(text): return # 去除HTML标签 text re.sub(r[^], , text) # 去除多余空白字符 text .join(text.split()) return text df[introduction] df[introduction].apply(clean_text) # 6. 去重 df.drop_duplicates(subset[title, author], keepfirst, inplaceTrue) # 7. 保存清洗后的数据 df.to_csv(data/processed/novels_clean.csv, indexFalse, encodingutf-8-sig) print(f清洗完成剩余{len(df)}条数据。)数据入库清洗完成后编写Django的models.py然后使用python manage.py makemigrations和python manage.py migrate创建数据库表。最后写一个脚本读取novels_clean.csv创建Novel模型实例并保存到数据库。这一步将静态数据变成了Django可以动态管理的数据。4. 协同过滤推荐算法从理论到Django集成这是项目的算法核心。协同过滤Collaborative Filtering基本思想是“物以类聚人以群分”。它分为两类基于用户的协同过滤User-CF找到和你兴趣相似的用户把他们喜欢而你没看过的小说推荐给你。基于物品的协同过滤Item-CF找到和你喜欢的小说相似的其他小说直接推荐给你。对于小说推荐基于物品的协同过滤Item-CF通常更稳定、更常用因为小说的相似性比如同作者、同类别、同标签比用户的相似性更容易衡量且不会因为用户数量增长而剧烈变化。4.1 算法原理与实现步骤我们以实现Item-CF为例拆解其步骤构建用户-物品评分矩阵矩阵的行是用户列是小说值是评分如1-5分。我们的模拟数据或小型数据集可以构造这个矩阵。计算物品相似度计算每两本小说之间的相似度。最常用的方法是余弦相似度或皮尔逊相关系数。这里可以简单理解为如果两个小说被很多用户同时打了高分它们就越相似。生成推荐对于目标用户找出他评分过的小说然后找到与这些小说最相似的其他小说根据相似度加权排序剔除已看过的生成推荐列表。使用scikit-learn实现一个简化的Item-CF# recommendation/algorithms/item_cf.py import pandas as pd import numpy as np from sklearn.metrics.pairwise import cosine_similarity from scipy.sparse import csr_matrix class ItemCFRecommender: def __init__(self): self.item_sim_matrix None # 物品相似度矩阵 self.items None # 物品列表 self.user_item_matrix None # 用户-物品矩阵 def fit(self, ratings_df): 训练模型 :param ratings_df: DataFrame包含user_id, item_id, rating三列 # 创建用户-物品评分矩阵稀疏矩阵节省内存 user_item ratings_df.pivot(indexuser_id, columnsitem_id, valuesrating).fillna(0) self.user_item_matrix csr_matrix(user_item.values) self.items user_item.columns.tolist() self.user_ids user_item.index.tolist() # 计算物品相似度矩阵 (物品数 x 物品数) # 这里使用余弦相似度计算的是物品向量所有用户对它的评分之间的相似度 self.item_sim_matrix cosine_similarity(self.user_item_matrix.T) # .T 进行转置行变物品 def recommend(self, user_id, top_n10): 给指定用户推荐物品 :param user_id: 用户ID :param top_n: 推荐数量 :return: 推荐的物品ID列表 try: user_idx self.user_ids.index(user_id) except ValueError: print(f用户 {user_id} 不在训练集中。) return [] # 获取该用户的评分向量 user_ratings self.user_item_matrix[user_idx].toarray().flatten() # 找出用户已评分的物品索引 rated_item_indices np.where(user_ratings 0)[0] if len(rated_item_indices) 0: # 用户没有历史行为可以返回热门物品或随机物品 return self._recommend_popular(top_n) # 初始化预测评分 pred_scores np.zeros(len(self.items)) for item_idx in rated_item_indices: # 用户对这个物品的评分 rating user_ratings[item_idx] # 这个物品与其他所有物品的相似度 similarities self.item_sim_matrix[item_idx] # 累加相似度 * 评分 pred_scores similarities * rating # 将用户已经评分的物品预测分设为负无穷确保不会被推荐 pred_scores[rated_item_indices] -np.inf # 获取top_n的索引 top_indices np.argsort(pred_scores)[::-1][:top_n] recommended_item_ids [self.items[i] for i in top_indices if pred_scores[i] -np.inf] return recommended_item_ids[:top_n] def _recommend_popular(self, top_n): 冷启动推荐返回评分次数最多的物品 item_rating_counts np.asarray(self.user_item_matrix.sum(axis0)).flatten() top_indices np.argsort(item_rating_counts)[::-1][:top_n] return [self.items[i] for i in top_indices] # 假设我们有一个评分DataFrame # ratings_data { # user_id: [1,1,1,2,2,3,3,3], # item_id: [101,102,103,101,104,102,103,105], # rating: [5,3,4,4,2,5,5,4] # } # ratings_df pd.DataFrame(ratings_data) # recommender ItemCFRecommender() # recommender.fit(ratings_df) # print(recommender.recommend(user_id1, top_n2))4.2 将算法集成到Django中算法不能孤立存在需要和Django的Web部分打通。通常有两种集成方式方式一实时计算适合数据量小、用户少每次用户请求推荐时都调用上面的recommend方法。这简单直接但用户或物品多了以后计算相似度矩阵会很慢。方式二离线计算 缓存推荐用于毕业设计这是更实用的方式。流程如下离线训练写一个Django管理命令python manage.py train_cf_model定期比如每天用全部评分数据训练一次Item-CF模型计算好物品相似度矩阵。模型存储将训练好的模型self.item_sim_matrix,self.items,self.user_ids使用pickle或joblib库保存到data/models/目录下。import joblib joblib.dump(recommender, data/models/item_cf_model.pkl)在线推荐在Django的视图View里加载预训练好的模型。当用户访问推荐页面时视图调用模型的recommend方法这步很快因为只是查表计算。# recommendation/views.py import joblib from django.shortcuts import render from django.contrib.auth.decorators import login_required # 全局加载模型注意在生产环境要考虑线程安全和模型更新 try: cf_model joblib.load(data/models/item_cf_model.pkl) except FileNotFoundError: cf_model None login_required def get_recommendation(request): user request.user # 假设你的用户模型有一个关联的ID字段或者直接用user.id user_id user.profile.external_user_id # 或者 user.id if cf_model is None: # 模型未训练返回热门推荐或提示 novels Novel.objects.order_by(-popularity)[:10] return render(request, recommendation.html, {novels: novels, source: popular}) # 获取推荐的小说ID列表 recommended_item_ids cf_model.recommend(user_iduser_id, top_n10) # 从数据库查询这些小说对象 recommended_novels Novel.objects.filter(id__inrecommended_item_ids) # 注意需要保持推荐顺序可以后续处理 return render(request, recommendation.html, {novels: recommended_novels, source: cf})关键点你需要建立Django的User模型和算法中user_id的映射关系。同时Novel模型的ID需要和算法中的item_id对应。通常直接用数据库自增主键ID就可以。5. 数据分析与可视化大屏搭建这是项目的“门面”让分析结果一目了然。数据分析用Pandas可视化用PyECharts生成图表通过Django视图提供数据接口前端用ECharts JS库渲染。5.1 数据分析从数据库到洞察首先在Django中你可以很方便地用ORM查询数据并转为Pandas DataFrame进行分析。# visualization/views.py 或一个单独的分析脚本 import pandas as pd from django.db import connection from apps.novel.models import Novel, Category def analyze_novel_data(): 执行数据分析返回用于可视化的数据字典 # 方法1使用Django ORM查询然后转为DataFrame适合数据量不大 novels_qs Novel.objects.all().values(id, title, author, category__name, word_count, popularity) df pd.DataFrame.from_records(novels_qs) # 方法2对于复杂聚合直接使用原始SQL查询更灵活高效 # with connection.cursor() as cursor: # cursor.execute(SELECT category_id, COUNT(*) as count FROM novel GROUP BY category_id) # rows cursor.fetchall() # df pd.DataFrame(rows, columns[category_id, count]) # 开始分析 analysis_results {} # 1. 小说数量按类别分布 if category__name in df.columns: category_dist df[category__name].value_counts().to_dict() analysis_results[category_distribution] { categories: list(category_dist.keys()), counts: list(category_dist.values()) } # 2. 作者产量Top10 if author in df.columns: top_authors df[author].value_counts().head(10) analysis_results[top_authors] { authors: top_authors.index.tolist(), counts: top_authors.values.tolist() } # 3. 字数与热度关系示例计算相关系数 if all(col in df.columns for col in [word_count, popularity]): # 过滤掉无效数据 df_valid df.dropna(subset[word_count, popularity]) if not df_valid.empty: correlation df_valid[word_count].corr(df_valid[popularity]) analysis_results[word_popularity_corr] round(correlation, 3) # 4. 热门小说Top10 (假设popularity是热度指标) if popularity in df.columns and title in df.columns: top_novels df.nlargest(10, popularity)[[title, popularity]] analysis_results[top_novels] { titles: top_novels[title].tolist(), popularity: top_novels[popularity].tolist() } return analysis_results5.2 使用PyECharts生成图表数据PyECharts允许你在Python端配置好图表的所有选项然后生成一个包含配置的字典或JSON传给前端。# visualization/utils/charts.py from pyecharts import options as opts from pyecharts.charts import Bar, Pie, Scatter, Line from pyecharts.commons.utils import JsCode def create_category_pie(data): 创建类别分布饼图 categories data[categories] counts data[counts] pie ( Pie() .add( series_name小说类别, data_pair[list(z) for z in zip(categories, counts)], radius[30%, 70%], # 环形图 label_optsopts.LabelOpts(formatter{b}: {c} ({d}%)), ) .set_global_opts( title_optsopts.TitleOpts(title小说类别分布, pos_leftcenter), legend_optsopts.LegendOpts(orientvertical, pos_top15%, pos_left2%), ) ) return pie.dump_options_with_quotes() # 返回图表配置JSON字符串 def create_top_authors_bar(data): 创建作者产量柱状图 authors data[authors] counts data[counts] bar ( Bar() .add_xaxis(authors) .add_yaxis(作品数量, counts, colorJsCode( new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: #83bff6 }, { offset: 0.5, color: #188df0 }, { offset: 1, color: #188df0 }]) )) .set_global_opts( title_optsopts.TitleOpts(title高产作者TOP10, pos_leftcenter), xaxis_optsopts.AxisOpts(axislabel_optsopts.LabelOpts(rotate-45)), # 标签旋转防重叠 datazoom_opts[opts.DataZoomOpts()], # 添加数据区域缩放 ) ) return bar.dump_options_with_quotes() def create_word_popularity_scatter(df): 创建字数-热度散点图 # 假设df是包含word_count和popularity的DataFrame scatter ( Scatter() .add_xaxis(df[word_count].tolist()) .add_yaxis( series_name小说, y_axisdf[popularity].tolist(), symbol_size10, label_optsopts.LabelOpts(is_showFalse), ) .set_global_opts( title_optsopts.TitleOpts(title小说字数与热度关系), xaxis_optsopts.AxisOpts(name字数万, type_value), yaxis_optsopts.AxisOpts(name热度, type_value), tooltip_optsopts.TooltipOpts(formatter{b}), ) ) return scatter.dump_options_with_quotes()5.3 Django视图与前端大屏集成在Django中创建视图提供图表数据接口并渲染包含ECharts的HTML页面。# visualization/views.py from django.shortcuts import render from .utils.charts import create_category_pie, create_top_authors_bar, create_word_popularity_scatter from .data_analysis import analyze_novel_data def data_dashboard(request): 数据可视化大屏页面 # 1. 获取分析数据 analysis_data analyze_novel_data() # 2. 生成各图表的配置选项JSON字符串 context { category_pie_options: create_category_pie(analysis_data[category_distribution]), top_authors_bar_options: create_top_authors_bar(analysis_data[top_authors]), # ... 其他图表选项 correlation: analysis_data.get(word_popularity_corr, N/A), top_novels: analysis_data.get(top_novels, {}) } return render(request, visualization/dashboard.html, context)对应的HTML模板dashboard.html中需要引入ECharts JS库并为每个图表准备一个DOM容器。!-- templates/visualization/dashboard.html -- !DOCTYPE html html head meta charsetutf-8 title网络小说数据分析大屏/title script srchttps://cdn.jsdelivr.net/npm/echarts5.4.3/dist/echarts.min.js/script style .dashboard-container { display: flex; flex-wrap: wrap; } .chart-box { width: 48%; height: 400px; margin: 1%; border: 1px solid #eee; } /style /head body h1 styletext-align: center;网络小说数据分析中心/h1 div classdashboard-container div idcategoryPie classchart-box/div div idtopAuthorsBar classchart-box/div !-- 更多图表容器 -- /div script typetext/javascript // 初始化图表 var categoryPieChart echarts.init(document.getElementById(categoryPie)); var topAuthorsBarChart echarts.init(document.getElementById(topAuthorsBar)); // 从Django模板变量中获取图表配置注意安全转义 var categoryPieOptions {{ category_pie_options|safe }}; var topAuthorsBarOptions {{ top_authors_bar_options|safe }}; // 设置图表配置 categoryPieChart.setOption(categoryPieOptions); topAuthorsBarChart.setOption(topAuthorsBarOptions); // 响应窗口大小变化 window.addEventListener(resize, function() { categoryPieChart.resize(); topAuthorsBarChart.resize(); }); /script /body /html这样一个包含数据分析与可视化大屏的模块就完成了。你可以根据需要添加更多图表类型如折线图展示热度趋势、词云图展示小说标签等。6. 深度学习模块的引入与模型训练如果想让项目更有深度“深度学习”部分可以作为一个独立的进阶模块。这里不要求你从头实现SOTA模型而是展示如何将深度学习流程集成到Django项目中。一个可行的方向是基于小说简介的文本分类或标签预测。6.1 任务定义与数据准备任务利用小说的简介文本自动预测其类别如玄幻、都市、科幻等。这是一个文本分类任务。步骤数据准备从数据库导出带有introduction简介和category类别的小说数据。文本预处理清洗文本去除停用词、标点、分词中文用jieba、构建词汇表。文本向量化将分词后的文本转换为模型能理解的数字向量。可以用简单的TF-IDF也可以用词嵌入Word2Vec, FastText或预训练模型BERT的特征。模型选择与训练对于入门可以使用scikit-learn的朴素贝叶斯、SVM或者用kerasTensorFlow后端搭建一个简单的LSTM或CNN文本分类模型。模型评估与保存在测试集上评估准确率保存训练好的模型。6.2 一个简单的深度学习文本分类示例使用Keras# deep_learning/train_text_classifier.py import pandas as pd import numpy as np import jieba from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout from tensorflow.keras.utils import to_categorical import joblib def load_and_preprocess_data(): 从数据库或CSV加载数据 # 假设有一个包含introduction和category的DataFrame df pd.read_csv(data/processed/novels_for_dl.csv) df df.dropna(subset[introduction, category]) texts df[introduction].astype(str).tolist() labels df[category].tolist() return texts, labels def train_model(): texts, labels load_and_preprocess_data() # 1. 标签编码 label_encoder LabelEncoder() encoded_labels label_encoder.fit_transform(labels) num_classes len(label_encoder.classes_) # 保存标签编码器预测时要用 joblib.dump(label_encoder, data/models/label_encoder.pkl) # 2. 文本分词和序列化 # 中文分词 texts_cut [ .join(jieba.cut(text)) for text in texts] tokenizer Tokenizer(num_words5000) # 只考虑前5000个常用词 tokenizer.fit_on_texts(texts_cut) sequences tokenizer.texts_to_sequences(texts_cut) # 保存tokenizer预测时要用 joblib.dump(tokenizer, data/models/text_tokenizer.pkl) # 统一序列长度 max_len 100 # 假设简介最大长度100个词 X pad_sequences(sequences, maxlenmax_len, paddingpost, truncatingpost) # 3. 划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split(X, encoded_labels, test_size0.2, random_state42) y_train_cat to_categorical(y_train, num_classesnum_classes) y_test_cat to_categorical(y_test, num_classesnum_classes) # 4. 构建模型一个简单的LSTM模型 vocab_size len(tokenizer.word_index) 1 embedding_dim 128 lstm_units 64 model Sequential() model.add(Embedding(input_dimvocab_size, output_dimembedding_dim, input_lengthmax_len)) model.add(LSTM(lstm_units, dropout0.2, recurrent_dropout0.2)) model.add(Dense(64, activationrelu)) model.add(Dropout(0.5)) model.add(Dense(num_classes, activationsoftmax)) model.compile(losscategorical_crossentropy, optimizeradam, metrics[accuracy]) model.summary() # 5. 训练模型 history model.fit(X_train, y_train_cat, epochs10, batch_size32, validation_data(X_test, y_test_cat), verbose1) # 6. 评估模型 loss, accuracy model.evaluate(X_test, y_test_cat, verbose0) print(f测试集准确率: {accuracy:.4f}) # 7. 保存模型 model.save(data/models/text_classifier_lstm.h5) print(模型训练完成并已保存。) if __name__ __main__: train_model()6.3 在Django中调用深度学习模型训练好模型后可以在Django中创建一个API或视图接收一段新的小说简介预测其类别。# deep_learning/views.py from django.http import JsonResponse from tensorflow.keras.models import load_model import joblib import jieba import numpy as np from tensorflow.keras.preprocessing.sequence import pad_sequences # 加载预训练的模型和工具可以放在视图外避免每次请求都加载 try: dl_model load_model(data/models/text_classifier_lstm.h5) tokenizer joblib.load(data/models/text_tokenizer.pkl) label_encoder joblib.load(data/models/label_encoder.pkl) MAX_LEN 100 except Exception as e: print(f加载深度学习模型失败: {e}) dl_model None def predict_category(request): if request.method POST: introduction request.POST.get(introduction, ) if not introduction or dl_model is None: return JsonResponse({error: 无效输入或模型未就绪}, status400) # 预处理输入文本 words .join(jieba.cut(introduction)) sequence tokenizer.texts_to_sequences([words]) padded_seq pad_sequences(sequence, maxlenMAX_LEN, paddingpost, truncatingpost) # 预测 prediction dl_model.predict(padded_seq, verbose0) predicted_class_idx np.argmax(prediction, axis1)[0] predicted_category label_encoder.inverse_transform([predicted_class_idx])[0] confidence float(prediction[0][predicted_class_idx]) return JsonResponse({ predicted_category: predicted_category, confidence: confidence }) else: return JsonResponse({error: 仅支持POST请求}, status405)将这个视图添加到Django的URL配置中前端就可以通过Ajax调用实现一个“智能分类”的演示功能。7. 项目优化、部署与答辩准备把功能做出来只是第一步让项目更完整、更健壮才能在答辩时获得高分。7.1 系统优化点推荐算法优化冷启动问题对于新用户或新小说协同过滤无法工作。可以结合热门推荐、基于内容的推荐利用小说类别、作者、标签作为补充。实时性离线计算的模型无法反映用户最新兴趣。可以设计一个简单的在线学习模块将用户最近的点击/评分行为快速融入到推荐中例如使用增量更新或混合推荐。多样性避免推荐结果过于同质化。可以在排序时在相似度得分中引入类别、作者等多样性因子。系统性能优化数据库查询对频繁访问的列表页如小说列表、推荐列表使用Django的select_related或prefetch_related来减少数据库查询次数。缓存使用Django的缓存框架将首页、热门推荐、分类分布等不常变化的数据缓存起来如使用Redis或Memcached。异步任务模型训练、数据爬取等耗时任务可以使用Celery结合Redis做成异步任务避免阻塞Web请求。前端体验优化大屏自适应使用ECharts的resize方法让图表适应不同屏幕大小。加载动画在图表数据加载时显示加载动画提升用户体验。交互式图表为图表添加点击事件例如点击某个作者柱状图下方显示该作者的详细作品列表。7.2 基础部署演示毕业设计通常不需要上线公网但能在本地或局域网内稳定运行是基本要求。演示部署可以很简单收集依赖生成requirements.txt文件。pip freeze requirements.txt配置生产设置在settings.py中设置DEBUG False配置ALLOWED_HOSTS例如[127.0.0.1, localhost]并配置静态文件收集。使用生产级WSGI服务器不使用Django自带的runserver。使用GunicornLinux/Mac或WaitressWindows来运行Django应用。# 安装gunicorn pip install gunicorn # 在项目根目录运行 gunicorn novel_analysis.wsgi:application -b 0.0.0.0:8000 -w 4前端代理可选如果需要更专业的演示可以用Nginx做反向代理处理静态文件并将动态请求转发给Gunicorn。7.3 答辩准备要点答辩时老师关注的是你的思路、实现和解决问题的能力而不是一个无懈可击的商业系统。讲清楚脉络按照“数据从哪来 - 怎么存 - 怎么分析 - 怎么推荐 - 怎么展示”的逻辑来介绍。突出重点详细讲解1-2个技术难点比如协同过滤算法的原理和你的实现方式或者深度学习文本分类的流程。演示核心功能现场演示数据大屏的图表联动、用户登录后的个性化推荐、以及智能分类的预测功能。诚实面对不足如果某些部分效果一般比如推荐准确率不高要分析原因数据量小、特征简单并提出可能的改进方向引入更多用户行为、使用更复杂的模型。展示代码和文档确保代码结构清晰有必要的注释。准备一份简洁的README.md说明如何安装和运行你的项目。最后也是最重要的在你开始编码之前先用纸笔或思维导图把整个系统的数据流、功能模块、技术选型画出来。想清楚每个部分怎么连接数据库表怎么设计。前期设计多花一小时后期开发能省下一天。这个项目涉及面广但只要你拆解清楚一步步实现完全有能力把它做出来并且成为一个非常出彩的毕业设计。