垃圾短信识别:NLP文本分类从TF-IDF到TextCNN的完整实践
简介这是一套面向本科毕业设计及NLP初学者的中文文本分类实战项目聚焦垃圾短信识别覆盖从数据预处理、中文分词、TF-IDF特征提取到SVM模型训练评估的完整流程并支持按需替换为其他分类模型。包内共8个文件包含文本数据集与停用词表、训练好的SVM模型及TF-IDF向量化模型、可直接运行的训练脚本、流程图和说明文档压缩包约38MB结构清晰便于快速复现。数据集采用标签与短信文本以制表符Tab分隔的格式正样本标记为1表示垃圾短信负样本为0表示正常短信同时标明了依赖的Python3.6、jieba与Scikit-learn环境运行提供的训练脚本即可完成训练。目前已有4451人浏览学习适合本科毕业设计、课程设计及NLP文本分类入门实战能帮助理解文本分类特征工程与经典SVM算法在短文本上的应用也可作为后续扩展模型对比实验的起点。1. 本科毕设选垃圾短信识别看着简单其实是 NLP 中文文本分类最稳的切入每年春天都能看到一堆 NLP 毕业设计题目最后都堆在“基于 BERT 的情感分析”或者“基于 LSTM 的新闻分类”上。这些题目听起来体面但对本科阶段时间、数据、算力都有限的情况来说很难做出让人信服的结果。垃圾短信识别这条线反而稳任务边界清晰、样本好找、指标直观而且它覆盖了 NLP 中文文本分类从清洗、分词、表示、建模到评估的完整链条。做好这一件事答辩时能拿出的东西比很多盲目套用大模型的项目扎实得多。这个方向的合适人群很明确有一定 Python 基础、想完整跑一遍 NLP 流程但不想一上来碰预训练大模型的同学。它不要求 GPU也不是非得用 BERT 才叫 NLP数据量千条起步就能看到明显区分度。后面的章节我会直接按“选型、数据准备、模型落地、避坑、验收”拆开讲每一步都给出能直接改的代码和参数照着做就能把题目落地。2. 建模前先选型垃圾短信识别该走哪条文本分类路线2.1 统计模型与 TF-IDF为什么朴素贝叶斯和逻辑回归仍是合格基线很多初学者一上来就自我加码觉得自己不做深度学习就不够“NLP”。实际上垃圾短信识别这个场景有一个鲜明特征特征往往是表面的词面信号而不是深层语义。“中奖”“回 T 退订”“领取话费”这类词和短句出现基本就能判定。这类任务用 TF-IDF 加权后的词袋特征再配一个线性模型往往已经能撑到 90% 左右的准确率完全足够作为整个项目的基线。朴素贝叶斯是教科书里最常提到的文本分类模型但放在真实短信数据上有一个明显短处它假设特征条件独立而短信里“领奖”“点击链接”这样的强相关词会被重复计算。逻辑回归没有这个假设对词与词之间的共现关系更宽容在大规模稀疏特征上收敛也快。所以我的习惯是第一版基线上逻辑回归而不是朴素贝叶斯同时用 TF-IDF 的 sublinear_tf 参数把词频压缩成对数形式避免“退订”出现三次就把概率拉满。这个阶段不用急着上深度学习。基线的作用是给后续模型一把尺子它足够简单、可解释、几乎不可能失败。如果某个深度模型在测试集上的 F1 连这个基线都压不过那一定是数据或训练设置出了问题而不是模型不够先进。2.2 FastText 的入门价值把整条短信变成词包与子词的组合基线之后有很多条路但本科毕设我优先推荐 FastText。它虽然带“Fast”和“Text”本质上是一个线性分类器加词向量平均的结构但有两个对中文短文本非常友好的设计一是支持词语层面的 n-gram 特征比如“中奖”会被当作一个整体特征参与训练二是支持字符子词信息拼写变体也能被捕获。对垃圾短信这种偏短、偏口语化、带有大量营销套话的文本来说词序的重要程度很低。“立即点击领取”和“点击立即领取”意思完全相同顺序对判断是不是垃圾没有实质影响词袋和词平均天然忽略顺序反而成为优点。FastText 训练速度极快几千条短信几秒钟就能跑完一轮方便反复调参这点对时间紧张的毕业设计尤其重要。FastText 的另一个优势是结果稳定。它不像深度模型那样对随机种子敏感同参数下跑出来的指标波动很小这在答辩时非常关键——你不会因为“上星期准确率 92%今天变成 89%”这种玄学问题被老师追问。2.3 TextCNN 与 BERT 的取舍边界小数据量下怎么选深度模型如果想让项目里有真正的“深度模型成分”TextCNN 是最合理的第二站。它把短信当作一串词用多个不同宽度的卷积核并行扫过相当于同时提取“单个词”“相邻两词”“相邻三词”的局部特征之后做最大池化取出最重要的信号。相比 FastText它能保留短距离词序信息对“不 是 垃圾”这类否定结构更敏感。但要注意TextCNN 不适合在数据量很小的场景里直接替换 FastText。我见过同学拿着两千条样本硬训 CNN结果卷积层学到的是大量记忆样本噪声的局部模式验证集指标反而低于逻辑回归。更合理的做法是让 TextCNN 和 FastText 并行存在二者用同一验证集对比精确率和召回率最后让老师看到你的选型推理过程。BERT 在国内答辩中很容易被追问。稳妥策略是把它放进“思考过、但有意不做”的位置说明白它需要更大的数据量、更长的训练时间以及知识蒸馏和部署成本同时指出如果数据集扩充到五万条以上BERT 是值得升级的方向。这比写一行代码加载微软中文 BERT 然后跑不动要体面得多。选型验证阶段我一般会建一张记录表按数据量、训练时间、可解释性、答辩风险四栏打分表格本身就是很好的毕设文档素材。3. 数据与基线首跑把短信语料切成能训练的特征3.1 中文短信文本的清洗函数编码、链接、数字与特殊符号公开渠道能拿到的短信语料大多来自用户主动贡献或公开学术资源格式通常是 CSV字段包括标签和短信正文。下载后第一件事不是分词而是打开文件确认编码。很多语料是从 GBK 或 GB18030 转成 UTF-8 的处理不当后面会不断出现乱码报错。清洗环节的目标不是把文本变漂亮而是降低噪声对特征提取的干扰。短信里最常见的噪声是 URL、电话号码、长数字序列和重复符号它们对分类判断有辅助作用但不能让它们产生过于分散的词汇特征。下面是我常用的一套清洗函数针对垃圾短信场景做了折中处理不把全部数字删掉而是把手机号这类长数字串替换成统一占位符保留“5 万”“100 元”这类短数字因为它们对判断营销短信非常关键。import re def clean_sms(text: str) - str: 清洗单条短信文本返回适合分词的干净字符串 if not text: return text text.lower().strip() # 去掉 URL避免 http、www 后面跟的一长串无意义字符 text re.sub(rhttps?://\S, , text) text re.sub(rwww\.\S, , text) # 邮箱地址替换成占位符 text re.sub(r\S\S\.\S, email , text) # 连续 5 位及以上数字视为电话号码或乱码统一成占位符 text re.sub(r\d{5,}, num , text) # 多余空白压成一个空格 text re.sub(r\s, , text).strip() return text清洗逻辑里最关键的是数字截断阈值。太激进会误删“10086”“95588”这类服务号特征太保守会引入大量不重复的长串数字使词典膨胀、模型过拟合。保留一到四位数字并按原样交给分词器是中文短信场景里一个比较平衡的口径。3.2 分词、停用词与候选特征ngram 窗口该怎么设中文文本分类无法绕过分词。分词质量直接影响特征的粒度。以“双十一特惠”为例正确切分让模型学到“双十一”和“特惠”两组强信号切错了变成“双”“十一”“特惠”信号就被稀释了。我一般直接用 jieba 的精确模式不开全模式。全模式会把句子切成所有可能的词组合特征数量成倍增长但绝大多数是无效冗余对小数据集反而带来噪声。停用词表方面不要照搬网上那份英文停用词表直接跑中文。中文短信里最需要停的是语气词、人称代词和连词“的、了、吗、我、你、它、因为、所以”这类词对文本分类几乎没有信息增益。但小心不要把“回”“退”“订”这些字误放进停用词表它们合起来正是垃圾短信的高频信号。建议自己从训练集中统计高频词把前 300 个词里明显无语义的字词加入停用词表比任何公开通用表都贴合任务。分词之后还需要决定特征窗口。TF-IDF 向量化器里的 ngram_range 是少数几个对效果影响极大的旋钮之一。只用单个词会丢失“立即”“领取”之间的组合关系用三连词则让特征空间迅速爆炸。垃圾短信场景用二元组就够它能表达出“免费领”“点击链接”“回 T 退订”这些营销短语。3.3 训练验证切分与第一个基线跑通TF-IDF 逻辑回归的最小代码准备数据时最容易犯的一个错误是直接随机切分。短信数据里同一条群发内容会以几十遍形式重复出现如果不去重就随机切分同一条文本可能同时落在训练集和测试集里测试指标虚高非常严重。所以切分前一定要先按短信原文做去重再切分确保任意一条唯一文本只出现在一侧。这一步在工程上决定了整个验证过程有没有参考价值。完成了清洗、分词和去重之后第一个基线模型就可以上了。下面这段代码把 TF-IDF 和逻辑回归封装成一个 pipeline半小时内就能看到可复现的数字。from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression from sklearn.pipeline import make_pipeline from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report # df 里已包含两列label0 正常 / 1 垃圾text已完成清洗和分词 X_train, X_test, y_train, y_test train_test_split( df[text], df[label], test_size0.2, random_state42, stratifydf[label] # 按类别比例分层切分防止测试集里垃圾短信占比失衡 ) pipeline make_pipeline( TfidfVectorizer( ngram_range(1, 2), # 单个词加相邻两词 max_features80000, # 防止特征维度过大导致训练过慢 sublinear_tfTrue # 对词频取 log弱化高频词的影响 ), LogisticRegression(max_iter1000, C1.0) ) pipeline.fit(X_train, y_train) y_pred pipeline.predict(X_test) print(classification_report(y_test, y_pred, target_names[normal, spam]))sublinear_tf 值得单独说明。垃圾短信里“退订”经常连续出现多次如果按原始词频计算它会压过其他有效特征取对数后次数差距从倍数关系变成加数关系特征分布更平稳。C 是逻辑回归的正则化强度默认 1.0 可以先不动。第一次跑完不要只看准确率重点看 spam 那一行的精确率和召回率。4. 三套模型落地FastText、TextCNN 与阈值工程4.1 FastText 训练文本格式、词向量维度与学习率三个必调项FastText 的训练接口很简单但格式很容易栽跟头。它不读 CSV而是要求每行文本以__label__开头标记类别后面跟已经分好词的句子。这一步必须和你前面跑基线的处理方式完全一致顺序是那句清洗、分词、拼标签、写文件。# 将训练集和测试集分别转成 fasttext 文本格式 def write_ft_file(df, path): with open(path, w, encodingutf-8) as f: for label, text in zip(df[label], df[text]): tag __label__spam if label 1 else __label__normal f.write(f{tag} {text}\n) write_ft_file(train_df, train_ft.txt) write_ft_file(test_df, test_ft.txt) import fasttext model fasttext.train_supervised( train_ft.txt, lr1.0, # 学习率过大会梯度震荡过小收敛很慢 dim50, # 词向量维度小语料 50 就够没必要设 300 epoch25, # 轮数配合学习率一起观察训练 loss wordNgrams2, # 开启词级二元组合特征对中文营销短语很关键 minCount1, # 低频词保留策略小数据集建议保留全部 losssoftmax # 二分类类别少softmax 足够 ) result model.test(test_ft.txt) print(fprecision{result[1]:.4f}, recall{result[2]:.4f})FastText 的调参经验与深度模型差异很大。学习率是最敏感的参数lr1.0是官方文档给出的起点但对中文短文本经常表现过冲日志里训练 loss 下降变慢或忽高忽低时优先把它降到 0.3。dim是个性价比很低的参数从 50 涨到 100 一般只提升零点几个点却不必要地拖慢训练和加载速度。真正影响判断的是wordNgrams2缺了它模型就只能看到孤立词垃圾短信里大量的短语记忆能力会被削弱。最后minCount1在小数据集中能保留“发票”“退订”这类低频强信号数据量在五千以下时建议就设成 1。4.2 TextCNN 落地一个可直接运行的 PyTorch 分类器TextCNN 的原理不复杂但本科项目里自己写容易出一堆维度不对的报错。这里给一个稳定的最小实现模型本身不作为重点装饰而是刻意保持紧凑便于把精力放在数据端和调参上。import torch import torch.nn as nn class TextCNN(nn.Module): def __init__(self, vocab_size, embed_size100, num_filters128, num_classes2, max_len64): super().__init__() self.embedding nn.Embedding(vocab_size, embed_size, padding_idx0) # 三个卷积核分别覆盖相邻 2 词、3 词、4 词 self.convs nn.ModuleList([ nn.Conv1d(embed_size, num_filters, kernel_sizew) for w in (2, 3, 4) ]) self.dropout nn.Dropout(0.5) self.fc nn.Linear(num_filters * 3, num_classes) def forward(self, x): # x 形状: (batch, max_len) emb self.embedding(x) # (batch, max_len, embed_size) emb emb.transpose(1, 2) # 转成 (batch, embed_size, max_len) pooled [] for conv in self.convs: c torch.relu(conv(emb)) p torch.max_pool1d(c, c.size(2)).squeeze(2) pooled.append(p) cat torch.cat(pooled, dim1) # 三个池化结果拼接 cat self.dropout(cat) return self.fc(cat)向模型喂数据之前要做两件事构建词汇表给每个词一个 ID以及把每条短信 padding 到一个固定长度。短信大多不长max_len64能覆盖九成以上样本过长截断、过短补零。padding 时 ID 用 0和nn.Embedding里的padding_idx0对齐池化时这些位置不会贡献有效信号。训练部分的重点是要加入 dropout 和早停。TextCNN 收敛很快通常十来个 epoch 就到顶继续训练很容易从“记住营销短语”滑向“记住某一条短信原文”。我的做法是每个 epoch 结束后在验证集上算一次 F1如果连续三轮没有提升就保存当前最佳模型并停止。省下来的时间和改进空间会直观反映在你的实验记录里。4.3 阈值调整与类别不平衡模型输出概率如何变成最终判断无论是逻辑回归、FastText 还是 TextCNN模型默认判断阈值为 0.5。但短信语料天然不平衡正常短信占比经常达到九成以上此时 0.5 未必是合理分界。把阈值调高到 0.7 会让模型只在非常确信时才判为垃圾短信换来更低的正常短信误伤率调低到 0.3 则会抓得更全面代价是部分活动邀约或物流提醒被误杀。from sklearn.metrics import confusion_matrix y_proba pipeline.predict_proba(X_test)[:, 1] # 垃圾短信类别的概率 for thresh in [0.3, 0.5, 0.7]: y_pred (y_proba thresh).astype(int) tn, fp, fn, tp confusion_matrix(y_test, y_pred).ravel() precision tp / (tp fp) recall tp / (tp fn) print(fthreshold{thresh:.1f} precision{precision:.3f} recall{recall:.3f})这段代码可以直接先跑在基线模型上用来快速了解数据集中两类样本的重叠程度。对垃圾短信拦截场景我更建议优先保证精确率因为一条正常短信被归入垃圾的体验代价远高于放过一条广告。这一点可以在毕业设计论文里写成明确的系统设计取舍比拍脑袋定一个阈值有说服力得多。5. 垃圾短信识别避坑五条把准确率拖下来的踩坑记录5.1 重复短信泄漏训练集和测试集同源导致分数虚高现象测试集准确率超过 96%但换到少量手工标注的新短信上明显下降一查发现测试集中大量文本和训练集重复。原因短信是群发性质的营销内容经常被几百万用户同时上传到语料库。直接随机切分时同一条文本被同时分到两侧模型等于背下了标准答案。解决在切分前先对清洗后的短信原文做哈希去重并保证某条文本只进入训练集、测试集或验证集中任意一侧。我的做法是建立文本到集合的分组键用df.drop_duplicates(subset[text])再加多次分组切分来避免串集。5.2 分词把关键短语切碎营销短句特征被稀释现象模型对“免费领取”“限时秒杀”判断不准但对“免费”和“领取”单独出现的判断比较稳定整体召回率偏低。原因jieba 在遇到“免费领取”这类动词加动词结构时常常切分成两个独立词原本的短语记忆单元消失双词特征又需要更大数据量才能补上这个空缺。解决维护一个自定义词典把短信里重复出现的营销短语直接写进jieba.suggest_freq或自定义词表。像“免费领取”“点击链接”“回复退订”这类词强制合并成分词单元再做一次对比实验召回率通常会有明显提升。5.3 标签不一致同一类短信被标成两个类别现象训练过程中 loss 居高不下垃圾短信的召回率始终在一半附近波动检查错误样本时发现两条几乎相同内容的短信标签相反。原因人工标注或半自动清洗时不同批次之间标准不统一。比如“贷款推广”在第 1 次标注中算垃圾在第 2 次标注中被当成了“金融资讯”放行。解决标完数据后先跑一版基线模型找出模型高置信但预测与标签相反的全部样本逐一复查。这类样本往往就是标注错误修正后模型指标会突然上涨一个台阶属于最划算的提分手段。5.4 短文本特征不足标注太短导致模型无从学起现象测试集里单条短信只有五六个字例如“加 V 送”“凭码领”。模型输出接近五五开判定不稳定。原因这类短文本几乎没有上下文词包特征只有一两个词可以提取无论模型多先进都很难给出置信判断。解决把“短信长度”作为一个特征加入训练同时在预处理阶段把主题明显的高频短文本直接合并到营销模板库交给规则层拦截。模型负责吞掉长文本规则兜底处理极短的确定性样本这种配合在工程上是成熟模式。5.5 只看准确率不看混淆矩阵95% 的准确率可能毫无意义现象训练完成准确率 94%看起来不错但打开混淆矩阵发现垃圾短信被大量漏报模型几乎把所有样本都预测成了正常短信。原因负样本占比超过 90% 时全预测正常的基线也能拿到九成准确率这显然不代表系统有价值。解决从第一版实验开始就只看 F1 和召回率同时强制打印混淆矩阵。如果 F1 持续低于准确率十个点说明模型正在安全地偷懒此时需要做类别重采样、换阈值或调整损失权重。6. 验收比训练更重要用推理脚本和逐条走查结束项目6.1 固定推理脚本模型持久化与预处理对齐毕设答辩时老师不会现场看训练过程但一定会要求演示“输入一条短信、输出判断结果”。很多同学训练出了不错的模型演示当天却在加载时报错原因往往是训练脚本和推理脚本里的预处理不一致。训练时做了清洗和 jieba 分词推理时却没有调用同一套函数。稳妥做法是把所有预处理封装成固定函数模型训练完用 joblib 保存整个 pipeline推理时直接加载。import joblib import jieba pipeline joblib.load(sms_pipeline.joblib) label_map {0: 正常短信, 1: 垃圾短信} def predict_sms(raw_text: str): text clean_sms(raw_text) # 与训练时完全一致的清洗函数 cut .join(jieba.cut(text)) # 与训练时完全一致的分词方式 prob pipeline.predict_proba([cut])[0][1] pred int(prob 0.5) return label_map[pred], prob demo_text 恭喜您获得精品礼包点击链接即可领取回复T退订 print(predict_sms(demo_text))这段代码最核心的动作是把“清洗分词向量化”固定在脚本里。日志里加一条记录是最好的调试方式。6.2 用 30 条真实短信逐条走查模型指标只能说明整体水平毕设验收需要落到具体样本上。从语料外收集 30 条真实场景短信按“劫持诱导、营销广告、金融借贷、正常通知”四类均匀分布逐条用推理脚本预测。检查重点不是准确率而是模型漏掉的垃圾短信长什么样是短文本、新式变体还是高度口语化的说法每一条差异都可以成为论文里“失败案例分析”的素材。这 30 条样本不要从训练集抽而是尽量贴近当下实际收到的短信内容。出现过多次的结论是模型在训练集表现好但面对没见过的句子直接暴露出特征覆盖不足的问题。这一事实本身比好的指标更符合本科毕设的真实性也能引导答辩讨论走向工程问题而不是背题。6.3 用混淆矩阵和阈值策略交代效果最后一步是把方案收口成一块完整证据链数据规模、清洗与分词方式、三个模型的对比表、混淆矩阵、阈值选择依据以及 30 条新样本的逐条走查结果。建议在论文里放一张精度与召回随阈值变化的曲线直观展示这个任务不是“能分出来”而是“在什么容忍度下分出来”。这项工作不复杂但极容易和其他同学拉开差距。我自己的习惯是任何模型在宣布完成之前一定要做完这轮手工走查哪怕指标再漂亮也要先接受这 30 条样本的检验。这样才能让整条链路闭环也让调用你的模型的人敢用。哪怕最后模型只达到业务可接受的水平完整的测试动作也足以证明你掌握了中文文本分类的完整方法论。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

