news 2026/4/15 7:44:05

spaCy:Python与Cython中的高效文本处理库

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
spaCy:Python与Cython中的高效文本处理库

Introducing spaCy

spaCy 是一个用于 Python 和 Cython 文本处理的新库。之所以开发它,是因为我认为小公司在自然语言处理方面表现得很糟糕。或者更准确地说:小公司正在使用糟糕的 NLP 技术。

更新(2016年10月3日)
这篇文章展示了 spaCy 最初的发布公告,其中包含一些使用示例和基准测试。这些基准测试现已相当过时,但令人欣慰的是,其使用方式变化相对较小。在发布此公告之前,我在 spaCy 的初始设计上花了很长时间。其回报是 API 一直保持相当稳定。

要做好 NLP,你需要懂一点语言学,懂很多机器学习,并且几乎要了解最新的所有研究。符合这种描述的人很少加入小公司。他们中的大多数都刚毕业,囊中羞涩。如果他们不想留在学术界,就会加入某中心、某机构等。

最终结果是,除了科技巨头之外,商业 NLP 在过去十年中变化甚微。而在学术界,它已经完全改变了。质量有了惊人的提升,速度快了几个数量级。但学术代码总是 GPL 许可、缺乏文档、无法使用,或者三者兼具。你可以自己实现这些想法,但论文很难读懂,而且训练数据极其昂贵。那么你还剩下什么?一个常见的答案是 NLTK,它主要是作为教育资源编写的。除了分词器之外,其他部分都不适合生产环境使用。

我曾经认为 NLP 社区只需要做更多工作,将其发现传达给软件工程师。所以我写了两篇博客文章,解释如何编写一个词性标注器和解析器。两篇文章都反响不错,并且我的研究软件也引起了一些兴趣——尽管它完全没有文档,除了我之外对大多数人来说几乎无法使用。

于是六个月前,我辞去了博士后的工作,从那以后一直夜以继日地开发 spaCy。现在我很高兴地宣布一个 alpha 版本。

如果你是一家从事 NLP 的小公司,我认为 spaCy 会像是一个小奇迹。它是迄今为止发布的最快的 NLP 软件。完整的处理流水线每份文档只需 20 毫秒,包括准确的标注和解析。所有字符串都映射为整数 ID,词元链接到嵌入的词表示,一系列有用的特征被预先计算并缓存。

计算机不理解文本。这很不幸,因为网络主要由文本构成。

如果上述内容对你来说毫无意义,那么要点是:计算机不理解文本。这很不幸,因为网络几乎完全由文本构成。我们希望根据人们喜欢的其他文本来推荐文本。我们想缩短文本以在移动屏幕上显示。我们想要聚合、链接、过滤、分类、生成和纠正它。spaCy 提供了一个实用函数库,帮助程序员构建此类产品。它是商业开源软件:你可以选择在 AGPL 下使用它,或者以慷慨的条款购买商业许可证。

功能示例

假设你正在开发一个校对工具,或者可能是一个面向作家的 IDE。你被斯蒂芬·金的建议说服了,他认为副词不是你的朋友,所以你想高亮显示所有副词。我们将使用一个他认为特别糟糕的例子:

>>>importspacy.en>>>fromspacy.parts_of_speechimportADV>>># 加载流水线,并用一些文本调用它。>>>nlp=spacy.en.English()>>>tokens=nlp(u"‘Give it back,’ he pleaded abjectly, ‘it’s mine.’",tag=True,parse=False)>>>printu''.join(tok.string.upper()iftok.pos==ADVelsetok.stringfortokintokens)u‘Give it BACK,’ he pleaded ABJECTLY,‘it’s mine.

这很简单——但问题是我们也高亮了“back”。虽然“back”无疑是副词,但我们可能不想高亮它。如果我们的目标是标记可疑的文体选择,我们需要完善我们的逻辑。事实证明,只有特定类型的副词才是我们感兴趣的。

根据我们想要标记的确切词语,我们有很多方法可以做到这一点。排除像“back”和“not”这类副词的最简单方法是根据词频:这些词比典型的、文体指南所担心的方式副词要常见得多。

