V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
v2zero
V2EX  ›  Python

Python 如何高效的在大量文本里面搜索匹配大量词

  •  1
     
  •   v2zero · 2020-04-04 18:27:04 +08:00 · 4315 次点击
    这是一个创建于 1476 天前的主题,其中的信息可能已经有所发展或是发生改变。

    数千万篇文章,寻找其中包含成语的句子。成语有数万条。

    目前没有对文章内容建立过全文索引,鉴于这个事情是一次性的,为此搞个索引可能也成本过高。

    暂时的解决方案是,把成语都放在一条 re.compile('乌合之众|鸡犬相闻|...')里面去搜索文章,但效率总觉得不理想。

    求教,是否可能有更高效的解决方案。

    14 条回复    2020-04-11 21:11:10 +08:00
    superrichman
        1
    superrichman  
       2020-04-04 18:36:41 +08:00 via iPhone
    文章内容很长的话,正则的效率是很低的。全文搜索还是要用 elasticsearch 或者 solr 比较靠谱。
    fishCatcher
        2
    fishCatcher  
       2020-04-04 18:38:40 +08:00 via iPhone   ❤️ 3
    AC 自动机
    ClericPy
        3
    ClericPy  
       2020-04-04 19:06:58 +08:00   ❤️ 1
    直接套 AC 自动机, 专门搞敏感词过滤和发现的, 现成的库就挺快了, 貌似是 C 写的给 py 调

    套正则, 四五万字的 "或" 条件, 还不如直接用 Python 字符串的 for 和 in
    ypw
        4
    ypw  
       2020-04-04 19:08:11 +08:00
    成语长度固定四个字的话,建一个集合 set,然后暴力搜也是可以的,复杂度 O(n),与成语集合大小无关。
    v2zero
        5
    v2zero  
    OP
       2020-04-04 19:10:24 +08:00
    @fishCatcher 感动,一个词解决一个大难题。业余写代码,自己也实现不了这种东西,网上找了个 Python 实现。原来预计一周多的运行时间,瞬间就缩减到一天了。
    v2zero
        6
    v2zero  
    OP
       2020-04-04 19:11:35 +08:00
    @ypw 成语这种东西吧,有的还带逗号。。。也挺麻烦的
    v2zero
        7
    v2zero  
    OP
       2020-04-04 19:12:58 +08:00
    @ClericPy 以前自己做了个敏感词过滤,就是用的正则,现在看来还是蛮蠢的了。
    superrichman
        8
    superrichman  
       2020-04-04 19:16:39 +08:00 via iPhone
    @fishCatcher
    @ClericPy
    涨知识了,感谢
    ClericPy
        9
    ClericPy  
       2020-04-04 20:02:13 +08:00
    @v2zero #7 这事我实习时候干过啊... 不过不是用竖线, 用的是超长裹脚布版的零宽断言...... 后来发现还不如一个个 in 去判断呢...

    @superrichman #8 你这么提问其实挺好的, 背景, 思路, 自己的尝试, 甚至没什么语文错误
    上次见一个类似的需求, 说了一大堆自己的思路, 实际一开始就跑偏了, 带着起码二十多楼跟着歪了, 哈哈, 共同学习
    lithbitren
        10
    lithbitren  
       2020-04-04 20:29:40 +08:00 via iPhone
    @ClericPy 带佬,有稳定好用 py3 支持 utf8 的 ac 自动机 c 拓展嘛,我之前没找到,自己用纯 py 手撕了一个,算法上应该优化到极限了,但 40 万词启动还建树是用了两秒多,查词还好基本忽略不计了,用起来没啥问题,就是启动太难。
    ClericPy
        11
    ClericPy  
       2020-04-04 20:56:13 +08:00
    @lithbitren #10 你手撸已经比我强多了... 我都五六年没动 NLP 的东西了...
    lithbitren
        12
    lithbitren  
       2020-04-05 22:32:48 +08:00
    说起来,当时找 ac 自动机解决方案还是有坑的,py 的对于复杂算法的模板不多,csdn 上搜到的 py 的 ac 自动机是有问题,建树竟然用 remove 首元素来处理队列,让队列处理在 c 层面的时间复杂度变成了 O(N^2),小规模的屏蔽词过滤看不出啥,大规模词语处理时间会陡增,40 万词要处理将近四分钟,不过改数据解构用 deque 和 popleft 大概就好了。另外搜到过 2 个 pipy 上的开源库,一个是 py2 时代的,一个是重叠的关键字词输出会有问题,最后才决定手撸的。。
    qsnow6
        13
    qsnow6  
       2020-04-11 17:33:22 +08:00
    @v2zero #7
    之前在过滤 black list 时找过相关的资料,长文本的搜索适合上 AC 自动机。短文本建议直接 x in s 就完事了,Python 编译器做了优化,效率更快,写起来也方便。

    可以看这个答案: https://stackoverflow.com/questions/3389574/check-if-multiple-strings-exist-in-another-string#comment105454320_3389574

    PS:楼主是做 SEO 的?可以加个好友交流下啊,我平时接触爬虫、数据清洗、NLP 这些领域比较多。
    v2zero
        14
    v2zero  
    OP
       2020-04-11 21:11:10 +08:00
    @qsnow6 过于明显了么。微信,去空格: 182 1055 2814
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3428 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 10:39 · PVG 18:39 · LAX 03:39 · JFK 06:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.