三国人物关系词频分析词云图:从文本到洞察的完整落地路径

三国人物关系词频分析词云图:从文本到洞察的完整落地路径

简介:这是一份面向Python文本分析与数据可视化学习者的实战资源包,围绕三国人物关系与词频展开,适合想掌握中文分词、词频统计与词云图生成的中级学习者练手。包内共16个文件,以txt文本、xml配置、png图片为主,另含py脚…

2026/10/13 13:51:55 阅读更多 →
GitHub项目推荐--Plane:开源版 JIRA,让项目管理回归“有序”

GitHub项目推荐--Plane:开源版 JIRA,让项目管理回归“有序”

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 13:50:33 阅读更多 →
Agent Harness 实战指南:用 TaoToken 统一 Key 搭建生产级 AI Agent 的“马具”框架

Agent Harness 实战指南:用 TaoToken 统一 Key 搭建生产级 AI Agent 的“马具”框架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 13:50:37 阅读更多 →

最新新闻

三强版 Codex 一键部署包,本地桌面 AI 自动化全流程实操

三强版 Codex 一键部署包,本地桌面 AI 自动化全流程实操

🔍前言 本文介绍 Codex Harness 一键安装包的部署方案,无需解压,也无需繁琐的环境配置,新手也能快速上手。该方案同时支持 Windows 与 macOS 双平台,跟随向导几步即可完成安装、登录与模型密钥配置。文中完整演示了技…

