本人往期文章可查阅: 深度学习总结
我的环境:
本周任务:
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同学啊】找到我"
]
# 中文分词方法
tokenizer=jieba.lcut
# 加载自定义词典
jieba.load_userdict(r"E:\DATABASE\N-series\N2\my_dict.txt")
jiaba是一个由Python编写的中文分词库,用于对中文文本进行分词(知道这个就可以了,没必要深入),其安装方法如下:
my_dict.txt 文件内容如下:
jieba.lcut
是 jieba
分词库中的一个便捷函数,用于对中文文本进行分词。它直接返回一个分词后的列表,而不需要手动将生成器转换为列表。
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
运行代码后:
分词结果: ['李明', '正在', '学习', '人工智能', '和', '深度学习', ',', '希望', '成为', '领域', '专家', '。']
可以看到,李明
、人工智能
和 深度学习
都被正确地识别为独立的词汇。
在使用 jieba 进行分词时,可以通过去除标点符号来减少分词结果中的噪音。
# 去除标点符号的函数
def remove_punctuation(text):
return re.sub(r'[^\w\s]','',text)
re.sub(pattern, replacement, string)
是 Python 的正则表达式库 re
中的一个函数,用于替换字符串中的匹配项。
在这里,pattern
是正则表达式 r'[^\w\s]'
,replacement
是空字符串 ''
,string
是输入的 text
。
r'[^\w\s]'
[^...]
表示匹配不在括号内的字符。
\w
匹配字母、数字和下划线(等价于 [a-zA-Z0-9_]
)。
\s
匹配任意空白字符(包括空格、制表符、换行符等)。
因此,[^\w\s]
匹配所有非字母数字和非空白字符,即标点符号和其他特殊字符。
''
将匹配到的标点符号替换为空字符串,从而移除它们。
在使用 jieba 进行分词时,可以通过去除停用词(即没有具体含义、对文本语义没有影响的词汇,如“的”、“是”、“这”)来减少分词结果中的噪音。标点符号与停用词的去除通常有助于提高文本分类任务的效果。
# 假设我们有一个停用词表,内容如下:
stopwords=set([
"的","这","是"
])
# 去除停用词的函数
def remove_stopwords(words):
return [word for word in words if word not in stopwords]
# 定义一个迭代器来返回文本数据中的词汇
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 来构建词汇表
vocab=build_vocab_from_iterator(yield_tokens(data),specials=[""])
# 将未知的词汇索引为0
vocab.set_default_index(vocab[""])
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
)
参数详解:
以上需要注意的几点:
- 若是specials设置为了False,则直接默认加在末尾。
- 通过该方法建立的vocab默认按照频次从大到小的顺序排列,若specials_first为True,则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
# 打印词汇表中的内容
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]
通过本项目练习,了解了如果通过自定义词典来优化分词结果,以及build_vocab_from_iterator()函数的使用方法。