代码逻辑
首先对训练数据和测试数据进行处理,按词进行分割然后储存起来,然后通过SVG和SGNS方法计算出训练数据的词向量,再在测试数据上进行测试。
为此,在代码中定义了load_data()
, caculate_sim()
, svd_embedding()
和sgns_embedding()
四个方法,分别进行数据处理、计算测试集上向量相关性、通过svd和sgns得到训练集上向量的操作。
最后将输出结果按要求写入文本文件中。
SVG
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| def svd_embedding(train_data, test_data, dim): model = Word2Vec(train_data, vector_size=dim, window=2, sg=0) vectors = model.wv.vectors svd = TruncatedSVD(n_components=5) vec_svd = svd.fit_transform(vectors) word_index = model.wv.key_to_index print('总奇异值个数:', len(word_index))
selected_singular_values_sum = np.sum(svd.explained_variance_ratio_) all_singular_values_sum = np.sum(svd.explained_variance_) ratio = selected_singular_values_sum / all_singular_values_sum print("选取的奇异值之和:", selected_singular_values_sum) print("全部奇异值之和:", all_singular_values_sum) print("选取的奇异值之和与全部奇异值之和的比例:", ratio)
svd_result = caculate_sim(test_data, vec_svd, word_index)
return vec_svd, svd_result
|
SVD分解算法的主要思想是将一个矩阵分解为三个矩阵的乘积,即$A = UΣV^T$,其中$A$是待分解的矩阵,$U$是左奇异矩阵,$Σ$是奇异值矩阵,$V^T$是右奇异矩阵。在代码中,保留的主成分数量为$K$,然后将原始矩阵$A$分解为$U_kΣ_kV_k^T$,其中$U_k$、$Σ_k$和$V_k^T$分别是前$K个$左奇异矩阵、奇异值矩阵和右奇异矩阵。
在SVD中,非零奇异值的数量即为原始矩阵的秩,等于词汇表的大小,代码中word_index
的长度即为非零奇异值的个数,在本实验数据中为24843。
在代码中使用了TruncatedSVD方法,选取了K=5个奇异值进行模型分析。
选取的奇异值之和: 0.47254738
全部奇异值之和: 1.6644406
选取的奇异值之和与全部奇异值之和的比例: 0.28390762
SGNS
1 2 3 4 5 6 7
| def sgns_embedding(train_data, test_data, dim): model = Word2Vec(train_data, vector_size=dim, window=2, sg=1, negative=8) vec_sgns = model.wv.vectors word_index = model.wv.key_to_index sgns_result = caculate_sim(test_data, vec_sgns, word_index) return vec_sgns, sgns_result
|
初始词向量是由Word2Vec模型随机初始化的,是随机的小数值。
在代码中,词向量的维数通过 vector_size
参数指定,在此选择了维数为128。
在Word2Vec模型中,学习率、训练算法的学习率、训练批次大小和训练轮数等由模型的默认值控制,对使用者透明。