1 原理
One-Hot 编码就是用于将离散的分类(文本)标签转换为二进制向量。
2 代码实现
文本词汇无法直接参与模型训练,所以需要先将其转换成向量表示(与图片类似)。
import numpy as np
# one-hot 编码
def one_hot_encoding(word: str, word2inx: dict):
"""
将文本转换成向量
:param word: 目标词汇
:param word2inx: 词汇到索引的映射字典
:return:
"""
# 初始化,[0, 0, 0, 0]
ndarray = np.zeros(len(word2inx))
# 将对应词的索引设为 1,[0, 0, 1, 0]
ndarray[word2inx[word]] = 1
return ndarray
if __name__ == '__main__':
word2ids = {"你": 0, "今天": 1, "好": 2, "漂亮": 3, "啊": 4}
print(one_hot_encoding("你", word2ids)) # [1. 0. 0. 0. 0.]
print(one_hot_encoding("漂亮", word2ids)) # [0. 0. 0. 1. 0.]
3 缺点
One-Hot 编码后的任意两个词向量是正交的,即余弦相似度为零,这就导致 One-Hot 编码无法表示词汇与词汇间的相似关系,Word2Vec 模型就很好地解决了这一问题。
import numpy as np
# 余弦相似度
def cos2vec(x1, x2):
"""
值越大,两个向量夹角越小,越相似
:param x1: 向量 1
:param x2: 向量 2
:return: 取值范围 [-1, 1]
"""
return x1.dot(x2) / (np.linalg.norm(x1) * np.linalg.norm(x2))
if __name__ == '__main__':
print(cos2vec(np.array([1, 0, 0]), np.array([0, 1, 0]))) # 0.0
print(cos2vec(np.array([1, 1, 1]), np.array([1, 1, 1]))) # 1.0
print(cos2vec(np.array([1, 1, 1]), np.array([2, 1, 1]))) # 0.9428
print(cos2vec(np.array([1, 1, 1]), np.array([3, 1, 1]))) # 0.8704