使用spaCy进行大规模数据分析

数据结构 (1): Vocab, Lexemes和StringStore

  • Vocab: 存储那些多个文档共享的数据
  • 为了节省内存使用,spaCy将所有字符串编码为哈希值
  • 字符串只在StringStore中通过nlp.vocab.strings存储一次。
  • 字符串库:双向的查询表
  • 哈希是不能逆求解的,所以我们要提供共享词汇表。
  • nlp.vocab.strings中查找字符串和哈希值
  • doc也会暴露出词汇表和字符串

Lexemes: 词汇表中的元素

  • 一个Lexeme实例是词汇表中的一个元素
  • 包含了一个词的和语境无关的信息
    • 词组的文本:lexeme.textlexeme.orth(哈希值)
    • 词汇的属性如lexeme.is_alpha
    • 并不包含和语境相关的词性标注、依存关系和实体标签

Vocab, 哈希值和语素

'I'、'love'和'coffee'三个词在Doc、Vocab和StringStore中的图解

从字符串到哈希值

  • nlp.vocab.strings中查找字符串”猫”来得到哈希值。
  • 查找这个哈希值来返回原先的字符串。

返回结果如下

  • nlp.vocab.strings中查找字符串标签”PERSON”来得到哈希值。
  • 查找这个哈希值来返回原先的字符串。

返回结果如下

数据结构(2):Doc、Span和Token

Doc是spaCy的核心数据结构之一。 当我们用nlp实例来处理文本时Doc就会被自动创建, 当然我们也可以手动初始化这个类。

创建nlp实例之后,我们就可以从spacy.tokens中导入Doc类。

这个例子中我们用了三个词来创建一个doc。空格存储在一个布尔值的列表中, 代表着对应位置的词后面是否有空格。每一个词符都有这个信息,包括最后一个词符!

Doc类有三个参数:共享的词汇表,词汇和空格。

创建一个Doc

  • spacy.tokens中导入Doc
  • wordsspaces创建一个Doc。别忘了把vocab传进去!

返回结果如下

从头开始练习Docs(文档), spans(跨度)和entities(实体)

  • spacy.tokens中导入DocSpan
  • Doc类使用词组和空格直接创建一个doc实例。
  • doc实例创建一个”David Bowie”的Span,赋予它"PERSON"的标签。
  • 用一个实体的列表,也就是”David Bowie” span,来覆盖doc.ents

返回结果如下

数据结构最佳实践

  • doc中遍历每一个token并检查其token.pos_属性。
  • doc[token.i + 1]来检查下一个词符及其.pos_属性
  • 如果找到一个处于动词前的专有名词,我们就打印其token.text

返回结果如下

词向量和语义相似度

  • spaCy可以对比两个实例来判断它们之间的相似度
  • Doc.similarity()Span.similarity()Token.similarity()
  • 使用另一个实例作为参数返回一个相似度分数(在01之间)
  • 注意:我们需要一个含有词向量的流程,比如:
    • ✅ en_core_web_md (中等)
    • ✅ en_core_web_lg (大)
    • 🚫 而不是 en_core_web_sm (小)
  • 相似度是通过词向量计算的
  • 词向量是一个词汇的多维度的语义表示
  • 词向量是用诸如Word2Vec 这样的算法在大规模语料上面生成的
  • 词向量可以是spaCy流程的一部分
  • 默认我们使用余弦相似度,但也有其它计算相似度的方法
  • DocSpan的向量默认是由其词符向量的平均值计算得出的
  • 短语的向量表示要优于长篇文档,因为后者含有很多不相关的词

检查词向量

  • 读取中等大小的"zh_core_web_md"流程,该流程含有词向量
  • token.vector属性来打印"老虎"的向量。

返回结果如下

比对相似度

使用doc.similarity方法来比较doc1doc2的相似度并打印结果。

返回结果如下

使用token.similarity方法来比较token1token2的相似度并打印结果。

返回结果如下

  • 为”不错的餐厅”/“很好的酒吧”创建跨度(span)。
  • 使用span.similarity来比较它们并打印结果。

返回结果如下

流程和规则的结合

如果你的应用需要能够根据一些例子而进行泛化,那么统计模型会很有用。

举个例子,训练好的流程通常可以优化产品和人名的识别。 相比于给出一个所有曾经出现过的人名库,你的应用可以判断一段文本中的几个词符是否是人名。 相类似的你也可以预测依存关系标签从而得到主宾关系。

我们可以使用spaCy的实体识别器、依存句法识别器或者词性标注器来完成这些任务。

当我们要查找的例子差不多是有限个的时候,基于规则的方法就变得很有用。比如世界上所有的国家名或者城市名、药品名或者甚至狗的种类。

在spaCy中我们可以用定制化的分词规则以及matcher和phrase matcher这样的匹配器来完成这些任务。

在上一章中,我们学过如何用spaCy的基于规则的匹配器matcher来查找文本中的复杂模板。 这里我们简单回顾一下。

matcher由一个共享词汇表(通常是nlp.vocab)来初始化。

模板是一个元素为字典的列表,每个字典代表了一个词符及其属性。 模板可以用matcher.add添加到matcher中。

运算符可以定义一个词符应该被匹配多少次,比如"+"表示可以匹配一次或者更多次。

在doc实例上调用matcher会返回一个匹配结果的列表。每一个匹配结果是一个元组, 其中包括一个ID以及文档中的词符的起始和终止索引。

短语匹配器phrase matcher是另一个在数据中查找词语序列的非常有用的工具。

短语匹配器也是在文本中做关键词查询,但不同于仅仅寻找字符串,短语匹配器可以直接读取语义中的词符。

短语匹配器将Doc实例作为模板。

短语匹配器也非常快。

所以当我们要在大规模语料中匹配一个很大的字典和词库时这就很有用。

模板调试

  • 编辑pattern1使其可以正确匹配到所有的形容词后面跟着"笔记本"
  • 编辑pattern2使其可以正确匹配到"锐龙"加上后面的数字 (LIKENUM) 和符号 (ISASCII) 。

返回结果如下

高效率的短语匹配

  • 导入PhraseMatcher并用含有共享vocab的变量matcher来初始化。
  • 加入短语模板并在’doc’上面调用matcher

返回结果如下

提取国家和关系

  • 对匹配结果进行遍历, 创建一个标签为"GPE"(geopolitical entity,地理政治实体)的Span
  • 覆盖doc.ents中的实体,加入匹配到的跨度span。
  • 获取匹配到的跨度span中的根词符的头。
  • 打印出词符头和跨度span的文本。

返回结果如下

LEAVE A REPLY

游客评论不支持回复他人评论内容,如需回复他人评论内容请