2026/10/13 20:11:08 阅读更多 →
SpringBoot多环境日志配置:用logback-spring.xml+Profile实现环境隔离

SpringBoot多环境日志配置:用logback-spring.xml+Profile实现环境隔离

1. 为什么SpringBoot项目要把日志配置拆成多环境不管你信不信,我见过太多SpringBoot项目,日志配置就一个logback.xml躺在resources目录里,从入职第一周用到项目上线,开发环境一堆DEBUG刷屏没人管,生产环境出了问题想查…

2026/10/13 20:11:07 阅读更多 →
MATLAB中AES-256加解密实战:Java桥接与文件安全

MATLAB中AES-256加解密实战:Java桥接与文件安全

简介:这份资源面向学习密码学与MATLAB编程的读者,提供AES-256位加密算法在MATLAB 2012B环境下的完整实现代码,帮助理解对称加密的内部运作机制。压缩包共16个文件,约448KB,以13个m脚本为核心,涵盖密钥扩展、…

2026/10/13 20:11:07 阅读更多 →
C++结构体与结构体数组:从定义、内存布局到排序实践

C++结构体与结构体数组:从定义、内存布局到排序实践

如果你翻过C教材的目录,多半会在“结构体”这一章停几秒钟,然后想:这不就是把几个变量捆在一起吗?有什么好讲的。我工作之后才意识到,结构体恰恰是C里最容易被低估的基础设施,链表、树、图形控件的属性表、…

2026/10/13 20:11:07 阅读更多 →
Spring Boot JPA 实战指南:从实体映射到查询优化的避坑经验

Spring Boot JPA 实战指南:从实体映射到查询优化的避坑经验

1. 为什么我要认真聊聊 Spring Boot 里的 JPA做后端开发这些年,我接触过的持久层方案不算少。从最早手写 JDBC 拼 SQL,到后来用 MyBatis 写 XML 映射文件,再到 Spring Boot 项目里大量使用 JPA,每一种方案都有它适合的场景。但要说…

2026/10/13 20:11:07 阅读更多 →
Sufer 8.0英文版等值线图实战:从散点插值到批量出图的完整避坑指南

Sufer 8.0英文版等值线图实战:从散点插值到批量出图的完整避坑指南

简介:Surfer 8.0英文版是Golden Software公司推出的专业地形图绘制与三维建模软件,面向地质、环境科学、工程及地球科学领域的从业者与学习者,用于将离散数据转化为连续格网表面并生成专业图件。压缩包共234个文件,约12.41MB&…

2026/10/13 20:10:07 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →