自然语言处理手撕-FastText-源码02基于字母的-Ngram-实现FastTexts-subwords

作者: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 中。 ...

June 30, 2019 · 5 min · jiezi

自然语言处理手撕-FastText-源码01分类器的预测过程

作者:LogM 本文原载于 https://segmentfault.com/u/logm/articles ,不允许转载~ 1. 源码来源FastText 源码:https://github.com/facebookre... 本文对应的源码版本: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. 概述FastText 的论文写的比较简单,有些细节不明白,网上也查不到,所幸直接撕源码。 FastText 的"分类器"功能是用的最多的,所以先从"分类器的predict"开始挖。 3. 开撕先看程序入口的 main 函数,ok,是调用了 predict 函数。 // 文件:src/main.cc// 行数:403int main(int argc, char** argv) { std::vector<std::string> args(argv, argv + argc); if (args.size() < 2) { printUsage(); exit(EXIT_FAILURE); } std::string command(args[1]); if (command == "skipgram" || command == "cbow" || command == "supervised") { train(args); } else if (command == "test" || command == "test-label") { test(args); } else if (command == "quantize") { quantize(args); } else if (command == "print-word-vectors") { printWordVectors(args); } else if (command == "print-sentence-vectors") { printSentenceVectors(args); } else if (command == "print-ngrams") { printNgrams(args); } else if (command == "nn") { nn(args); } else if (command == "analogies") { analogies(args); } else if (command == "predict" || command == "predict-prob") { predict(args); // 这句是我们想要的 } else if (command == "dump") { dump(args); } else { printUsage(); exit(EXIT_FAILURE); } return 0;}再看 predict 函数,预处理的代码不用管,直接看 predict 的那行,调用了 FastText::predictLine。这里注意下,这是个 while 循环,所以FastText::predictLine 这个函数每次只处理一行。 ...

June 30, 2019 · 3 min · jiezi