Lexeme.probToken.prob属性给出了该词的对数概率估计:

>>>nlp.vocab[u'back'].prob-7.403977394104004>>>nlp.vocab[u'not'].prob-5.407193660736084>>>nlp.vocab[u'quietly'].prob-11.07155704498291

(概率估计基于一个 30 亿词语料库的计数,并使用 Simple Good-Turing 方法平滑。)

因此,我们可以轻松地从我们的副词标记器中排除英语中最常见的 N 个词。现在让我们试试 N=1000:

>>>importspacy.en>>>fromspacy.parts_of_speechimportADV>>>nlp=spacy.en.English()>>># 查找第 N 个最常见词的对数概率>>>probs=[lex.probforlexinnlp.vocab]>>>probs.sort()>>>is_adverb=lambdatok:tok.pos==ADVandtok.prob<probs[-1000]>>>tokens=nlp(u"‘Give it back,’ he pleaded abjectly,‘it’s mine.)>>>printu''.join(tok.string.upper()ifis_adverb(tok)elsetok.stringfortokintokens)‘Give it back,’ he pleaded ABJECTLY,‘it’s mine.

根据我们想要标记的确切词语,我们还有许多其他方法可以完善逻辑。假设我们只想标记修饰类似于“pleaded”的词的副词。这很容易做到,因为 spaCy 为每个词加载了一个向量空间表示(默认是 Levy 和 Goldberg (2014) 生成的向量)。自然地,该向量以 numpy 数组的形式提供:

>>>pleaded=tokens[7]>>>pleaded.vector.shape(300,)>>>pleaded.vector[:5]array([0.04229792,0.07459262,0.00820188,-0.02181299,0.07519238],dtype=float32)

我们想根据词汇表中单词与“pleaded”的相似度对它们进行排序。测量两个向量相似度的方法有很多。我们将使用余弦度量:

>>>fromnumpyimportdot>>>fromnumpy.linalgimportnorm>>>cosine=lambdav1,v2:dot(v1,v2)/(norm(v1)*norm(v2))>>>words=[wforwinnlp.vocabifw.has_vector]>>>words.sort(key=lambdaw:cosine(w.vector,pleaded.vector))>>>words.reverse()>>>print('1-20',', '.join(w.orth_forwinwords[0:20]))1-20pleaded,pled,plead,confessed,interceded,pleads,testified,conspired,motioned,demurred,countersued,remonstrated,begged,apologised,consented,acquiesced,petitioned,quarreled,appealed,pleading>>>print('50-60',', '.join(w.orth_forwinwords[50:60]))50-60counselled,bragged,backtracked,caucused,refiled,dueled,mused,dissented,yearned,confesses>>>print('100-110',', '.join(w.orth_forwinwords[100:110]))100-110cabled,ducked,sentenced,perjured,absconded,bargained,overstayed,clerked,confided,sympathizes>>>print('1000-1010',', '.join(w.orth_forwinwords[1000:1010]))1000-1010scorned,baled,righted,requested,swindled,posited,firebombed,slimed,deferred,sagged>>>print('50000-50010',', '.join(w.orth_forwinwords[50000:50010]))50000-50010,fb,ford,systems,puck,anglers,ik,tabloid,dirty,rims,artists

如你所见,这些向量提供的相似性模型非常出色——仅凭一个原型词,我们在 1000 个词处仍然能得到有意义的结果!唯一的问题是列表中确实包含两个词簇:一个与“pleaded”的法律含义相关,另一个则指更一般的意义。理清这些簇是当前的一个活跃研究领域。

一个简单的解决方法是取几个词向量的平均值,并将其作为我们的目标:

>>>say_verbs=['pleaded','confessed','remonstrated','begged','bragged','confided','requested']>>>say_vector=sum(nlp.vocab[verb].vectorforverbinsay_verbs)/len(say_verbs)>>>words.sort(key=lambdaw:cosine(w.vector*say_vector))>>>words.reverse()>>>print('1-20',', '.join(w.orth_forwinwords[0:20]))1-20bragged,remonstrated,enquired,demurred,sighed,mused,intimated,retorted,entreated,motioned,ranted,confided,countersued,gestured,implored,interceded,muttered,marvelled,bickered,despaired>>>print('50-60',', '.join(w.orth_forwinwords[50:60]))50-60flaunted,quarrelled,ingratiated,vouched,agonized,apologised,lunched,joked,chafed,schemed>>>print('1000-1010',', '.join(w.orth_forwinwords[1000:1010]))1000-1010hoarded,waded,ensnared,clamoring,abided,deploring,shriveled,endeared,rethought,berate

这些词看起来确实像是金可能会因为作家为其添加副词而加以训斥的。回想一下,我们最初的副词高亮函数是这样的:

>>>importspacy.en>>>fromspacy.parts_of_speechimportADV>>># 加载流水线,并用一些文本调用它。>>>nlp=spacy.en.English()>>>tokens=nlp("‘Give it back,’ he pleaded abjectly, ‘it’s mine.’",tag=True,parse=False)>>>print(''.join(tok.string.upper()iftok.pos==ADVelsetok.stringfortokintokens))‘Give it BACK,’ he pleaded ABJECTLY,‘it’s mine.

我们想完善逻辑,以便只高亮修饰像“pleaded”这样富有表现力的沟通动词的副词。我们现在已经构建了一个代表这类词的向量,因此现在我们可以基于微妙的逻辑来高亮副词,根据我们的初始假设,聚焦于那些看起来在文体上最有问题的副词:

>>>importnumpy>>>fromnumpyimportdot>>>fromnumpy.linalgimportnorm>>>importspacy.en>>>fromspacy.parts_of_speechimportADV,VERB>>>cosine=lambdav1,v2:dot(v1,v2)/(norm(v1)*norm(v2))>>>defis_bad_adverb(token,target_verb,tol):...iftoken.pos!=ADV:...returnFalse...eliftoken.head.pos!=VERB:...returnFalse...elifcosine(token.head.vector,target_verb)<tol:...returnFalse...else:...returnTrue

这个例子有些刻意——而且说实话,我从来没有真正接受过副词是严重的文体罪过这个观点。但希望它能传达一个信息:最先进的 NLP 技术非常强大。spaCy 让你能够轻松高效地使用它们,从而构建各种以前不可能实现的有用产品和功能。

独立评估

某机构和某机构的独立评估,将在 ACL 2015 上发表。数值越高越好。
准确度是未标记弧正确的百分比,速度是每秒处理的词元数。

系统语言准确度速度
spaCy v0.86Cython91.913,963
ClearNLPJava91.710,271
spaCy v0.84Cython90.913,963
CoreNLPJava89.68,602
MATEJava92.5550
TurboC++92.4349
YaraJava92.3340

某机构的多位研究者和某机构的一位教授对现有最佳解析器进行了详细比较。以上所有数字均取自他们慷慨提供给我的预印本,除了 spaCy v0.86 的数据。

我特别感谢作者们对结果的讨论,这促成了 v0.84 到 v0.86 之间准确度的提升。来自 Jin-ho(ClearNLP 的开发者)的一个建议尤其有用。

详细速度对比

每文档处理时间。越低越好。
设置:10 万份纯文本文档从 SQLite3 数据库流式传输,并用 NLP 库处理到三个细节级别之一——分词、标注或解析。这些任务是累加的:要解析文本,你必须先对其进行分词和标注。预处理时间未从总时间中减去——我报告的是流水线完成所需的时间。我报告的是每文档的平均时间,单位为毫秒。
硬件:Intel i7-3770 (2012)

绝对(每文档毫秒)

系统分词标注解析
spaCy0.2ms1ms19ms
CoreNLP2ms10ms49ms
ZPar1ms8ms850ms
NLTK4ms443msn/a

相对(相对于 spaCy)

系统分词标注解析
spaCy1x1x1x
CoreNLP10x10x2.6x
ZPar5x8x44.7x
NLTK20x443xn/a

