ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

南邮NLP实验一:Anaconda环境、jieba分词与词频统计实战

南邮NLP实验一:Anaconda环境、jieba分词与词频统计实战 简介南邮自然语言处理课程实验一资源围绕词典分词与二元语法分词两大核心任务整理了一份可逐项对照学习的实验报告。内容覆盖HanLP的命令行分词、取消词性标注参数、文件输入输出分词、句法分析指令并给出商品和服务、结婚的和尚未结婚的等典型句子的分词结果同时整理了前向最长匹配、后向最长匹配、双向最长匹配三种词典分词算法的Python代码与结果对比讲解三种算法的区别与适用性。资源还附有教材第27页相关Python实现示例和HanLP核心词典路径说明便于在Windows、Python3.7/3.8环境下复现。资源为doc文档1份压缩包大小232KB内容精炼、层级清楚适合南京邮电大学计算机相关专业学生及NLP初学者快速掌握实验要点。已有421人学习下载对完成课程实验和巩固自然语言处理基础具有实用参考价值。1. 南邮自然语言处理实验一第一个实验在动手之前要认清什么第一次做南邮自然语言处理实验一的人最容易把时间耗在“装环境”而不是“跑通任务”上。这个实验名义上是自然语言处理入门实际考察的却是一个最小闭环拿到一份中文语料完成分词、过滤、统计最后输出一组能被解释的词频结果。很多人在这一步就卡住往往不是算法不会而是编码没处理、分词模式选错、停用词没过滤。这篇内容适合第一次打开 Anaconda、第一次写中文文本处理脚本的读者也适合已经写完但结果和预期对不上的情况——实验一的坑不在模型而在数据处理的基本功。2. 先把工具链理清楚Anaconda、Jupyter 与实验一依赖2.1 为什么实验一普遍要求 Anaconda 而不是裸 Python自然语言处理课程从实验一开始就引导安装 Anaconda不是因为 Python 本身跑不了中文处理而是 Anaconda 解决了进实验室的第一道障碍——依赖和路径。Windows 上裸装 Python 再逐个 pip install最容易在 numpy、scipy 这类带二进制扩展的包上踩编译错误而 Anaconda 自带 conda 包管理器和预编译的科学计算栈能在不碰系统 Python 的前提下隔离出一个干净的实验环境。从实验一的角度看Anaconda 的第二个价值是 Jupyter Notebook。NLP 实验的典型工作流是“读语料、看分词结果、调参数、再读一段”这种交互式迭代恰好是 Jupyter 的强项单元格级执行让每一步的输出都能立刻被检查。相比之下写一个完整 .py 再整体运行遇到分词结果不理想时来回改成本高很多。第三个理由和可复现性有关。实验报告要求截图和输出Jupyter 天然把代码、输出、说明文字放在同一个文件里导出的 HTML 或 PDF 可以直接作为实验报告素材。南邮实验一如果要求提交代码和结果分析用 Notebook 组织会比零散脚本更接近评分标准里的“实验过程完整”这一项。2.2 创建独立环境与安装 jieba 的完整命令不建议直接在 base 环境里装包。实验一后续还有二、三、四不同实验可能依赖不同版本的库独立环境能把互相污染的风险降到最低。常见做法是创建命名环境比如叫 nlp-labconda create -n nlp-lab python3.10 -y conda activate nlp-lab conda install jupyter -y pip install jieba逐条说明这几条命令的作用。第一条用 conda 创建名为 nlp-lab 的环境指定 Python 3.10-y 跳过确认提示第二条激活环境激活后命令行前缀会变成 (nlp-lab)第三条在当前环境里装 Jupyter第四条用 pip 装 jieba。为什么用 pip 而不是 conda 装 jieba因为 jieba 是纯 Python 包没有二进制依赖pip 和 conda 效果一致但 jieba 在 conda 默认源里的更新往往滞后pip 拿到的版本更新。装完之后验证环境是否正常conda env list输出里带有 * 号的就是当前激活的环境。确认是 nlp-lab 后再启动 Jupyterjupyter notebook如果浏览器没有自动打开把终端里输出的带 token 的 URL复制到浏览器即可。这是实验一最常见的环境卡点之一多数情况下不是装失败而是没看清终端里的 URL。2.3 环境验证跑通第一段 NLP 代码环境装好不等于能用先用最小代码验证 jieba 是否可导入、中文是否能正确分词import jieba text 南邮自然语言处理实验一 print(list(jieba.cut(text)))输出应该是 [南邮, 自然语言, 处理, 实验, 一] 这样的分词结果。这里有两个值得注意的点第一jieba.cut 返回的是生成器必须用 list() 包裹才能一次性看到全部词第二如果输出出现 \u5357 之类转义字符说明终端编码有问题Python 3 下通常在代码开头不需要额外处理但 Windows 终端建议设置 chcp 65001 切换到 UTF-8。依赖包用途实验一中的角色jieba中文分词核心依赖所有文本切分都靠它jupyter交互式执行代码与报告的组织载体numpy数值计算构建 n-gram 计数矩阵时需要pandas表格处理词频结果整理与导出这张表里的前三项是实验一装完就必须能 import 的pandas 可以等做到实验三、四再补但如果实验一要求把词频结果整理成 CSV直接用 pandas 会更省事。3. 实验一核心代码中文分词、停用词过滤与词频统计3.1 读入语料的编码问题实验一的语料通常以 .txt 形式给出第一个坑就是编码。绝大多数中文语料是 UTF-8 编码但偶尔会遇到 GBK 或 GB2312尤其是在 Windows 下另存的文本。用错误编码读取轻则出现乱码重则直接 UnicodeDecodeError。稳妥的读法是指定 encoding并处理可能的异常def load_text(path): for enc in [utf-8, gbk, utf-8-sig]: try: with open(path, r, encodingenc) as f: return f.read() except UnicodeDecodeError: continue raise ValueError(f无法识别文件编码: {path})这个函数依次尝试三种常见编码。utf-8-sig 放在最后是因为它会自动处理 BOM 头如果文件是 UTF-8 无 BOM用 utf-8-sig 读取也不会出错只是多一次尝试。实际使用中可以先读出前几个字节判断编码但这个顺序尝试版本足够应对实验一的所有情况。3.2 jieba 分词的三种模式与参数选择jieba 提供三种分词模式精确模式、全模式和搜索引擎模式。精确模式是最常用的默认模式适合做词频统计因为它把句子切分成最合理的一组词没有冗余全模式会把所有可能成词的组合都切出来比如“南京市”会同时切出“南京”“南京市”“京市”这种冗余对词频统计是灾难搜索引擎模式在全模式基础上做合并主要用于搜索场景。实验一选择精确模式即可对应的调用是 jieba.cut(text, cut_allFalse)这也是默认值。有几个参数值得注意import jieba # 精确模式默认 cut_allFalse words jieba.cut(text) # 保留词性便于后续按词性过滤 words_with_pos jieba.posseg.cut(text) # 加载自定义词典补充领域词 jieba.load_userdict(userdict.txt)cut_all 参数控制是否全模式jieba.posseg.cut 返回带词性的对偶比如 (南邮, nt)如果实验要求统计动词或名词就用到这个接口load_userdict 用于把“自然语言处理”这类 jieba 可能切错的词强制切成一个整体词典格式是每行一个词后面可以跟词频和词性例如“自然语言处理 5 n”。分词结果的质量直接影响后续统计。一个常见的问题是包含标点、数字、英文混排的文本分出来的“词”里有大量噪声。这时候需要在分词前做清洗或者分词后过滤。3.3 用 Counter 统计词频并输出 Top-K词频统计在 Python 里最顺手的工具是 collections.Counter。它接收一个可迭代对象自动统计每个元素出现的次数from collections import Counter import re import jieba def clean_and_cut(text): # 只保留中文字符去掉标点与英文数字 text re.sub(r[^\u4e00-\u9fa5], , text) return [w.strip() for w in jieba.cut(text) if w.strip()] def top_k_words(text, k20, stopwordsNone): words clean_and_cut(text) if stopwords: words [w for w in words if w not in stopwords] counter Counter(words) return counter.most_common(k)正则替换把非中文字符统一换成空格这样标点和数字不会混进分词结果。停用词过滤放在分词之后、统计之前顺序错了会导致停用词被拆分出现“我 是 南邮 学生”这种片段里混入单字的情况。停用词表可以直接用网上的通用中文停用词表也可以根据自己的语料手动维护核心是保留“南邮”“自然语言”这类领域词过滤“的、了、是、在”这类高频虚词。输出时建议同时打印词频和占比而不是只打印次数total sum(counter.values()) for word, count in counter.most_common(20): print(f{word}\t{count}\t{count/total:.4f})占比比绝对次数更有解释力。比如“南邮”出现 120 次如果总词数是 8000占比 1.5%这个信息在实验报告里可以直接说明文本的主题集中度。4. 从词频到 n-gram让实验一多拿分的特征工程4.1 为什么词频只是第一步bi-gram 的构建词频统计给出了“每个词出现多少次”的一维视角但自然语言的重要信息恰恰在词与词的顺序关系里。“南京”和“大学”分开看是两个高频词合在一起“南京大学”才是一个实体。实验一如果只交词频统计能及格但要拿高分通常要证明你理解了 n-gram 的基本思想——把相邻词作为一个整体来统计。n-gram 的做法是把文本切成长度为 n 的滑动窗口。n1 就是 unigram对应词频统计n2 是 bigram统计相邻两个词的组合n3 是 trigram。bigram 能捕捉“自然语言”“语言处理”这类局部搭配而这些往往是主题词。对实验一来说实现到 bigram 已经足够展示对上下文的理解再往上 trigram 的数据会变得稀疏统计意义反而下降。4.2 实现一个最小 bigram 模型在分词结果上构建 bigram 非常简单不需要额外安装库from collections import Counter from itertools import islice def build_bigrams(words): # 相邻两词组成一个二元组 return Counter(zip(words, islice(words, 1, None))) bigram_counter build_bigrams(words) print(bigram_counter.most_common(10))zip 把 words 和去掉首元素后的 words 逐对拼接islice 生成偏移一个位置的迭代器避免显式写索引循环。这个实现的效率足够处理几十万字的语料因为生成器是惰性求值的内存占用可控。拿到 bigram 统计后可以进一步筛选只保留出现次数大于等于 3 的组合减少噪声比如“的 时候”“在 这里”这类高频但无信息的搭配。4.3 用困惑度perplexity粗略验证建好 bigram 后一个自然的验证方式是计算困惑度。困惑度越低说明模型对语料的拟合越好。对实验一来说不需要实现平滑算法用最简单的相对频率估计即可import math def bigram_perplexity(bigram_counter, unigram_counter, test_words): total_bigrams sum(bigram_counter.values()) total_unigrams sum(unigram_counter.values()) log_prob_sum 0.0 n 0 for w1, w2 in zip(test_words, islice(test_words, 1, None)): prob_bigram bigram_counter.get((w1, w2), 0) / total_bigrams prob_unigram unigram_counter.get(w1, 0) / total_unigrams # 如果 bigram 没出现退化为 unigram 概率避免 log(0) prob prob_bigram if prob_bigram 0 else prob_unigram if prob 0: log_prob_sum math.log(prob) n 1 if n 0: return float(inf) return math.exp(-log_prob_sum / n)这里用了一个最简单的回退策略bigram 没出现时退回到 unigram 概率。真正的实验报告里不需要实现完整的 Kneser-Ney 平滑但能说明这个回退逻辑已经比只交一个词频统计高出一个层次。可以用语料的前 80% 构建计数后 20% 计算困惑度对比 unigram 和 bigram 的困惑度差异数字越小说明 n-gram 确实捕获了词序信息。5. 提交前自查结果验证与四个常见扣分点5.1 用内置语料做端到端回归实验一交上去之前先用一段你知道标准答案的小文本跑一遍确认每个环节没有静默出错。比如用“南京市长江大桥欢迎你”这句话期望的分词结果是“南京市/长江大桥/欢迎/你”而不是“南京/市长/江大桥”。如果分错了用 load_userdict 把“长江大桥”加进词典再重新跑。这个检查只需要十几秒但能避免最尴尬的“程序跑完、结果全错”的情况。5.2 编码、随机性与可复现性四个常见扣分点第一读文件没指定 encoding在 Windows 上偶发乱码截图时输出是坏的第二没有固定随机种子——如果实验涉及随机采样比如从语料中抽取子集建议 random.seed(42)否则每次运行结果不同报告里写的数据对应不上第三停用词过滤不完整词频 Top-K 里全是“的”“了”这类虚词看起来像是没做预处理第四输出没有保存只在 Jupyter 里有展示提交时临时重新跑结果有出入。提示Jupyter 里跑完后用 df.to_csv(result.csv, indexFalse) 把中间结果落盘确保报告里的截图和数据文件能对应上这比提交前临时截图可靠得多。最后的一个实用技巧是给代码加一个“最小语料”测试把一份只有几千字的样本和期望输出硬编码进测试函数跑通后再处理全量语料。这个习惯能让实验一从“写完碰运气”变成“每步可验证”——评分看的不只是结果对不对更是这个过程是否经得起追问。本文还有配套的精品资源点击获取
返回列表