一.自然语言处理入门

目标:

  • 了解什么是自然语言处理
  • 了解自然语言处理的发展简史
  • 了解自然语言处理的应用场景

1.什么是自然语言处理

自然语言处理(Natural Language Processing,简称NLP)是计算机科学与语言学中关注于计算机与人类语言间转换的领域,直白地说: NLP就是让计算机来理解人类的语言,让机器理解并生成人类语言

为啥大模型现在这么火,这么成功的应用?

  • 1.输入内容,大模型能理解
  • 2.大模型生成的答案,我们能看懂,符合人类的习惯

2.自然语言处理的发展简史

  • 1950 图灵提出“机器能思考吗”,划时代性的话题
  • 1956 达特茅斯会议,提出人工智能(Artificial Intelligence),AI的元年,之前都是人类智能(Human Intelligence)
  • 1957-1970 NLP开始出现两大阵营:规则(基于人-专家) + 统计(基于数据)
  • 1994-1999 统计学开始占据主导地位(概率计算开始引入到NLP领域的每个任务中)
  • 2000-2012 机器学习开始盛行
  • 2012-2022 传统的深度学习占据主导地位
  • 2023+   大模型时代
  • 基于规则举例:设计语言学规则,解析句子结构,例如一个句子由主谓宾构成
  • 基于统计举例:统计机器翻译模型,收集大量平行语料库,例如中英互译,统计不同短语的分配概率,计算给定源语言翻译为目标语言的可能性

3.自然语言处理的应用场景

  • 语音助手:小爱同学
  • 机器翻译:谷歌翻译
  • 搜素引擎:百度翻译
  • 智能对话:文心一言
  • 推荐系统:短视频app推荐

二.文本预处理

目标:

  • 了解文本预处理相关的内容

1.认识文本预处理

1.1 文本预处理及其作用

文本语料在输送给模型前一般需要一系列的预处理工作, 才能符合模型输入的要求, 如: 将文本转化成模型需要的张量, 规范张量的尺寸(维度)等, 而且科学的文本预处理环节还将有效指导模型超参数的选择, 提升模型的评估指标

1.2 文本预处理中包含的主要环节

  • 文本处理的基本方法: 分词,词性标注,命名实体识别
  • 文本张量表示方法: 文本->切词->词向量
  • 文本语料的数据分析: 样本是否均衡
  • 文本特征处理
  • 数据增强方法
1.2.1 文本处理的基本方法
  • 分词
  • 词性标注
  • 命名实体识别
1.2.2 文本张量表示方法
1.2.3 文本语料的数据分析
  • 标签数量分布
  • 句子长度分布
  • 词频统计与关键词词云
1.2.4 文本特征处理
  • 添加n-gram特征
  • 文本长度规范
1.2.5 数据增强方法
  • 回译数据增强法

常见的文本预处理步骤包括:

  • 文本清理:去除 HTML 标签、特殊字符、表情符号等,提高数据质量
  • 分词:将中文文本拆分成词语,便于后续处理(如 TF-IDF、词向量训练)
  • 去停用词:删除“的”、“是”、“了”等低信息量的词,提高模型效率
  • 词性标注:识别词的词性,有助于 NLP 任务,如命名实体识别(NER)
  • 文本向量化:将文本转换为数值表示,如 TF-IDF、Word2Vec、BERT 词向量等,以便机器学习模型处理

2.文本处理的基本方法

目标

  • 了解什么是分词, 词性标注, 命名实体识别及其它们的作用
  • 掌握分词, 词性标注, 命名实体识别流行工具的使用方法

2.1 什么是分词

