数千万篇文章,寻找其中包含成语的句子。成语有数万条。
目前没有对文章内容建立过全文索引,鉴于这个事情是一次性的,为此搞个索引可能也成本过高。
暂时的解决方案是,把成语都放在一条 re.compile('乌合之众|鸡犬相闻|...')里面去搜索文章,但效率总觉得不理想。
求教,是否可能有更高效的解决方案。
1
superrichman 2020-04-04 18:36:41 +08:00 via iPhone
文章内容很长的话,正则的效率是很低的。全文搜索还是要用 elasticsearch 或者 solr 比较靠谱。
|
2
fishCatcher 2020-04-04 18:38:40 +08:00 via iPhone 3
AC 自动机
|
3
ClericPy 2020-04-04 19:06:58 +08:00 1
直接套 AC 自动机, 专门搞敏感词过滤和发现的, 现成的库就挺快了, 貌似是 C 写的给 py 调
套正则, 四五万字的 "或" 条件, 还不如直接用 Python 字符串的 for 和 in |
4
ypw 2020-04-04 19:08:11 +08:00
成语长度固定四个字的话,建一个集合 set,然后暴力搜也是可以的,复杂度 O(n),与成语集合大小无关。
|
5
v2zero OP @fishCatcher 感动,一个词解决一个大难题。业余写代码,自己也实现不了这种东西,网上找了个 Python 实现。原来预计一周多的运行时间,瞬间就缩减到一天了。
|
8
superrichman 2020-04-04 19:16:39 +08:00 via iPhone
|
9
ClericPy 2020-04-04 20:02:13 +08:00
@v2zero #7 这事我实习时候干过啊... 不过不是用竖线, 用的是超长裹脚布版的零宽断言...... 后来发现还不如一个个 in 去判断呢...
@superrichman #8 你这么提问其实挺好的, 背景, 思路, 自己的尝试, 甚至没什么语文错误 上次见一个类似的需求, 说了一大堆自己的思路, 实际一开始就跑偏了, 带着起码二十多楼跟着歪了, 哈哈, 共同学习 |
10
lithbitren 2020-04-04 20:29:40 +08:00 via iPhone
@ClericPy 带佬,有稳定好用 py3 支持 utf8 的 ac 自动机 c 拓展嘛,我之前没找到,自己用纯 py 手撕了一个,算法上应该优化到极限了,但 40 万词启动还建树是用了两秒多,查词还好基本忽略不计了,用起来没啥问题,就是启动太难。
|
11
ClericPy 2020-04-04 20:56:13 +08:00
@lithbitren #10 你手撸已经比我强多了... 我都五六年没动 NLP 的东西了...
|
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 时代的,一个是重叠的关键字词输出会有问题,最后才决定手撸的。。
|
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 这些领域比较多。 |