视频剪辑软件 centos Vue全家桶 CK Jetbains全家桶 swing hyperlink dplayer不能全屏 axure时间选择控件 flutter 缺点 python环境 python基础 python中文文档 python怎么配置环境 java正则 java日期 java数组添加 java运行环境 java的泛型 java获取本机ip php入门例子 lseek函数 矩阵分析与应用 java获取时间戳 ftp客户端软件 mysql游标 hdcp功能是什么 安卓人脸识别 ai投影 快手封号规则 mac微信安装 凯立德导航地图 created 文字底纹怎么设置 苹果手机怎么显示网速 ps怎么取色 js判断类型 草图大师mac版 文鼎字库 magickey
当前位置: 首页 > 学习教程  > 编程学习

基于word2vec的多组词语相似度计算

2021/1/9 1:56:31 文章标签: word计算

文章目录1. 前言2. 找到对应词汇id3. 算法逻辑3.1 多次运行out行不通3.2 修改placeholder3.3 修改余弦相似度变量3.4 运行run4. 实验结果4.1 小批量数据4.2 真实数据5. 完整代码1. 前言 之前写过一篇类似的文章,基于预训练词向量的文本相似度计算-word2vec, paddle…

文章目录

  • 1. 前言
  • 2. 找到对应词汇id
  • 3. 算法逻辑
    • 3.1 多次运行out行不通
    • 3.2 修改placeholder
    • 3.3 修改余弦相似度变量
    • 3.4 运行run
  • 4. 实验结果
    • 4.1 小批量数据
    • 4.2 真实数据
  • 5. 完整代码

1. 前言

之前写过一篇类似的文章,基于预训练词向量的文本相似度计算-word2vec, paddle,讲的计算一个词汇和一组词汇的相似度计算。
本文主要讲,多组词语之间的相似度比较。

语料为:

A = ['轿车', '宝石', '旅游', '男孩子',... ]
B = ['汽车', '宝物', '游历', '小伙子', ...]

2. 找到对应词汇id

def getVocab(path="vocab.txt"):
    # 读取文件并得到dict
    vocab_dict = {} #"unk":0
    id = 0
    with open(path, "r", encoding="utf-8") as f:
        for line in f.readlines():
            word = line.strip()
            vocab_dict[word] = id
            id += 1
    return vocab_dict

vocab_dict = getVocab()

def getIdByWords(mylist):
    #根据mylist找到对应的id
    myid = []
    for word in mylist:
        myid.append(vocab_dict.get(word,0))
    return myid

MC30_A = ['轿车', '宝石', '旅游', '男孩子', '海岸', '庇护所', '魔术师', '中午', '火炉', '食物', '鸟', '鸟', '工具', '兄弟', '起重机', '小伙子',
            '旅行', '和尚', '墓地', '食物', '海岸', '森林', '岸边', '和尚', '海岸', '小伙子', '琴弦', '玻璃', '中午', '公鸡']
id_a = getIdByWords(MC30_A)
print(id_a)

得到结果:

[8808, 6546, 608, 21590, 5701, 109972, 15229, 11022, 39583, 1362, 3004, 3004, 1067, 1733, 23391, 10317, 4592, 5973, 7327, 1362, 5701, 1524, 12328, 5973, 5701, 10317, 24705, 2675, 11022, 25853]

3. 算法逻辑

3.1 多次运行out行不通

直接按照 基于预训练词向量的文本相似度计算-word2vec, paddle 这篇文章来是不行的,原本想多运行几次out:

out = exe.run(feed={'source_emd_placeholder':source_data, "targets_emd_placeholder":targets_data},
			   fetch_list=[out.name])

只能运行一次,之后就找不到out的变量了。

3.2 修改placeholder

都改为一个变量就存一个emb向量:

id1_placeholder = fluid.layers.data(name="id1_placeholder", shape=[1], dtype="int64")
id2_placeholder = fluid.layers.data(name="id2_placeholder", shape=[1], dtype="int64")

3.3 修改余弦相似度变量

#计算余弦相似度
#有多少组要比较,则弄多少组
outs = []
for i in range(len(MC_A)):
    tmp = fluid.layers.cos_sim(id1_emb, id2_emb)
    outs.append(tmp)

这样保证每次运行的是不同的out,从而解决3.1的问题。

3.4 运行run

res = []
i = 0
for a,b in zip(MC_A, MC_B):
    id1 = np.array([a])
    id2 = np.array([b])
    out = exe.run(feed={'id1_placeholder':id1, "id2_placeholder":id2},
    	   fetch_list=[outs[i]])
    # print(out)
    i += 1
    res.append(out[0][0][0])
print(res)

应该还有更好的方法,比如直接将多组emb变量存储到一个矩阵中,再用矩阵运算,element-cos,但我没找到对应的函数。