分词就是将连续的字序列按照一定的规范(语法)重新组合成词序列的过程, 在英文的行文中,单词之间是以空格作为自然分界符的,而中文只是字、句和段能通过明显的分界符来简单划界,唯独词没有一个形式上的分界符,分词过程就是找到这样分界符的过程

  • 分词的作用(分词的每个结果=1个Token):

    • 作为语言语义理解的最小单元, 是人类理解文本语言的基础. 因此也是AI解决NLP领域高阶任务, 如自动问答, 机器翻译, 文本生成的重要基础环节
  • 流行中文分词工具jieba:

    • 愿景: “结巴”中文分词, 做最好的 Python 中文分词组件
  • jieba的特性:

    • 支持多种分词模式
      • 精确模式(jieba.lcut())
      • 全模式
      • 搜索引擎模式(工作中用得最多)
    • 支持中文繁体分词
    • 支持用户自定义词典
  • jieba的安装:

pip install jieba
  • jieba的使用:
  • 精确模式分词:
  • 试图将句子最精确地切开,适合 文本分析, 自然语言处理(分词标注, 信息提取等...)
import jieba
content = "打发大水噶电饭锅舒服点,给丰东股份丰东股份"
# 精确模型:试图将句子最精确地切开,适合文本分析。也属于默认模式
jieba.cut(content, cut_all=False)  # cut_all默认为False

# 将返回一个生成器对象
#<generator object Tokenizer.cut at 0x7f8d9053e650>

# 若需直接返回列表内容, 使用jieba.lcut即可
jieba.lcut(content, cut_all=False)
['打发', '大水', '噶', '电饭锅', '舒服点', ',',  '丰东股份', '丰东', '股份']
  • 全模式分词:
  • 把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能消除歧义,适用于: 关键词提取, 不需要 严格分词准确性 的场
# 若需直接返回列表内容, 使用jieba.lcut即可
jieba.lcut(content, cut_all=True)

['打发', '大水', '噶', '电饭锅', '舒服点', ',',  '丰东股份', '丰东', '股份']

# 注意1:人工智能全模型分成三个词
# 注意2:逗号和句号也给分成了词
  • 搜索引擎模式分词:
  • 在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎 ,文本匹配
import jieba
content = "打发大水噶电饭锅舒服点,给丰东股份丰东股份"
jieba.cut_for_search(content)

# 将返回一个生成器对象
<generator object Tokenizer.cut_for_search at 0x7f8d90e5a550>

# 若需直接返回列表内容, 使用jieba.lcut_for_search即可
jieba.lcut_for_search(content)

['打发', '大水', '噶', '电饭锅', '舒服点', ',',  '丰东', '股份', '丰东', '股份']

# 对'丰东股份'等较长词汇都进行了再次分词
  • 中文繁体分词:
  • 针对中国香港, 台湾地区的繁体文本进行分词
import jieba
content = "煩惱即是菩提,我暫且不提"
jieba.lcut(content)
['煩惱', '即', '是', '菩提', ',', '我', '暫且', '不', '提']
  • 使用用户自定义词典:
  • 添加自定义词典后, jieba能够准确识别词典中出现的词汇,提升整体的识别准确率
  • 词典格式: 每一行分三部分:词语、词频-词出现的概率(可省略)、词性(可省略),用空格隔开,顺序不可颠倒
  • 词典样式如下, 具体词性含义请参照 jieba词性对照表
import jieba

sentence = '打发大水噶电饭锅舒服点,给丰东股份丰东股份'
# 1 没有使用用户自定义词典
mydata = jieba.lcut(sentence, cut_all=False)
print('mydata-->', mydata)

# 2 使用用户自定义词典
jieba.load_userdict("./userdict.txt")
mydata2 = jieba.lcut(sentence, cut_all=False)
print('mydata2-->', mydata2)

# 没有使用用户自定义词典的分词效果
mydata-->['打发', '大水', '噶', '电饭锅', '舒服点', ',',  '丰东', '股份', '丰东', '股份']


# 使用用户自定义词典的分词效果
mydata2-->['打发', '大水', '噶', '电饭锅', '舒服', '点', ',',  '丰东股份', '丰东股份']

举例 jieba 精确分词模式, 全分词模式, 搜索引擎分词模式, ,繁体分词,自定义词典 模式代码:

