前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python实战 | 100毫秒过滤一百字万字文本的停用词

Python实战 | 100毫秒过滤一百字万字文本的停用词

作者头像
快学Python
发布2021-08-09 10:40:17
1K0
发布2021-08-09 10:40:17
举报
文章被收录于专栏:快学Python

小小明,「快学Pthon」专栏作者

之前有位群友分享了使用Pandas过滤停用词的技巧:

不过其实这并不是效率最高的一种方法,今天我将演示一种更高效过滤停用词的方法。

本文目录

  • 过滤停用词前的准备工作
    • 数据读取
    • jieba分词器设置角色为特定词汇
    • 开始分词
    • 加载停用词
  • 过滤停用词的n种方法性能对比
    • 直接过滤
    • 使用Pandas进行停用词过滤
    • 使用set集合过滤
  • 速度最快的过滤方法
  • 总结

过滤停用词前的准备工作

这次我打算用一部127W字的小说——《天龙八部》作为数据示例,这样能更好表现出效率高不高

数据读取

首先,我们读取这部小说的数据:

代码语言:javascript
复制
with open(r"D:\hdfs\novels\天龙八部.txt", encoding="gb18030") as f:
    text = f.read()
print(len(text))

结果:

代码语言:javascript
复制
1272432

可见这部小说共127.2万字。

下面我们对它进行分词并加载停用词:

jieba分词器设置角色为特定词汇

为了避免jieba分词库不能将主角正确的切词,所以现在我们需要将这部小说的角色名称加入到jieba的分词表中。

首先,加载《天龙八部》小说的角色名称:

代码语言:javascript
复制
with open('D:/hdfs/novels/names.txt', encoding="utf-8") as f:
    for line in f:
        if line.startswith("天龙八部"):
            names = next(f).split()
            break

print(names[:20])

前20个角色为:

代码语言:javascript
复制
['刀白凤', '丁春秋', '马夫人', '马五德', '小翠', '于光豪', '巴天石', '不平道人', '邓百川', '风波恶', '甘宝宝', '公冶乾', '木婉清', '包不同', '天狼子', '太皇太后', '王语嫣', '乌老大', '无崖子', '云岛主']

设置角色到特定词汇中:

代码语言:javascript
复制
import jieba
for word in names:
    jieba.add_word(word)

提示了一些警告信息:

代码语言:javascript
复制
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\Think\AppData\Local\Temp\jieba.cache
Loading model cost 0.759 seconds.
Prefix dict has been built successfully.

开始分词

然后对原始文本进行中文分词:

代码语言:javascript
复制
%time cut_word = jieba.lcut(text)
代码语言:javascript
复制
Wall time: 6 s

中文分词耗时6秒。

加载停用词

然后加载停用词:

代码语言:javascript
复制
#  加载停用词
with open("stoplist.txt", encoding="utf-8-sig") as f:
    stop_words = f.read().split()
stop_words.extend(['天龙八部', '\n', '\u3000', '目录', '一声','之中', '只见'])
print(len(stop_words), stop_words[:10])
代码语言:javascript
复制
5748 ['说', '人', '元', 'hellip', '&', ',', '?', '、', '。', '"']

过滤停用词的n种方法性能对比

直接过滤

代码语言:javascript
复制
%%time
all_words = [word for word in cut_word if len(word) > 1 and word not in stop_words]
print(len(all_words), all_words[:20])

结果:

代码语言:javascript
复制
300656 ['释名', '青衫', '磊落', '险峰', '玉壁', '月华', '马疾香幽', '高人远', '微步', '纹生', '谁家', '子弟', '谁家', '无计悔', '多情', '虎啸', '龙吟', '换巢', '鸾凤', '剑气']
Wall time: 26.2 s

直接过滤耗时26.2秒

使用Pandas进行停用词过滤

代码语言:javascript
复制
%%time
words = pd.Series(cut_word)
all_words = words[(words.str.len() > 1) & (~words.isin(stop_words))].tolist()
print(len(all_words), all_words[:20])

结果:

代码语言:javascript
复制
300656 ['释名', '青衫', '磊落', '险峰', '玉壁', '月华', '马疾香幽', '高人远', '微步', '纹生', '谁家', '子弟', '谁家', '无计悔', '多情', '虎啸', '龙吟', '换巢', '鸾凤', '剑气']
Wall time: 465 ms

耗时0.46秒

使用set集合过滤

代码语言:javascript
复制
%%time
stop_words = set(stop_words)
all_words = [word for word in cut_word if len(word) > 1 and word not in stop_words]
print(len(all_words), all_words[:20])

结果:

代码语言:javascript
复制
300656 ['释名', '青衫', '磊落', '险峰', '玉壁', '月华', '马疾香幽', '高人远', '微步', '纹生', '谁家', '子弟', '谁家', '无计悔', '多情', '虎啸', '龙吟', '换巢', '鸾凤', '剑气']
Wall time: 104 ms

耗时0.1秒

速度最快的过滤方法

虽然我们过滤停用词使用set集合过滤更快,但是我们并没有考虑一开始分词过程所消耗的时间,分词耗时达到6秒的时间,有没有办法降低这个时间呢?

先看看使用set集合的情况,分词过滤的整体耗时:

代码语言:javascript
复制
%%time

all_words = [word for word in jieba.cut(text) if len(word) > 1 and word not in stop_words]
print(len(all_words), all_words[:20])

结果:

代码语言:javascript
复制
300656 ['释名', '青衫', '磊落', '险峰', '玉壁', '月华', '马疾香幽', '高人远', '微步', '纹生', '谁家', '子弟', '谁家', '无计悔', '多情', '虎啸', '龙吟', '换巢', '鸾凤', '剑气']
Wall time: 5.91 s

耗时5.9s秒。

但假如我们一开始就将停用词从原始文本中去掉会不会更快点呢?

代码语言:javascript
复制
%%time

text_sub = text
for stop_word in stop_words:
    text_sub = text_sub.replace(stop_word, " ")
all_words = [word for word in jieba.cut(text_sub) if len(word) > 1]
print(len(all_words), all_words[:20])

结果:

代码语言:javascript
复制
174495 ['天龙', '释名', '青衫', '磊落', '险峰', '玉壁', '月华', '马疾香幽', '微步', '纹生', '子弟', '家院', '计悔', '虎啸', '龙吟', '换巢', '鸾凤', '剑气', '碧烟', '水榭']
Wall time: 5.76 s

整体耗时5.7秒。

速度稍微提升了一丁点儿,区别不大,结果差异还挺大,所以还是使用set集合来过滤比较好一点。

总结

综上所述,中文分词过滤停用词时,使用set集合即可获得最好的性能。

感谢各位读者的陪伴,明天我们将分享 词频统计的3种方法字典与集合的原理

咱们不见不散,求个三连,下期再见~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 快学Python 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 过滤停用词前的准备工作
    • 数据读取
      • jieba分词器设置角色为特定词汇
        • 开始分词
          • 加载停用词
          • 过滤停用词的n种方法性能对比
            • 直接过滤
              • 使用Pandas进行停用词过滤
                • 使用set集合过滤
                • 速度最快的过滤方法
                • 总结
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档