4. 实验结果

4.1 小批量数据

filename = "work/test300d.txt"
...
MC_A = [2, 3]
MC_B = [1, 2]
...

在这里插入图片描述

4.2 真实数据

#加载word2vec文件
filename = "/home/aistudio/data/data18976/word-char1.dim300"
...
MC_A = [8808, 6546, 608, 21590, 5701, 109972, 15229, 11022, 39583, 1362, 3004, 3004, 1067, 1733, 23391, 10317, 4592, 5973, 7327, 1362, 5701, 1524, 12328, 5973, 5701, 10317, 24705, 2675, 11022, 25853]
MC_B = [916, 14874, 15450, 10317, 10488, 38271, 14564, 32497, 61843, 3568, 25853, 7870, 11000, 5973, 11000, 1733, 8808, 23010, 7400, 25853, 6402, 7327, 7400, 7304, 1524, 14564, 5410, 15229, 16515, 8097]
...

在这里插入图片描述

5. 完整代码

import numpy as np

################part1################################
#加载word2vec文件
filename = "/home/aistudio/data/data18976/word-char1.dim300"
# filename = "work/test300d.txt"

def loadWord2Vec(filename):
    vocab = []
    embd = []
    cnt = 0
    fr = open(filename, 'r', encoding="utf-8")
    line = fr.readline().strip()
    #print(line) #3 300
    word_dim = int(line.split(' ')[1])
    vocab.append("unk")
    embd.append([0]*word_dim)
    for line in fr :
        row = line.strip().split(' ')
        vocab.append(row[0]) #把第一个字/词加入vocab中
        embd.append([np.float32(x) for x in row[1:]]) #把后面一长串加入embd中. 将字符转换成float32
    print("finish load word2vec.")
    fr.close()
    return vocab,embd

vocab,embd = loadWord2Vec(filename)
vocab_size = len(vocab) #1+3
embedding_dim = len(embd[0]) #300
embedding = np.asarray(embd) # numpy格式的词向量数据

################part2################################
#待计算的词汇id
MC_A = [8808, 6546, 608, 21590, 5701, 109972, 15229, 11022, 39583, 1362, 3004, 3004, 1067, 1733, 23391, 10317, 4592, 5973, 7327, 1362, 5701, 1524, 12328, 5973, 5701, 10317, 24705, 2675, 11022, 25853]
MC_B = [916, 14874, 15450, 10317, 10488, 38271, 14564, 32497, 61843, 3568, 25853, 7870, 11000, 5973, 11000, 1733, 8808, 23010, 7400, 25853, 6402, 7327, 7400, 7304, 1524, 14564, 5410, 15229, 16515, 8097]
# MC_A = [2, 3]
# MC_B = [1, 2]

################part3################################
#定义模型
import paddle.fluid as fluid
id1_placeholder = fluid.layers.data(name="id1_placeholder", shape=[1], dtype="int64")
id2_placeholder = fluid.layers.data(name="id2_placeholder", shape=[1], dtype="int64")

#加载用户自定义或预训练的词向量
w_param_attrs = fluid.ParamAttr(
    name="w_param_attrs",
    initializer=fluid.initializer.NumpyArrayInitializer(embedding),
    trainable=False)
#分别查询找到对应的向量
id1_emb = fluid.embedding(input=id1_placeholder, size=(vocab_size, embedding_dim), param_attr=w_param_attrs, dtype='float32')
id2_emb = fluid.embedding(input=id2_placeholder, size=(vocab_size, embedding_dim), param_attr=w_param_attrs, dtype='float32')

#计算余弦相似度
#有多少组要比较,则弄多少组
outs = []
for i in range(len(MC_A)):
    tmp = fluid.layers.cos_sim(id1_emb, id2_emb)
    outs.append(tmp)
out = fluid.layers.cos_sim(id1_emb, id2_emb)
out2 = fluid.layers.cos_sim(id1_emb, id2_emb)
print("finish build model.")

################part4################################
#运行模型
GPU = True
place = fluid.CUDAPlace(0) if GPU else fluid.CPUPlace() # 定义运算场所
exe = fluid.Executor(place) # 创建执行器
exe.run(fluid.default_startup_program()) # 网络参数初始化

print("finish init model.")


res = []
i = 0
for a,b in zip(MC_A, MC_B):
    id1 = np.array([a])
    id2 = np.array([b])
    out = exe.run(feed={'id1_placeholder':id1, "id2_placeholder":id2},
    	   fetch_list=[outs[i]])
    # print(out)
    i += 1
    res.append(out[0][0][0])
print(res)

(不白嫖我们还是好朋友)


本文链接: http://www.dtmao.cc/news_show_1100106.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?