新闻推荐系统近年来发展迅速,其中一个重要的技术突破是深度知识感知网络 (DKN) 的出现。DKN 能够利用知识图谱 (KG) 中的实体信息来增强新闻推荐的准确性。为了训练 DKN 模型,我们需要预先训练词向量和实体向量,本文将介绍如何使用 Word2Vec 和 TransE 模型来完成这一任务。
用 Word2Vec 训练词向量
Word2Vec 是一种常用的词向量训练模型,它能够将词语映射到一个高维向量空间中,并学习到词语之间的语义关系。在 DKN 中,我们需要将新闻标题和文本中的词语转换为向量表示,以便模型能够理解文本内容。
我们可以使用 Gensim 库中的 Word2Vec 模型来训练词向量。Gensim 提供了简单易用的接口,可以方便地加载文本数据并训练模型。
from gensim.test.utils import common_texts, get_tmpfile
from gensim.models import Word2Vec
import time
from utils.general import *
import numpy as np
import pickle
from utils.task_helper import *
首先,我们定义一个类 MySentenceCollection
来读取新闻文本数据。该类实现了迭代器接口,可以逐行读取文本文件并将其转换为词语列表。
class MySentenceCollection:
def __init__(self, filename):
self.filename = filename
self.rd = None
def __iter__(self):
self.rd = open(self.filename, 'r', encoding='utf-8', newline='\\r\\n')
return self
def __next__(self):
line = self.rd.readline()
if line:
return list(line.strip('\\r\\n').split(' '))
else:
self.rd.close()
raise StopIteration
接下来,我们定义一个函数 train_word2vec
来训练 Word2Vec 模型。该函数接受新闻文本文件路径和输出目录作为参数,并保存训练好的模型文件。
def train_word2vec(Path_sentences, OutFile_dir):
OutFile_word2vec = os.path.join(OutFile_dir, r'word2vec.model')
OutFile_word2vec_txt = os.path.join(OutFile_dir, r'word2vec.txt')
create_dir(OutFile_dir)
print('start to train word embedding...', end=' ')
my_sentences = MySentenceCollection(Path_sentences)
model = Word2Vec(my_sentences, size=32, window=5, min_count=1, workers=8, iter=10) # user more epochs for better accuracy
model.save(OutFile_word2vec)
model.wv.save_word2vec_format(OutFile_word2vec_txt, binary=False)
print('\\tdone . ')
Path_sentences = os.path.join(InFile_dir, 'sentence.txt')
t0 = time.time()
train_word2vec(Path_sentences, OutFile_dir)
t1 = time.time()
print('time elapses: {0:.1f}s'.format(t1 - t0))
用 TransE 训练实体向量
知识图谱 (KG) 由实体和关系组成,可以用来表示世界上的各种知识。在 DKN 中,我们可以利用 KG 中的实体信息来增强新闻推荐的准确性。为了将 KG 中的实体信息融入到 DKN 模型中,我们需要将实体映射到向量空间中,即训练实体向量。
TransE 是一种常用的知识图谱嵌入模型,它能够将实体和关系映射到同一个向量空间中,并学习到实体和关系之间的语义关系。我们可以使用开源的 Fast-TransX 库来训练 TransE 模型。
!bash ./run_transE.sh
构建上下文向量
DKN 模型不仅需要考虑实体本身的向量表示,还需要考虑实体的上下文信息。例如,同一个实体在不同的新闻中可能具有不同的含义。为了捕捉这种上下文信息,我们需要构建上下文向量。
我们可以利用 KG 中的实体关系来构建上下文向量。例如,对于一个实体,我们可以将所有与它相关的实体的向量加权平均,得到该实体的上下文向量。
##### build context embedding
EMBEDDING_LENGTH = 32
entity_file = os.path.join(OutFile_dir_KG, 'entity2vec.vec')
context_file = os.path.join(OutFile_dir_KG, 'context2vec.vec')
kg_file = os.path.join(OutFile_dir_KG, 'train2id.txt')
gen_context_embedding(entity_file, context_file, kg_file, dim=EMBEDDING_LENGTH)
加载预训练向量
最后,我们需要将训练好的词向量和实体向量加载到 DKN 模型中。
load_np_from_txt(
os.path.join(OutFile_dir_KG, 'entity2vec.vec'),
os.path.join(OutFile_dir_DKN, 'entity_embedding.npy'),
)
load_np_from_txt(
os.path.join(OutFile_dir_KG, 'context2vec.vec'),
os.path.join(OutFile_dir_DKN, 'context_embedding.npy'),
)
format_word_embeddings(
os.path.join(OutFile_dir, 'word2vec.txt'),
os.path.join(InFile_dir, 'word2idx.pkl'),
os.path.join(OutFile_dir_DKN, 'word_embedding.npy')
)
参考文献
- Wang, Hongwei, et al. "DKN: Deep Knowledge-Aware Network for News Recommendation." Proceedings of the 2018 World Wide Web Conference on World Wide Web. International World Wide Web Conferences Steering Committee, 2018.
- Knowledge Graph Embeddings including TransE, TransH, TransR and PTransE. https://github.com/thunlp/KB2E
- GloVe: Global Vectors for Word Representation. https://nlp.stanford.edu/projects/glove/
- Tomas Mikolov, Ilya Sutskever, Kai Chen, Greg Corrado, and Jeffrey Dean. 2013. Distributed representations of words and phrases and their compositionality. In Proceedings of the 26th International Conference on Neural Information Processing Systems - Volume 2 (NIPS’13). Curran Associates Inc., Red Hook, NY, USA, 3111–3119.
- Gensim Word2vec embeddings : https://radimrehurek.com/gensim/models/word2vec.html