引言
腾讯AI实验室于2021年12月24日发布了中文词向量0.2.0版本。相比已经存在的中文词向量模型,腾讯词向量的优越性在于:覆盖面广、新颖以及准确性高。
- 覆盖面广:收录了许多领域专业词汇和常用俗语,如: “喀拉喀什河”, “皇帝菜”, “不念僧面念佛面”, “冰火两重天”, “煮酒论英雄" 等。
- 新颖:包括了最近出现的新词和流行词,如: “新冠病毒”, “元宇宙”, “了不起的儿科医生”, “流金岁月”, “凡尔赛文学”, “yyds” 等。
- 准确性高:基于大规模的预料以及精心设计的训练算法,能更准确地反映中文词语与短语的语义。
感兴趣的同学可以去官网了解更多。
下载词向量模型
前往页面选择合适的模型下载,此次发布的模型有4个,如下图所示,根据词嵌入维度,词汇量大小以及模型大小进行选择。
下文将以100维、Small、1.8G模型为例进行讲解,下载完成后将得到巨大的文本文件,打开后格式如下图所示。第一行表示词表大小是两百万,每个词的维度是100,从第二行开始表示具体的词语以及对应的100维向量。
使用词向量模型
推荐使用python的gensim库读取使用词向量模型。
- 安装gensim。
pip install gensim
- 载入词向量模型。
from gensim.models import KeyedVectors
file = 'assets/tencent-ailab-embedding-zh-d100-v0.2.0-s.txt'
model = KeyedVectors.load_word2vec_format(file, binary=False)
# 耗时1min 54s
此种方式比较耗时,再第一次载入后,可保存模型的2进制形式,以后可快速加载。
model.save('Tencent_AILab_ChineseEmbedding.bin')
model = KeyedVectors.load('Tencent_AILab_ChineseEmbedding.bin')
# 耗时1.92s
- 使用词向量模型
# 查找近义词
model.most_similar('宋江', 10)
# model.most_similar(['宋江', '孙悟空'], 10)
"""
[('晁盖', 0.5961815118789673),
('李逵', 0.5785620212554932),
('晁天王', 0.554072380065918),
('武松', 0.5515801310539246),
('卢俊义', 0.539480447769165),
('梁山好汉', 0.5388783812522888),
('梁山兄弟', 0.5371261239051819),
('晁盖等人', 0.5350269675254822),
('阮小七', 0.5330761671066284),
('朱仝', 0.526482105255127)]
"""
# 选出不同意义的词
model.doesnt_match("上海 宝马 广州 北京".split(" "))
# 宝马
# 计算两个词的相似度
model.similarity('宋江', '武松')
# 0.9261145
model.similarity('宋江', '刘备')
# 0.7652319
# 判断词是否在词表中
'水浒传' in model
# True
'水浒传传' in model
# False
# 获取词的向量表示
model['宋江']
# 100维向量
# 组合词向量
import numpy as np
words = ['及时雨', '宋江']
vector = np.zeros((100,), dtype='float32')
for word in words:
vector += model[word]
vector = vector / len(words)
vector.shape
高维向量可视化
首先将数据降维到2维或者3维,再利用绘图工具实现可视化。
降维方法采用T-SNE,绘图工具采用matplotlib。
import jieba
from sklearn.manifold import TSNE
import numpy as np
import random
import matplotlib.pyplot as plt
from gensim.models import KeyedVectors
def reduce_dimensions(vectors, labels, num_dimensions=2):
vectors = np.asarray(vectors)
# 一定要指定随机种子,这样每次降维后的结果才能一样
tsne = TSNE(n_components=num_dimensions, random_state=0)
vectors = tsne.fit_transform(vectors)
x_vals = np.asarray([v[0] for v in vectors])
y_vals = np.asarray([v[1] for v in vectors])
return x_vals, y_vals, labels
def plot_word2vec(x_vals, y_vals, words):
# 设置字体
plt.rcParams["font.sans-serif"] = ["SimHei"]
# 该语句解决图像中的“-”负号的乱码问题
plt.rcParams["axes.unicode_minus"] = False
random.seed(0)
plt.figure(figsize=(20, 20), dpi=300)
plt.scatter(x_vals, y_vals)
# 为图中的点标注文本
for i in list(range(len(words))):
plt.text(x_vals[i], y_vals[i], words[i],
fontdict={
'fontsize': 3, # 文本大小
'color': "black", # 文本颜色
}
)
plt.show()
if __name__ == '__main__':
location = ['新余市', '梧州市', '深圳市', '坪山区', '四川省', '肇庆市', '湘潭市', '潮州市', '国外', '湖北省', '青岛市', '滁州市', '中山市', '六盘水市',
'崇左市', '长沙市', '揭阳市', '汕头市', '无锡市', '陕西省', '云浮市', '南昌市', '洛阳市', '湖南省', '宜昌市', '保定市', '大鹏新区', '南宁市',
'清远市', '大同市', '深圳前海', '郴州市', '沈阳市', '福建省', '河南省', '江门市', '香港', '恩施土家族苗族自治州', '九江市', '益阳市', '北京市',
'赣州市', '广元市', '黔南布依族苗族自治州', '宁德市', '梅州市', '东莞市', '甘肃省', '光明区', '福田区', '阳江市', '三亚市', '合肥市', '南平市',
'苏州市', '福州市', '绍兴市', '鄂尔多斯市', '邵阳市', '海口市', '湛江市', '遵义市', '自贡市', '昆明市', '襄樊市', '上海市', '芜湖市', '郑州市',
'嘉兴市', '南阳市', '株洲市', '佛山市', '贵港市', '成都市', '朔州市', '永州市', '丹东市', '未知位置', '贵阳市', '山东省', '龙岗区', '宝安区',
'浙江省', '辽源市', '宁波市', '泉州市', '杭州市', '广西省', '茂名市', '海南省', '南山区', '南充市', '广州市', '汕尾市', '河源市', '济南市',
'黑龙江省', '江西省', '岳阳市', '新乡市', '龙华区', '韶关市', '盐田区', '黄石市', '江苏省', '防城港市', '大庆市', '宜春市', '上饶市',
'文山壮族苗族自治州', '哈尔滨市', '西安市', '天门市', '珠海市', '重庆市', '铜陵市', '厦门市', '北海市', '安徽省', '天津市', '武汉市', '衡阳市',
'怀化市', '长春市', '常德市', '罗湖区', '惠州市', '牡丹江市', '贵州省', '荆州市', '广东省', '金华市', '平顶山市', '承德市']
# 加载词向量模型
w2v_model = KeyedVectors.load('assets/tencent-100-embedding-zh.bin')
# 将词语映射成模型向量
location_vector = {}
for place in location:
if place not in w2v_model:
# 不在词表中的词,先分词再平均
words = jieba.lcut(place)
vector = np.zeros((100,), dtype='float32')
for word in words:
vector += w2v_model[word]
location_vector[place] = vector / len(words)
else:
location_vector[place] = w2v_model[place]
# 可视化
labels = []
vectors = []
for l, v in location_vector.items():
labels.append(l)
vectors.append(v)
x, y, words = reduce_dimensions(vectors, labels, num_dimensions=2)
plot_word2vec(x, y, words)
可视化效果如下图所示,省份词聚在一起,各省份内部的市级行政单位也聚在了一起,效果还不错。