效率是 NLP 应用的一个主要关注点。经常听到人们说他们无法承担更详细的处理,因为他们的数据集太大了。这是一个糟糕的处境。如果你不能应用详细处理,通常不得不拼凑各种启发式方法。这通常需要多次迭代,而且你想出来的东西通常是脆弱的,难以推理。

spaCy 的解析器比大多数标注器都快,其分词器对于任何工作负载来说都足够快。而且分词器不仅仅给你一个字符串列表。spaCy 的词元是一个指向 Lexeme 结构体的指针,从中你可以访问一系列预先计算的特征,包括嵌入的词表示。

关于作者

Matthew Honnibal
首席技术官,创始人

Matthew 是 AI 技术领域的领先专家。他于 2009 年获得博士学位,随后又花了 5 年时间发表关于最先进 NLP 系统的研究。他于 2014 年离开学术界,编写 spaCy 并创立了 Explosion。FINISHED
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)或者 我的个人博客 https://blog.qife122.com/
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/3 7:25:08

基于peakcan/PCAN UDS上位机 (14229/15765) 可以开发UDS小工具

基于peakcan/PCAN UDS上位机 (14229/15765) 可以开发UDS小工具 新增支持CANFD的数据链路层通信最近在折腾汽车电子诊断工具开发&#xff0c;发现基于peakcan/PCAN硬件配合UDS协议栈搞上位机开发真是块宝藏。特别是支持CANFD之后&#xff0c;诊断效率直接起飞。今天就跟大家唠唠…

作者头像 李华
网站建设 2026/4/6 1:32:44

计算机技术与科学毕设易上手课题建议

文章目录 &#x1f6a9; 1 前言1.1 选题注意事项1.1.1 难度怎么把控&#xff1f;1.1.2 题目名称怎么取&#xff1f; 1.2 选题推荐1.2.1 起因1.2.2 核心- 如何避坑(重中之重)1.2.3 怎么办呢&#xff1f; &#x1f6a9;2 选题概览&#x1f6a9; 3 项目概览题目1 : 基于协同过滤的…

作者头像 李华
网站建设 2026/4/13 11:37:28

Wallpaper Engine V2.5.28 离线版 + 30G精选壁纸资源(有彩蛋)

软件所在目录&#xff1a; 软件下载地址 直接扫一扫获取 备用地址 软件介绍 这是一款功能强大的PC动态壁纸工具&#xff0c;老司机们想必早已得心应手&#xff0c;尤其是创意工坊中那些隐藏内容&#xff0c;更是让人大开眼界。 首先&#xff0c;这个最新的Wallpaper Engine…

作者头像 李华
网站建设 2026/4/12 2:05:23

2026必备!8个降AIGC网站 千笔帮你高效降AI率

AI降重工具&#xff1a;让论文更自然&#xff0c;更专业 在当今学术写作中&#xff0c;AI生成内容&#xff08;AIGC&#xff09;已成为一种常见现象。然而&#xff0c;随着各大高校和期刊对AI痕迹的敏感度不断提升&#xff0c;如何有效降低AIGC率、去除AI痕迹并保持语义通顺&am…

作者头像 李华
网站建设 2026/4/12 9:33:55

学员焕发第二春,这个月收入破7000+

独孤实操AI项目&#xff0c;已经有一段时间了。 带的团队和学员。 来自各行各业的。 其中有个学员&#xff0c;之前做餐饮服务员。 加入AI项目前&#xff0c;问东问西。 问的问题很幼稚&#xff0c;独孤都不想理他了。 但是他对这个项目很坚持。 非要付费报名参加。 没…

作者头像 李华
网站建设 2026/4/10 22:20:00

保姆级教程:ccmusic-database/music_genre音乐分类Web应用部署

保姆级教程&#xff1a;ccmusic-database/music_genre音乐分类Web应用部署 1. 这个应用到底能帮你做什么&#xff1f; 你有没有遇到过这样的场景&#xff1a; 收到一段朋友发来的无名音频&#xff0c;听了几秒却猜不出是爵士还是电子&#xff1f;做音乐推荐系统时&#xff0…

作者头像 李华