第N2周:构建词典

本人往期文章可查阅: 深度学习总结

 我的环境:

  • 语言环境:Python3.11
  • 编译器:PyCharm
  • 深度学习环境:Pytorch
    • torch==2.0.0+cu118
    • torchvision==0.18.1+cu118
  • 显卡:NVIDIA GeForce GTX 1660

本周任务:

  • 使用N1周的 .txt 文件构建词典,停用词请自定义

1. 导入数据

from torchtext.vocab import build_vocab_from_iterator
from collections import Counter
from torchtext.data.utils import get_tokenizer
import jieba,re,torch

data=[
    "我是K同学啊!",
    "我是一个深度学习博主,",
    "这是我的365天深度学习训练营教案",
    "你可以通过百度、微信搜索关键字【K同学啊】找到我"
]

2. 设置分词器

# 中文分词方法
tokenizer=jieba.lcut
# 加载自定义词典
jieba.load_userdict(r"E:\DATABASE\N-series\N2\my_dict.txt")

       jiaba是一个由Python编写的中文分词库,用于对中文文本进行分词(知道这个就可以了,没必要深入),其安装方法如下:

  • cmd命令:pip install jieba

       my_dict.txt 文件内容如下:

第N2周:构建词典_第1张图片


2.1 jieba.lcu()

 jieba.lcutjieba 分词库中的一个便捷函数,用于对中文文本进行分词。它直接返回一个分词后的列表,而不需要手动将生成器转换为列表。

2.2 jieba.load_userdict()

jieba.load_userdict()jieba 分词库的一个功能,用于加载用户自定义的词典文件。通过加载自定义词典,你可以向 jieba 的分词系统中添加新的词汇、词频和词性,从而提高分词的准确性和适应性。

 以下是一个完整的示例,展示如何加载自定义词典并进行分词处理:

import jieba

# 加载自定义词典
jieba.load_userdict(r"E:\DATABASE\N-series\N2\my_dict.txt")

# 示例文本
text = "李明正在学习人工智能和深度学习,希望成为领域专家。"

# 使用 jieba 分词
tokens = jieba.lcut(text)

print("分词结果:", tokens)

假设自定义词典文件 my_dict.txt 包含以下内容:

人工智能 5 n
深度学习 10 n
李明 10 nz

 运行代码后:

分词结果: ['李明', '正在', '学习', '人工智能', '和', '深度学习', ',', '希望', '成为', '领域', '专家', '。']

可以看到,李明人工智能深度学习 都被正确地识别为独立的词汇。 

3. 清除标点符号与停用词

3.1 清除标点符号

       在使用 jieba 进行分词时,可以通过去除标点符号来减少分词结果中的噪音。

# 去除标点符号的函数
def remove_punctuation(text):
    return re.sub(r'[^\w\s]','',text)

3.1.1 re.sub

  • re.sub(pattern, replacement, string) 是 Python 的正则表达式库 re 中的一个函数,用于替换字符串中的匹配项。

  • 在这里,pattern 是正则表达式 r'[^\w\s]'replacement 是空字符串 ''string 是输入的 text

3.1.2 正则表达式 r'[^\w\s]'

  • [^...] 表示匹配不在括号内的字符。

  • \w 匹配字母、数字和下划线(等价于 [a-zA-Z0-9_])。

  • \s 匹配任意空白字符(包括空格、制表符、换行符等)。

  • 因此,[^\w\s] 匹配所有非字母数字和非空白字符,即标点符号和其他特殊字符。

3.1.3 替换为 ''

  • 将匹配到的标点符号替换为空字符串,从而移除它们。

3.2 去除停用词 

      在使用 jieba 进行分词时,可以通过去除停用词(即没有具体含义、对文本语义没有影响的词汇,如“的”、“是”、“这”)来减少分词结果中的噪音。标点符号与停用词的去除通常有助于提高文本分类任务的效果。

# 假设我们有一个停用词表,内容如下:
stopwords=set([
    "的","这","是"
])

# 去除停用词的函数
def remove_stopwords(words):
    return [word for word in words if word not in stopwords] 

4. 设置迭代器

# 定义一个迭代器来返回文本数据中的词汇
def yield_tokens(data_iter):
    for text in data_iter:
        # 去除标点符号
        text=remove_punctuation(text)
        # 分词并生成词汇
        text=tokenizer(text)
        # 去除停用词
        text=remove_stopwords(text)
        yield text