"""
案例: 演示jieba分词
分词相关介绍:
    概述:
        分词过程 = 找到 分界符 的过程, 找到分界符就可以分词了.
        每个分词结果 = 1个Token
    常见的分词包:
        jieba:      精确模式, 全模式, 搜索引擎模式...
        IK分词器:    ElasticSearch搜索引擎用的多.
        SnowNLP:    基于概率算法的中文自然语言处理工具包.
        pyltp:      哈工大的
        THULAC:     清华的
        ......
    jieba的作用:
        A.支持多种分词模式
            精确模式:       试图将句子 最精确的切开, 适合: 文本分析.
            全模式:        把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能消除歧义
            搜索引擎模式:   在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
        B.支持中文繁体分词
        C.支持用户自定义词典

    总结:
        上述的分词模式, 其实就是 分词粒度不同. 例如 "软件工程" -> 软件工程(粗粒度),    软件, 工程 (细粒度)

额外的话(扩展), 为了不和前边的环境冲突, 建议新创建1个沙箱来实现:
    Conda命令:
        conda env list                        查看本机安装的所有沙箱
        conda activate 沙箱名                  切换沙箱
        conda create -n 沙箱名 python==3.10    创建新的沙箱, 且指定Python解释器版本为 3.10
        conda remove -n 沙箱名 --all           删除沙箱

    需要做的:
        1.新建 nlbbase 沙箱
        2.在PyCharm中新建项目
        3.配置PyCharm连接nlpbase沙箱
        4.在nlpbase沙箱中安装jieba分词器,  演示分词

"""

import jieba


# 1.定义函数, 演示 jieba精确分词模式, 适用于: 文本分析, 自然语言处理(分词标注, 信息提取等...)
def dm01():
    # 1. 定义待分词的文本内容.
    content = '对光反射发光飞碟更好的听哈高发季干哈激发和卡卡'

    # 2. 使用jieba进行 精确模式分词(默认模式) -> cut_all = False
    # 获取分词结果(生成器对象) -> 好处: 节省内存, 只能遍历一次.
    result1 = jieba.cut(content, cut_all=False)
    print(f'result1: {result1}')        # 结果是: 生成器对象.

    # 3. 从生成器中获取元素.
    # 思路1: next()函数, 逐个获取下个元素.
    print(next(result1))
    print(next(result1))
    print('-' * 30)

    # 思路2: 遍历方式, 从生成器中获取元素, 接着上面的next展示数据.
    for value in result1:
        print(value)
    print('-' * 30)

    # 4. 如果要列表怎么办?
    # 思路1: 直接把上述的 生成器 -> 列表
    list1 = list(result1)
    print(f'list1: {list1}')

    # 思路2: 切词时, 直接返回 list, 相当于: 语法糖, 底层是 list1 = list(result1), 把cut转换成list
    result2 = jieba.lcut(content, cut_all=False)
    print(f'result2: {result2}')


# todo 2.定义函数, 演示 jieba全模式分词, 适用于: 关键词提取, 不需要 严格分词准确性 的场景.
def dm02():
    # 1. 定义待分词的文本内容.
    content = '对光反射发光飞碟更好的听哈高发季干哈激发和卡卡'

    # 2. 使用jieba进行 全模式分词 -> cut_all = True
    # 获取分词结果(生成器对象) -> 好处: 节省内存, 只能遍历一次.
    result1 = jieba.cut(content, cut_all=True)
    print(f'result1: {result1}')  # 结果是: 生成器对象.

    # 3. 从生成器中获取元素.
    # 思路1: next()函数, 逐个获取下个元素.
    print(next(result1))
    print(next(result1))
    print('-' * 30)

    # 思路2: 遍历方式, 从生成器中获取元素.
    for value in result1:
        print(value)
    print('-' * 30)

    # 4. 如果要列表怎么办?
    # 思路1: 直接把上述的 生成器 -> 列表
    list1 = list(result1)
    print(f'list1: {list1}')

    # 思路2: 切词时, 直接返回 list, 相当于: 语法糖.
    result2 = jieba.lcut(content, cut_all=True)
    print(f'result2(全模式): {result2}')

    # 扩展: 打印下 精确模式分词, 用于和上述的 全模式分词, 进行对比.
    result3 = jieba.lcut(content, cut_all=False)
    print(f'result3(精确模式): {result3}')


