训练一个词向量空间

 

word2vec (四) 动手训练一个词向量空间

开源的word2vec工具已经有不少了,可以直接使用google开源的C版本,也可以用gensim版本的。这里我就用gensim的word2vec来训练一个词向量空间。

训练语料输入

gensim word2vec的API接受一系列的句子作为输入语料,其中每一个句子是一系列词构成的list。如下所示

import gensim

sentences = [['ios','android'],['apple','google','xiaomi']]

model = gensim.models.Word2Vec(sentences)
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

将语料都转换为一个Python的list作为输入是很方便,但是如果输入的语料特别大,大到内存都装不下,就不能采用这种方式。gensim的API并不要求sentences必须是list对象,只要输入的sentences是iterable的就行,那我们只要一次载入一个句子,训练完之后再将其丢弃,内存就不会因为语料过大而不够了。我们通过下面的代码就可以生成一个iterator。事先已经将训练语料分词,词与词之间采用空格分开,并保存在一个文档里。

class sentences_generator():
    def __init__(self, filename):
        self.filename = filename

    def __iter__(self):
        for line in open(self.filename):
            sentence = line.rstrip().split(' ')
            yield sentence
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

其实用一个函数也可以生成一个迭代器,只不过函数生成的迭代器迭代一轮就失效了,而这里需要迭代多轮。第一轮统计词频,用于生成哈夫曼树。后续用于训练,因此封装成一个类。

训练

准备好语料以后就可以开始训练了,示例代码如下

sentences = sentences_generator('corpus_words.dat')

model = gensim.models.Word2Vec(sentences, size=200, workers=4)

  
  
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

备注:采用的语料是在知乎上抓取的100个topic下的问题,在文末会给出原始语料与分词后语料的网盘地址,感兴趣的可以下载玩玩。

gensim.models.Word2Vec() 有一系列的参数,常用的如下

  • size 定义词向量的维度,默认是100
  • alpha 初始的学习率,随着训练的进行,逐渐减少至0
  • window 扫描句子的窗口大小,默认值为5
  • min_count 过滤掉一些低频词,如果一个词在整个语料库里出现的次数小于min_count,在训练的时候就不考虑这个词。
  • max_vocab_size 限制一下词汇表的数量,避免太多词占用太多内存,默认为None
  • workers 训练模型的线程
  • sg 训练采用的算法,sg=0 采用CBOW,sg=1采用skip-gram
  • hs 为1的时候采用hierarchical softmax,如果为0且negative也非0,则采用negative sampling方案
  • negative negative sampling的词数,通常是5-20
  • cbow_mean 0或1。如果为0,则隐层为输入层的SUM,为1隐层为输入层向量的均值。
  • iter 迭代遍历语料库的次数,默认值为5

其中,worker参数仅在安装了Cython是有用的,没有Cython由于python的GIL的原因只能用单核。

保存与加载模型

训练好以后可以保存模型用于以后使用。代码如下

model.save('w2v_model')

new_model = gensim.models.Word2Vec.load('w2v_model')
  
  
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

看看效果

可以看看基于那些比较少的语料训练出来的效果如何

这里写图片描述

这里写图片描述

查看了与’iOS’和’av’比较相似的词,结果看起来还挺有意思的

语料

原始语料 http://pan.baidu.com/s/1nviuFc1

训练语料 http://pan.baidu.com/s/1kVEmNTd


词向量是一种将单映射到向量空间中的技术,它可以用于自然语言处理中的诸多任务,例如文本分类、机器翻译等。在Go语言中,我们可以使用Gonum库来实现词向量。 首先,我们需要定义一个词向量类型: ``` type WordVector struct { Words []string Vectors [][]float64 } ``` 其中,`Words`表示汇表,`Vectors`表示单对应的向量。 接下来,我们可以使用Gonum的矩阵运算函数来实现训练词向量模型。下面是一个简单的例子: ``` import ( "fmt" "github.com/gonum/matrix/mat64" ) func TrainWordVector(corpus [][]string, dim int) *WordVector { // 构建汇表 words := make([]string, 0) for _, doc := range corpus { for _, word := range doc { if !contains(words, word) { words = append(words, word) } } } // 初始化词向量矩阵 V := mat64.NewDense(len(words), dim, nil) for i := 0; i < V.RawMatrix().Rows; i++ { for j := 0; j < V.RawMatrix().Cols; j++ { V.Set(i, j, rand.Float64()) } } // 训练词向量模型 for _, doc := range corpus { for i, word := range doc { // 获取当前单词向量 x := V.RowVec(wordIndex(words, word)) // 计算上下文单的加权平均向量 var context mat64.Vector for j := i-2; j <= i+2; j++ { if j >= 0 && j < len(doc) && j != i { context.AddVec(context, V.RowVec(wordIndex(words, doc[j]))) } } context.ScaleVec(1.0/3.0, &context) // 更新当前单词向量 x.AddScaledVec(x, 0.01, &context) V.SetRow(wordIndex(words, word), x.RawVector().Data) } } return &WordVector{Words: words, Vectors: V.RawMatrix().Data} } // 判断一个字符串是否在一个字符串切片中 func contains(arr []string, str string) bool { for _, a := range arr { if a == str { return true } } return false } // 获取一个汇表中的索引 func wordIndex(words []string, word string) int { for i, w := range words { if w == word { return i } } return -1 } ``` 在上面的代码中,我们首先构建了汇表 `words`,然后初始化了词向量矩阵 `V`。接着,我们遍历语料库 `corpus`,对每个单进行更新。具体地,我们先获取当前单词向量 `x`,然后计算上下文单的加权平均向量 `context`,并将其与当前单词向量相加,最后更新当前单词向量。这个过程可以反复迭代多次,以得到更好的词向量模型。 最后,我们可以使用训练好的模型来获取单词向量: ``` func (wv *WordVector) GetVector(word string) []float64 { index := wordIndex(wv.Words, word) if index == -1 { return nil } return wv.Vectors[index] } ``` 这个函数可以返回一个词向量,如果该单不在汇表中,则返回 `nil`。 当然,上面的实现仅是一个简单的例子,实际应用中可能需要更复杂的模型和更大规模的语料库。但是,通过这个例子,我们可以看到如何使用Gonum库来实现词向量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值