目录
Embedding
主要思想
把世界万物变成一个向量,让计算机看这个向量,再进行处理
万物都可嵌入
Word2vec
主要思想
就是把每个单词
变成一个向量
,并且这个向量还保留了单词的语义关系
example:man<->woman
,queen<->king
两种模型:
CBOW
、Skip-gram(用处广)
目的:
把每个词都用向量表示
,同时还保留他们之间语义关系
算法
一、定义超参数
学习率、训练次数、窗口尺寸、嵌入(embedding)尺寸
以下是窗口为二的滑动窗口
二、将语料库转换one-hot编码表示
三、模型训练
1、目标词的one-hot编码传入神经网络模型中训练,最后得到输出结果
2、训练得到的输出结果运用softmax函数归一化处理
3、处理后的结果和相邻窗口的单词one-hot编码分别
做差得到各自的误差
4、将各自误差相加得到总误差
5、交叉熵损失函数处理
6、通过对参数求偏导,梯度下降
方法求更新的参数,反向传播更新权重矩阵
7、最终求得更新迭代过后
的输入层到隐藏层的权重矩阵
即为对应词的embedding词向量
代码手动实现 skip-gram模型
一、数据准备
#准备语料库
text="natural language processing and machine learning is fun and exciting"
#分词处理
corpus=[[word for word in text.split()]]
二、定义超参数
#准备超参数
settings = {
'window_size': 2, # 窗口大小(目标单词的左边和右边最近的2个单词被视为上下文单词)
'n': 10, # 单词嵌入维度,取决于词汇库大小,也是隐藏层大小
'epochs': 50, # 训练次数
'learning_rate': 0.01 # 学习率
}
三、定义word2vec模型
class word2vec():
def __init__(self):
self.n = settings['n']
self.lr = settings['learning_rate']
self.epochs = settings['epochs']
self.window = settings['window_size']
数据清洗及生成词汇表
为后续把数据放入神经网络做准备
在函数train_data内部,我们进行以下操作:
self.v_count: 词汇表的长度(注意,词汇表指的就是语料库中不重复的单词的数量)
self.words_list: 在词汇表中的单词组成的列表
self.word_index: 以词汇表中单词为key,索引为value的字典数据
self.index_word: 以索引为key,以词汇表中单词为value的字典数据
for循环给用one-hot表示的每个目标词和其的上下文词添加到train_data中,one-hot编码用的是word2onehot函数。
def train_data(self,settings,corpus):
#先对语料库进行去重,得到去重后的每个词语对应的个数 返回的是一个字典
word_counts=defaultdict(int)
for row in corpus:
for word in row: #这里的word是二维数组里的单词
word_counts[word]+=1
# 计算有多少个不同的单词
self.v_count = len(word_counts.keys())
#去重后单词放入列表
self.words_list=list(word_counts.keys())
#做成 单词:索引(这里要提出i,word两个参数 所以用enumerate)
self.word_index=dict((word,i) for i,word in enumerate(self.words_list))
#做成 索引:单词
self.index_word = dict((i,word) for i, word in enumerate(self.words_list))
#开始存入目标及窗口范围内的词语
train_data=[]
for sentence in corpus:
sent_len = len(sentence)
for i, word in enumerate(sentence):
w_target=self.word2onehot(sentence[i])
#保存窗口范围内的词语
w_context=[]
for j in range(i-self.window,i+self.window):
if j != i and j <= sent_len - 1 and j >= 0:
w_context.append(self.word2onehot(sentence[j]))
train_data.append([w_target,w_context])#这里就是最终存入神经网络输出层的格式
return np.array(train_data)
#定义Onehot函数
def word2onehot(self,word):
#初始化都是0
word_vec=[0 for i in range(0,self.v_count)]
#找到传入单词在句子中的索引
word_index=self.word_index[word]
#将对应位置改为1
word_vec[word_index]=1
return word_vec
训练模型
#训练模型
def train(self