【手撕 - 自然语言处理】手撕 FastText 源码(02)基于字母的 Ngram 实现

本文详述了FastText中字母Ngram的实现原理,从源码角度解析了Ngram的生成及其如何融入模型。通过分析,揭示了FastText对中文词的subwords处理方式,并探讨了Ngram在词向量计算中的作用。
摘要由CSDN通过智能技术生成

作者:LogM

本文原载于 https://segmentfault.com/u/logm/articles ,不允许转载~

1. 源码来源

FastText 源码:https://github.com/facebookresearch/fastText

本文对应的源码版本:Commits on Jun 27 2019, 979d8a9ac99c731d653843890c2364ade0f7d9d3

FastText 论文:

[1] P. Bojanowski, E. Grave, A. Joulin, T. Mikolov, Enriching Word Vectors with Subword Information

[2] A. Joulin, E. Grave, P. Bojanowski, T. Mikolov, Bag of Tricks for Efficient Text Classification

2. 概述

之前的博客介绍了"分类器的预测"的源码,里面有一个重点没有详细展开,就是"基于字母的 Ngram 是怎么实现的"。这块论文里面关于"字母Ngram的生成"讲的比较清楚,但是对于"字母Ngram"如何加入到模型中,讲的不太清楚,所以就求助于源码,源码里面把这块叫做 Subwords

看懂了源码其实会发现 Subwords 加入到模型很简单,就是把它和"词语"一样对待,一起求和取平均。

另外,我自己再看源码的过程中还有个收获,就是关于"中文词怎么算subwords",之前我一直觉得 Subwords 对中文无效,看了源码才知道是有影响的。

最后是词向量中怎么把 Subwords 加到模型。这部分我估计大家也不怎么关心,所以我就相当于写给我自己看的,解答自己看论文的疑惑。以skipgram为例,输入的 vector 和所要预测的 vector 都是单个词语subwords相加求和的结果。

3. 怎么计算 Subwords

之前的博客有提到,Dictionary::getLine 这个函数的作用是从输入文件中读取一行,并将所有的Id(包括词语的Id,SubWords的Id,WordNgram的Id)存入到数组 words 中。

首先我们要来看看 Subwords 的 Id 是怎么生成的,对应的函数是 Dictionary::addSubwords

// 文件:src/dictionary.cc
// 行数:378
int32_t Dictionary::getLine(
    std::istream& in,                       // `in`是输入的文件
    std::vector<int32_t>& words,            // `words`是所有的Id组成的数组(包括词语的id,SubWords的Id,WordNgram的Id)
    std::vector<int32_t>& labels) const {   // 因为FastText支持多标签,所以这里的`labels`也是数组
  std::vector<int32_t> word_hashes;
  std::string token;
  int32_t ntokens = 0;

  reset(in);
  words.clear();
  labels.clear();
  while (readWord(in, token)) {              // `token`
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值