5. 构建词典

# 使用 vocab=build_vocab_from_iterator 来构建词汇表
vocab=build_vocab_from_iterator(yield_tokens(data),specials=[""])

# 将未知的词汇索引为0
vocab.set_default_index(vocab[""])
  • build_vocab_from_iterator() 函数详解

       build_vocab_from_iterator 是一个函数,用于从一个迭代器中构建词汇表。它来自于 torchtext.vocab 模块。作用是从一个可迭代对象中统计token的频次,并返回一个vocab(词典)

函数原型:

build_vocab_from_iterator(
    iterator:Iterable,
    min_freq:int=1,
    specials:Optional[List[str]]=None,
    special_first:bool=True,
    max_tokens:Optional[int]=None
)

参数详解:

  • iterator:用于创建vocab(词汇字典)的可迭代对象
  • min_freq:最小频数。只有在文本出现频率大于等于 min_freq 的token才会被保留下来。
  • specials:特殊标志,字符串列表。用于在词汇字典中添加一些特殊的token/标记,比如最常用'',用于代表词汇字典中未存在的token,当然也可以用自己喜欢的符号来代替,具体的意义也取决于用的人。
  • special_first:表示是否将specials放到字典的最前面,默认是True
  • max_tokens:即限制一下这个词汇字典的最大长度。且这个长度包含的specials列表的长度。

以上需要注意的几点:

  • 若是specials设置为了False,则直接默认加在末尾。
  • 通过该方法建立的vocab默认按照频次从大到小的顺序排列,若specials_firstTrue,则specials在最前面。
  • max_tokens也是按照vocab的顺序,从前往后的保存,也就是说如果两个token出现的频次一样,那么是按照出现的顺序来决定vocab中两个单词的顺序
  • 一般使用时,通常配合set_default_index()一起使用

示例:

# 示例数据
data = [
    "这是一个测试文本,包含一些停用词和标点符号。",
    "另一个测试文本,用于演示生成器函数。"
]

# 定义生成器函数
def yield_tokens(data_iter):
    for text in data_iter:
        text = remove_punctuation(text)  # 去除标点符号
        text = tokenizer(text)  # 分词
        text = remove_stopwords(text)  # 去除停用词
        yield text

# 构建词汇表
vocab = build_vocab_from_iterator(yield_tokens(data), specials=[""])

# 设置未知词汇的默认索引
vocab.set_default_index(vocab[""])

# 打印词汇表
print("Vocabulary:", vocab.get_itos())  # 获取词汇表中的所有单词
print("Unknown Token Index:", vocab[""])  # 获取未知词汇的索引

假设 stopwords 包含 {"的", "是", "和", "一些", "用于"},运行代码后: 

Vocabulary: ['', '这是', '一个', '测试', '文本', '包含', '停用词', '标点符号', '另一个', '演示', '生成器', '函数']
Unknown Token Index: 0

6. 文本数字化

# 打印词汇表中的内容
print("词典大小:",len(vocab))
print("词典内部映射:",vocab.get_stoi())

text="这是我的365天深度学习训练营教案"
words=remove_stopwords(jieba.lcut(text))
print("\n")
print("jieba分词后的文本:",jieba.lcut(text))
print("去除停用词后的文本:",remove_stopwords(jieba.lcut(text)))
print("数字化后的文本:",[vocab[word] for word in words])

运行结果:

词典大小: 16
词典内部映射: {'': 0, 'K同学啊': 2, '你': 5, '可以': 8, '我': 1, '博主': 7, '关键字': 6, '365天深度学习训练营': 3, '一个': 4, '微信': 9, '找到': 10, '搜索': 11, '教案': 12, '深度学习': 13, '百度': 14, '通过': 15}


jieba分词后的文本: ['这', '是', '我', '的', '365天深度学习训练营', '教案']
去除停用词后的文本: ['我', '365天深度学习训练营', '教案']
数字化后的文本: [1, 3, 12]

7. 心得体会

       通过本项目练习,了解了如果通过自定义词典来优化分词结果,以及build_vocab_from_iterator()函数的使用方法。

你可能感兴趣的:(NLP)