
简介这份资源面向教育研究者、作文教学从业者及文本分析学习者提供一套针对leleketangcom在线作文平台十万余条作文数据的完整分析项目。项目围绕主题分布、语言风格、写作技巧等维度展开文本挖掘并借助图表与图谱完成可视化呈现帮助理解学生写作的整体趋势与偏好。压缩包共59个文件约20.99MB包含8个Python脚本、8个CSV数据文件、8张PNG图表、7个HTML页面、13个TXT说明及IPYNB笔记本、PDF报告等覆盖爬虫代码、统计分析与应用代码、数据集与说明文档目录结构清晰便于按模块复现分析流程。已有47人学习下载。读者可从中获得从数据采集、文本处理到可视化展示的完整方案并参考报告与代码理解分析思路为作文教学改进、个性化写作指导及在线教育量化研究提供数据支持与案例借鉴。1. 十万条作文数据能挖出什么从 leleketangcom 数据集说起如果你手里正好有一份十万量级的作文数据集第一反应大概率是“先跑个词云看看”。但真做过文本挖掘的人都知道词云除了好看几乎不解决任何问题。leleketangcom 这个在线作文平台沉淀下来的十万余条作文数据真正的价值不在“多”而在“全”——它同时包含标题、正文、年级、字数、体裁、评分等多个维度是一个天然适合做多维度文本分析与可视化的大规模语料库。这个方向适合三类人一是想练手完整文本分析流水线的 Python 学习者二是需要真实中文语料做教学或研究的从业者三是想搭一套数据可视化大屏给别人看的工程师。它解决的核心问题是如何把一堆非结构化的作文文本拆成可统计、可对比、可呈现的结构化指标再用图表讲清楚“这些作文到底长什么样”。下面我按自己实际做这类项目的顺序把选型、清洗、分析、可视化到踩坑一条条讲透。2. 拿到十万条作文先别急着分词数据摸底与清洗策略2.1 先看清字段结构再决定分析维度十万条数据听起来吓人但如果字段只有“标题正文”两列能做的分析其实很有限。我一般拿到数据集的第一件事不是写分析代码而是用 pandas 把字段类型、缺失率、重复率、长度分布全部打出来。leleketangcom 这类平台的作文数据常见字段包括作文 ID、标题、正文、作者年级、字数、提交时间、体裁标签、评分如果有。先确认哪些字段可用再决定分析维度否则后面全是返工。import pandas as pd # 读取原始数据注意编码中文语料常见 utf-8 或 gbk df pd.read_csv(composition_data.csv, encodingutf-8) # 基础摸底字段类型、缺失、重复 print(df.dtypes) print(df.isnull().sum()) print(重复行数:, df.duplicated(subset[title, content]).sum()) # 正文字数分布判断是否有异常短文本 df[char_len] df[content].astype(str).str.len() print(df[char_len].describe())这段代码的关键在最后一步describe()会告诉你正文字数的中位数和四分位。如果 25% 分位只有几十个字说明数据里混了大量无效短文本必须过滤。参数上我一般把正文少于 100 字的记录直接剔除因为作文分析里短文本会严重干扰词频和主题模型。2.2 清洗要处理的四类脏数据十万条作文里脏数据基本逃不出这四类HTML 标签残留、全角半角混用、重复提交、以及正文里夹带的平台水印或广告语。清洗顺序很重要先做结构化过滤去重、去短再做文本规范化去标签、统一标点最后做分词前的停用词处理。顺序反了会导致重复计算白白多跑几轮。import re def clean_text(text): text str(text) # 去掉 HTML 标签 text re.sub(r[^], , text) # 去掉多余空白和换行 text re.sub(r\s, , text) # 全角转半角标点统一 text text.replace(, ,).replace(。, .) return text.strip() df df[df[char_len] 100].copy() df[clean_content] df[content].apply(clean_text) df df.drop_duplicates(subset[clean_content]) print(清洗后剩余:, len(df))逻辑说明先去 HTML 再统一空白是因为标签里可能含换行顺序反了会残留碎片。全角转半角只处理标点不动汉字避免误伤。参数上char_len 100这个阈值不是死的如果你的数据整体偏短可以降到 50但低于 50 字的“作文”基本没有分析价值。提示清洗前后一定要各存一份文件清洗是不可逆操作出了问题没有后悔药。3. 多维度文本分析怎么落地词频、主题、情感三条线3.1 分词与词频统计的最小可用方案中文作文分析绕不开分词。jieba 是最稳的选择但直接用默认词典会出问题——作文里大量出现“妈妈”“老师”“春天”这类高频词同时又有“leleketangcom”这种平台词需要过滤。我的做法是加载自定义词典加停用词表再统计词频。词频本身不复杂难的是停用词表要针对作文场景定制通用停用词表会漏掉“我们”“他们”这类在作文里毫无信息量的词。import jieba from collections import Counter # 加载自定义词典和停用词 jieba.load_userdict(custom_dict.txt) stopwords set(open(stopwords.txt, encodingutf-8).read().split()) def cut_words(text): words jieba.lcut(text) return [w for w in words if len(w) 1 and w not in stopwords] all_words [] for content in df[clean_content]: all_words.extend(cut_words(content)) word_freq Counter(all_words).most_common(50) for word, freq in word_freq: print(word, freq)参数说明len(w) 1过滤单字因为单字在作文里多是虚词。停用词表建议至少 200 个词覆盖人称代词、连词、助词。如果你要做年级对比就把all_words按年级分组再统计这样能看出低年级和高年级的用词差异。3.2 用 LDA 做主题聚类别指望一次跑出好结果词频只能告诉你“什么词多”主题模型才能告诉你“作文在写什么”。LDA 是文本分析里最常用的主题聚类方法但它对参数敏感尤其是主题数 K。我的经验是先跑 K5 到 K15用困惑度perplexity和人工看关键词两头判断。作文数据的主题通常集中在“亲情”“校园”“自然”“成长”“社会”这几类如果跑出来的主题关键词互相重叠说明 K 太小或语料太杂。from gensim import corpora, models # 构建词典和语料 dictionary corpora.Dictionary([cut_words(c) for c in df[clean_content]]) corpus [dictionary.doc2bow(cut_words(c)) for c in df[clean_content]] # 训练 LDA主题数设为 8 lda models.LdaModel(corpus, num_topics8, id2worddictionary, passes10) for idx, topic in lda.print_topics(num_words8): print(f主题{idx}: {topic})逻辑说明passes10是训练轮数轮数太少主题不稳定太多则耗时。num_topics8是起点不是终点。跑完后看每个主题的前 8 个词如果两个主题的关键词高度重合就把 K 调大或调小再试。这一步没有标准答案靠人工判断。3.3 情感分析用 SnowNLP 够不够作文情感分析和商品评论不一样作文的情感往往是“先抑后扬”或“平淡叙述”用通用情感工具容易翻车。SnowNLP 对中文短文本情感判断还行但长作文里它会因为局部负面词给出偏低分数。我的做法是把作文按段落切分逐段打分再取均值同时结合字数加权。这样比整篇直接打分稳定得多。from snownlp import SnowNLP def paragraph_sentiment(text): paras [p for p in text.split(.) if len(p) 10] if not paras: return 0.5 scores [SnowNLP(p).sentiments for p in paras] return sum(scores) / len(scores) df[sentiment] df[clean_content].apply(paragraph_sentiment) print(df[sentiment].describe())参数说明len(p) 10过滤太短的段落避免噪声。取均值而不是最大值是因为作文整体情感倾向比单句更重要。如果你发现情感分数普遍集中在 0.5 附近说明语料本身情感中性这时候情感维度可以弱化把精力放到主题和词频上。4. 可视化怎么做才不沦为花瓶从 ECharts 到可视化大屏4.1 词云之外至少要有四类图表词云只是入口真正能说明问题的图表有四类词频条形图看高频词排名、主题分布饼图看各主题占比、字数分布直方图看写作长度习惯、年级-主题热力图看不同年级的关注点差异。这四类图用 ECharts 都能做数据从 pandas 导出 JSON 再喂给前端。如果你只想快速出图pyecharts 可以直接在 Python 里生成 HTML省去前后端对接。from pyecharts.charts import Bar from pyecharts import options as opts top20 word_freq[:20] bar ( Bar() .add_xaxis([w for w, _ in top20]) .add_yaxis(词频, [f for _, f in top20]) .set_global_opts( title_optsopts.TitleOpts(title作文高频词 Top20), xaxis_optsopts.AxisOpts(axislabel_optsopts.LabelOpts(rotate45)), ) ) bar.render(word_freq_bar.html)逻辑说明rotate45是防止中文词标签重叠这是血泪经验不旋转的话长词会挤成一团。top20截断是因为超过 20 个词条形图就失去可读性。pyecharts 生成的 HTML 可以直接嵌入可视化大屏的 iframe 里。4.2 可视化大屏的布局逻辑如果你要做可视化大屏别一上来就堆图表。大屏的核心是“一屏讲一个故事”。我的布局习惯是左上放总量指标总作文数、总字数、平均字数中间放词频或主题主图右侧放年级对比或时间趋势底部放明细表格或滚动列表。颜色不要超过三种主色否则看起来像调色板翻了。ECharts 的 dark 主题适合大屏但字号要调大因为大屏观看距离远。注意大屏数据量大的时候前端渲染会卡。十万条数据不要全量传给前端先在 Python 里聚合好再导出前端只负责展示聚合结果。5. 避坑与排查十万条作文分析里最容易翻车的五件事现象一分词结果里全是“的”“了”“我们”。原因停用词表没加载或加载失败。解决在cut_words函数里打印一次停用词集合长度确认不是空集停用词文件编码统一用 utf-8。现象二LDA 跑出来的主题每个都差不多。原因语料太杂或 K 值不合适。解决先按年级或体裁分组分组后再跑 LDAK 值从 5 开始逐步加每次看关键词是否区分明显。现象三情感分析分数全部集中在 0.5。原因SnowNLP 对长文本不敏感或者作文本身情感中性。解决改用逐段打分取均值如果仍然集中说明情感维度不适合这个数据集果断放弃。现象四可视化大屏打开空白。原因JSON 数据格式不对或跨域。解决检查导出的 JSON 是否是合法数组本地打开 HTML 时用python -m http.server起一个服务不要直接双击文件。现象五清洗后数据量骤降一半。原因去重阈值太严或短文本过滤太狠。解决先统计清洗前后各步骤的剩余量定位是哪一步砍太多去重时用clean_content而不是原始content避免因空白差异误判重复。6. 让分析结果可复现参数固化与增量更新技巧做这类项目最怕的是“跑过一次结果再也复现不出来”。我的习惯是把所有可调参数写进一个config.yaml包括短文本阈值、停用词路径、LDA 主题数、词频 TopN。这样换一台机器或换一批数据改配置就行不用翻代码。增量更新则是另一个实用技巧当 leleketangcom 新增作文时不需要全量重跑只需要对新数据做同样的清洗和分词然后合并词频和主题分布。import yaml config yaml.safe_load(open(config.yaml, encodingutf-8)) min_len config[min_content_len] topic_num config[lda_topics] top_n config[word_freq_top_n] # 增量合并词频 new_words [] for content in new_df[clean_content]: new_words.extend(cut_words(content)) merged_freq Counter(all_words) Counter(new_words)参数说明config.yaml里把min_content_len设为 100、lda_topics设为 8、word_freq_top_n设为 50这三个是最常调的。增量合并时注意Counter可以直接相加但停用词表要保证新旧数据一致否则词频不可比。验证分析结果是否靠谱我一般用两个办法一是随机抽 20 篇作文人工看主题标签是否合理二是把词频 Top10 和直觉对比如果出现明显不该高频的词回去查停用词表。这套流程我前后跑过几次最大的教训是别在清洗没做干净的时候就开始分析否则后面每个环节都在给脏数据擦屁股。希望帮到你。本文还有配套的精品资源点击获取