# todo 3. 定义函数, 演示 jieba搜索引擎模式分词, 适用于: 搜索引擎, 文本匹配.
"""
解释: 搜索引擎分词模式, 在精确模式分词的基础上, 对长词进行再次切分, 提高召回率. 
例如:
    场景1: 用户录入  "程序员"
        精确模式:       只能匹配包含完整 "程序员" 的文档.
        搜索引擎模式:    不仅能匹配 "程序员" 的文档, 还能匹配 "程序", "员"的文档.   提高召回.

    场景2: 用户搜索 "Python程序员"
        精确模式:       无法匹配, 分词为("Python", "程序员")
        搜索引擎模式:    能匹配, 分词为("Python", "程序", "员")

    场景3: 实际应用场景(电商搜索),  商品标题为: "荣耀AGC手机保护壳", 用户搜索 "荣耀壳"
        精确模式:       无法匹配, 分词为("荣耀", "AGC", "手机", "保护壳")
        搜索引擎模式:    能匹配, 分词为("荣耀", "AGC", "手机", "保护", "壳")

"""

def dm03():
    # 1. 定义待分词的文本内容.
    content = '对光反射发光飞碟更好的听哈高发季干哈激发和卡卡'

    # 2. 使用jieba进行 搜索引擎模式分词 -> cut_for_search
    # 获取分词结果(生成器对象) -> 好处: 节省内存, 只能遍历一次.
    result1 = jieba.cut_for_search(content)
    print(f'result1: {result1}')  # 结果是: 生成器对象.

    # 3. 从生成器中获取元素.
    # 思路1: next()函数, 逐个获取下个元素.
    print(next(result1))
    print(next(result1))
    print('-' * 30)

    # 思路2: 遍历方式, 从生成器中获取元素.
    for value in result1:
        print(value)
    print('-' * 30)

    # 4. 如果要列表怎么办?
    # 思路1: 直接把上述的 生成器 -> 列表
    list1 = list(result1)
    print(f'list1: {list1}')

    # 思路2: 切词时, 直接返回 list, 相当于: 语法糖.
    result2 = jieba.lcut_for_search(content)
    print(f'result2(搜索引擎模式): {result2}')

    # 扩展: 打印下 精确模式分词, 用于和上述的 全模式分词, 进行对比.
    result3 = jieba.lcut(content, cut_all=False)
    print(f'result3(精确模式): {result3}')

    # 扩展: 打印下 全模式分词, 用于和上述的 搜索引擎模式分词, 进行对比.
    result4 = jieba.lcut(content, cut_all=True)
    print(f'result4(全模式): {result4}')


# todo 4. 定义函数, 演示 jieba繁体分词, 适用于: 中国香港, 台湾, 澳门...
def dm04():
    # 1. 定义待分词的文本内容.
    content = '煩惱即是菩提,我暫且不提'

    # 2. 切割繁体字.
    result1 = jieba.lcut(content)
    print(f'result1: {result1}')


# todo 5.定义函数, 演示 jieba分词之 自定义词典, 适用于: 稍微生僻点的词或者特殊要求的词组, 一般不会太多.
"""
添加自定义词典后, jieba能够准确识别词典中出现的词汇,提升整体的识别准确率。
词典格式: 每一行分三部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒。
词典样式如下, 具体词性含义请参照7 jieba词性对照表, 将该词典存为userdict.txt, 方便之后加载使用。
"""


def dm05():
    # 1. 定义待分词的文本内容.
    content = '对光反射发光飞碟更好的听哈高发季干哈激发和卡卡'
    # 2. 执行未加载自定义词典的分词.
    result1 = jieba.lcut(content)  # 默认: 精确模式分词.
    print(f'result1(精确模式分词): {result1}')

    # 3. 加载用户自定义词典.
    jieba.load_userdict('./data/userdict.txt')
    # 4. 执行加载自定义词典的分词.
    result2 = jieba.lcut(content)
    # 5. 打印结果.
    print(f'result2: {result2}')


