词向量源码解析:(2.2)word2vec源码解析之word2phrase

本文详细解析了word2phrase.c源码,该代码用于从语料中识别常用短语。通过计算共同出现次数和单独出现次数来判断短语,例如将'New York'视为一个整体。文章介绍了词汇表的构建过程,包括读取文件、计算哈希值、处理哈希冲突、添加单词到词汇表等步骤,以及如何通过互信息判断短语。最后,代码展示了如何通过word2phrase和word2vec进行短语和词向量的生成。
摘要由CSDN通过智能技术生成

  我们首先过一遍源码word2phrase.c。这个源码中的很多内容和word2vec.c中的源码是共用的,可以之后方便我们理解word2vec.c。这个代码的的思想很简单,就是希望找出语料中的短语。比如New York这个短语,如果我们把它当做两个单词分开处理显然不合适。这里从语料中找短语的基本思想和和互信息的思想很相似,需要考虑两方面的信息,第一个方面是两个单词,比如New和York,在这个语料中共同出现的次数。如果两个单词基本就没有在语料中以New York这样的形式出现过,那么显然New York就不是常用短语了。另外还需要考虑两个单词在语料中单独出现的次数。像of the在语料中肯定大量的出现,但是他们并不是短语。这两个单词本身单独就会在语料中大量的出现。这也导致他们碰巧一块出现的次数也会非常的多。

单词用结构体表示,记录了单词以及其在语料中出现的次数

struct vocab_word {
  long long cn;
  char *word;
};

一些全局变量,有的后面会说它们的含义

char train_file[MAX_STRING], output_file[MAX_STRING];//输入文件名和输出文件名 这个代码的功能就是把输入的语料过滤一遍,输出把单词整合成phrase的语料
struct vocab_word *vocab;//字典,保存所有单词以及他们在语料中出现的次数
int debug_mode = 2, min_count = 5, *vocab_hash, min_reduce = 1;
long long vocab_max_size = 10000, vocab_size = 0;
long long train_words = 0;//已经处理的单词或是叫token的数量
real threshold = 100;

首先从main函数看起

vocab = (struct vocab_word *)calloc(vocab_max_size, sizeof(struct vocab_word));//为字典分配空间

vocab_hash = (int *)calloc(vocab_hash_size, sizeof(int));//由于C语言中没有python中字典(dict)这样的数据结构,所以这里是自己实现的。vocab_hash记录了hash值和vocab_word字典中的位置的对应关系

TrainModel();//开始训练

TrainModel函数中的代码:

long long pa = 0, pb = 0, pab = 0, oov, i, li = -1, cn = 0;
char word[MAX_STRING], last_word[MAX_STRING], bigram_word[MAX_STRING * 2];
real score;
FILE *fo, *fin;
printf("Starting training using file %s\n", train_file);
LearnVocabFromTrainFile();
fin = fopen(train_file, "rb");
fo = fopen(output_file, "wb");
word[0] = 0;

上面这些代码声明了一些变量,打开了输入和输出文件。最重要的代码就是LearnVocabFromTrain();它的功能是建立字典一般做自然语言问题第一件事都是要过一遍语料建立字典。这部分代码和word2vec.c中是一模一样的。下面仔细讲解一下如何建立字典。

字典的数据结构有单词结构体数组vocab以及int数组vocab_hash。C语言中没有python中字典数据结构所以这里是自己实现的。当我们要找到一个单词,想知道字典中有没有这个单词以及它的id的时候,首先计算这个单词的哈希值。比如是15,vocab_hash[15]中就记录了这个单词在vocab中的位置。比如vocab[15]=100,那么我们就直接知道了这个单词的id是100,以及vocab[100]中就存了单词的以及它的频数。如果vocab[15]=-1那么这个单词不在字典中,我们会进行插入等操作。还有可能几个单词有一样的哈希值,后面介绍代码的时候会介绍如何处理这种情况。

ReadWord函数从文件中读取一个单词。一个一个字符的读,遇到空格,\t,\n,或是文件结束就代表单词已经读完了,word[a] = 0;C语言中字符串最后一位为0,表示字符串结束

void ReadWord(char *word, FILE *fin) {
  int a = 0, ch;
  while (!feof(fin)) {
    ch = fgetc(fin);
    if (ch == 13) continue;
    if ((ch == ' ') || (ch == '\t') || (ch == '\n')) {
      if (a > 0) {

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值