1-1 分词
# encoding=utf-8
import jieba
# 导入 jieba 时,会先把模型导入进来,导入模型也是要消耗时间的;后面再次运行时,模型就不会重复导入了
# cut_all=True 的意思是全模式
# 全模式是什么意思?
# 全模式的意思是取出当前话的全部词;比如 我/来到/北京/北京大学/大学;拿出全部能够出现的词
# 只要是能分的词,jieba词典都可以找出来;这种全模式的分词很少用,因为无法完全表达句意,会有歧义
# 句子越长,能摘出来的词就越多;最后会变成词的组合
seg_list = jieba.cut("我来到北京大学",cut_all=True)
print("Full Mode: "+"/".join(seg_list)) # 全模式
# 精准模式是常用的模式,会构造一个有向的无环图
# 北京大学放一起的频率比较高,成词的个数会较少
seg_list = jieba.cut("我来到北京大学",cut_all=False)
print("Default Mode: "+"/".join(seg_list)) # 精确模式
seg_list = jieba.cut("他来到了网易行研大厦") # 默认是精确模式;而且 HMM 不开启 (HMM 隐马尔科夫模型)
print(", ".join(seg_list))
# 比如中国科学院,cut_for_search 会把 中国科学院 再次切分;会把高频词拿出来
# 因为这些高频词可能具有更好的召回率
# 但是不会像全模式那样,把所有的词都拿出来;有些词表里的低频词 就不会被拿出来;这就是搜索引擎模式
seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") # 搜索引擎模式
print(", ".join(seg_list))
-->
Full Mode: 我/来到/北京/北京大学/大学
Default Mode: 我/来到/北京大学
他, 来到, 了, 网易, 行研, 大厦
小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, ,, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造
# seg_list 返回的是 生成器,这里用 .join的方式放一个 generator 对象,就可以变成一个字符串
# ", ".join 就是用 逗号 把生成器中的子元素 隔开,然后拼接成一个字符串
# 以上是结巴分词的基础用法,主要是用 cut
部分代码解释说明:
1-1-1
# join()和生成器
In [84]: c = (str(i*2) for i in range(10))
In [85]: c
Out[85]: <generator object <genexpr> at 0x00000208D89C7890>
In [86]: "".join(c)
Out[86]: '024681012141618'
# 这里 join 做的事情和 for 循环是一样的,其实是相当于执行了 for 循环
1-2 结巴分词的衍生用法,添加自定义词典
# 自定义词典:jieba默认有一个词典,匹配分词时从这里高速扫描,但是这个词典一般无法保证时效性;
# 所以一些未登录词,网络词等,是无法分出来的,这时可以自定义一个词典
seg_list = jieba.cut("郁惜时是创新办主任也是云计算方面的专家") # 没有加自定义词典
print(", ".join(seg_list))
-->
郁惜, 时, 是, 创新, 办, 主任, 也, 是, 云, 计算, 方面, 的, 专家
# 在我们的认知中,创新班 和 云计算 都应该作为一个词 拿出来,但是 jieba 中明显没有这两个词
# 现在想把它们当成一个词,就可以放到自定义词典里
jieba.load_userdict("userdict.txt")
seg_list = jieba.cut("郁惜时是创新办主任也是云计算方面的专家") # 添加自定义词典后
print()
print("这是自定义后的结果:")
print(", ".join(seg_list))
-->
这是自定义后的结果:
郁惜时, 是, 创新办, 主任, 也, 是, 云计算, 方面, 的, 专家
# 但是这里也有一些问题,计算机识别时,有些内容是没有用的废话,比如 的 地 也;这样也不影响句子表达
# 中文的有些代词和副词,在任务中,其实可以不要,比如 非常 特别等
# 在整个句子表达中,并没有起到非常关键的作用;所以是可以去掉的
# 去掉的这些词,用专业术语表示,就叫 停用词
1-3 去除停用词
# 停用词一般分词工具中是不包含的,分词工具只关注于分词;所以一般都是人为的去除
# 将停用词读出放在 stopwords 这个列表中
# 停用词表,一般不可以乱给,一般精确任务的停用词表,里面的每一个词都是筛选出来的
filepath = r'stopwords.txt'
# 这个 open 函数 open(filepath,'r',encoding='utf-8') 就相当于一个 f
# 将 filepath 中的内容,按行读取;line 是带有换行符的,所以用 strip()去除
stopwords = [line.strip() for line in open(filepath,'r',encoding='utf-8').readlines()]
set_list = jieba.cut("郁惜时是创新办主任也是云计算方面的专家") # 自定义词典保存在了结巴分词的缓存中
# 这是一个 带有判断的列表生成式,如果 if 为真,i 才可以被取出;
set_list = [i for i in seg_list if i not in stopwords] # 当分出来的词不再停用词表中时,我们保留它
print()
print("这是自定义后结果:")
print(", ".join(seg_list))
-->
这是自定义后结果:
郁惜时、创新办、主任、云计算、专家
部分代码解释说明:
1-3-1
# 带判断的列表生成式
In [95]: [i*2 for i in range(10) if i > 5]
Out[95]: [12, 14, 16, 18]
# 相当于
In [96]: a = []
In [97]: for i in range(10):
...: if i > 5:
...: a.append(i*2)
In [98]: a
Out[98]: [12, 14, 16, 18]
1-3-2
# 关于 readline 和 readlines 的用法
# 参考链接:https://blog.51cto.com/u_15149862/2791987 (2-5)
1-4 词性标注
# POS(Part-of-speech tagging) 在自然语言处理里,可以理解为一个强特征,比如 名词,形容词,代词等
# 词性一般也是使用分词工具进行标注
import jieba.posseg as pseg
words = pseg.cut("我爱北京*")
for w in words:
print(w.word, w.flag)
-->
我 r
爱 v
北京 ns
* ns
1-4-1
# 以下给出的是词性表
with open("tags.txt","r",encoding="utf-8") as f:
for i in f.readlines():
print(i.strip())
# 不同的分词工具,给出的词性表也不是完全一致的,但是差别不大
# 很多时候会把词性进行量化,作为文本特征进行输入