# todo 6.测试
if __name__ == '__main__':
    dm01()
    # dm02()
    # dm03()
    # dm04()
    # dm05()

jieba词性对照表

- a 形容词  
    - ad 副形词  
    - ag 形容词性语素  
    - an 名形词  
- b 区别词  
- c 连词  
- d 副词  
    - df   
    - dg 副语素  
- e 叹词  
- f 方位词  
- g 语素  
- h 前接成分  
- i 成语 
- j 简称略称  
- k 后接成分  
- l 习用语  
- m 数词  
    - mg 
    - mq 数量词  
- n 名词  
    - ng 名词性语素  
    - nr 人名  
    - nrfg    
    - nrt  
    - ns 地名  
    - nt 机构团体名  
    - nz 其他专名  
- o 拟声词  
- p 介词  
- q 量词  
- r 代词  
    - rg 代词性语素  
    - rr 人称代词  
    - rz 指示代词  
- s 处所词  
- t 时间词  
    - tg 时语素  
- u 助词  
    - ud 结构助词 得
    - ug 时态助词
    - uj 结构助词 的
    - ul 时态助词 了
    - uv 结构助词 地
    - uz 时态助词 着
- v 动词  
    - vd 副动词
    - vg 动词性语素  
    - vi 不及物动词  
    - vn 名动词  
    - vq 
- x 非语素词  
- y 语气词  
- z 状态词  
    - zg 

hanlp词性对照表:

【Proper Noun——NR,专有名词】

【Temporal Noun——NT,时间名词】

【Localizer——LC,定位词】如“内”,“左右”

【Pronoun——PN,代词】

【Determiner——DT,限定词】如“这”,“全体”

【Cardinal Number——CD,量词】

【Ordinal Number——OD,次序词】如“第三十一”

【Measure word——M,单位词】如“杯”

【Verb:VA,VC,VE,VV,动词】

【Adverb:AD,副词】如“近”,“极大”

【Preposition:P,介词】如“随着”

【Subordinating conjunctions:CS,从属连词】

【Conjuctions:CC,连词】如“和”

【Particle:DEC,DEG,DEV,DER,AS,SP,ETC,MSP,小品词】如“的话”

【Interjections:IJ,感叹词】如“哈”

【onomatopoeia:ON,拟声词】如“哗啦啦”

【Other Noun-modifier:JJ】如“发稿/JJ 时间/NN”

【Punctuation:PU,标点符号】

【Foreign word:FW,外国词语】如“OK

2.2 什么是命名实体识别

  • 命名实体: 通常将人名, 地名, 机构名等专有名词统称命名实体. 如: 周杰伦, 黑山县, 孔子学院
  • 顾名思义, 命名实体识别(Named Entity Recognition,简称NER)就是识别出一段文本中可能存在的命名实体

  • 举个例子:

鲁迅, 浙江绍兴人, 五四新文化运动的重要参与者, 代表作朝花夕拾.

鲁迅(人名) / 浙江绍兴(地名)人 / 五四新文化运动(专有名词) / 重要参与者 / 代表作 / 朝花夕拾(专有名词)
  • 命名实体识别的作用:
    • 同词汇一样, 命名实体也是人类理解文本的基础单元, 因此也是AI解决NLP领域高阶任务的重要基础环节

2.3 什么是词性标注

  • 词性: 语言中对词的一种分类方法,以语法特征为主要依据、兼顾词汇意义对词进行划分的结果, 常见的词性有14种, 如: 名词, 动词, 形容词等
  • 顾名思义, 词性标注(Part-Of-Speech tagging, 简称POS)就是标注出一段文本中每个词汇的词性

  • 举个例子:

我爱自然语言处理

我/rr, 爱/v, 自然语言/n, 处理/vn

rr: 人称代词
v: 动词
n: 名词
vn: 动名词
  • 词性标注的作用:

    • 词性标注以分词为基础, 是对文本语言的另一个角度的理解, 因此也常常成为AI解决NLP领域高阶任务的重要基础环节.
  • 使用jieba进行中文词性标注:

import jieba.posseg as pseg
pseg.lcut("我爱北京天安门") 
[pair('我', 'r'), pair('爱', 'v'), pair('北京', 'ns'), pair('天安门', 'ns')]

# 结果返回一个装有pair元组的列表, 每个pair元组中分别是词汇及其对应的词性, 具体词性含义请参照[jieba词性对照表]()
"""
案例:
    代码演示 POS(词性标注)

名词解释:
    NER(命名实体识别, Named Entity Recognition), 就是识别出一段文本中可能存在的 命名实体.
        命名实体:
            人名, 地名, 机构名等专有名词 -> 命名实体
        作用:
            和词汇一样, 也是人类理解文本的基础单元.
            (后续我们NLP的第1个项目, 就是NER, 后续详解, 目前了解概念即可)


    POS(词性标注 Part Of Speech Tagging), 语言中对词的一种分类方法.
        以 语法特征 为主要依据, 兼顾词汇意义对词进行划分 词性, 例如: 名词, 动词, 形容词...

        大白话解释:
            POS(词性标注) = 标注出一段文本中 每个词汇的 词性.
"""

# 导包
import jieba.posseg as pseg

# 1. 定义变量, 记录: 待分词并标注词性的 文本.
content = '我爱北京天安门'

# 2. 使用 pseg#lcut()方法进行 分词 和 词性标注.
# 结果: 每个元素是1个pair对象, 包括: 词语, 词性
result = pseg.lcut(content)
print(f'result: {result}')

# 3. 获取每组数据, 词 和 词性.
for word, flag in result:
    print(f'词语: {word}, 词性: {flag}')
result: [pair('我', 'r'), pair('爱', 'v'), pair('北京', 'ns'), pair('天安门', 'ns')]
词语: 我, 词性: r
词语: 爱, 词性: v
词语: 北京, 词性: ns
词语: 天安门, 词性: ns

小结

  • 学习了什么是分词:

    • 分词就是将连续的字序列按照一定的规范(语法)重新组合成词序列的过程。在英文的行文中,单词之间是以空格作为自然分界符的,而中文只是字、句和段能通过明显的分界符来简单划界,唯独词没有一个形式上的分界符, 分词过程就是找到这样分界符的过程.
  • 学习了分词的作用:

    • 词作为语言语义理解的最小单元, 是人类理解文本语言的基础. 因此也是AI解决NLP领域高阶任务, 如自动问答, 机器翻译, 文本生成的重要基础环节.
  • 学习了流行中文分词工具jieba:

    • 支持多种分词模式: 精确模式, 全模式, 搜索引擎模式
    • 支持中文繁体分词
    • 支持用户自定义词典
  • 学习了jieba工具的安装和分词使用

  • 学习了什么是命名实体识别:

    • 命名实体: 通常将人名, 地名, 机构名等专有名词统称命名实体. 如: 周杰伦, 黑山县, 孔子学院, 24辊方钢矫直机.
    • 顾名思义, 命名实体识别(Named Entity Recognition,简称NER)就是识别出一段文本中可能存在的命名实体.
  • 命名实体识别的作用:

    • 同词汇一样, 命名实体也是人类理解文本的基础单元, 因此也是AI解决NLP领域高阶任务的重要基础环节.
  • 学习了什么是词性标注:

    • 词性: 语言中对词的一种分类方法,以语法特征为主要依据、兼顾词汇意义对词进行划分的结果, 常见的词性有14种, 如: 名词, 动词, 形容词等.
    • 顾名思义, 词性标注(Part-Of-Speech tagging, 简称POS)就是标注出一段文本中每个词汇的词性.
  • 学习了词性标注的作用:

    • 词性标注以分词为基础, 是对文本语言的另一个角度的理解, 因此也常常成为AI解决NLP领域高阶任务的重要基础环节.
  • 学习了使用jieba进行词性标注

【上一篇】【深度学习】12.循环神经网络RNN-文本生成案例

【下一篇】【NLP自然语言处理】2.基础-文本预处理-文本张量表示方法

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