KMeans 聚类多维特征
Posted
技术标签:
【中文标题】KMeans 聚类多维特征【英文标题】:KMeans clustering multidimensional features 【发布时间】:2019-11-19 10:29:38 【问题描述】:是否可以使用多维特征矩阵来训练 Kmeans ML 模型?
我使用 sklearn 和 KmeansClass 进行聚类,使用 Word2Vec 提取词袋,使用 TreeTagger 进行文本预处理
from gensim.models import Word2Vec
from sklearn.cluster import KMeans
lemmatized_words = [["be", "information", "contract", "residential"], ["can", "send", "package", "recovery"]
w2v_model = Word2Vec.load(wiki_path_model)
bag_of_words = [w2v_model.wv(phrase) for phrase in lemmatized_words]
#
#
# bag_of_words = [array([[-0.08796783, 0.08373307, 0.04610106, ..., 0.41964772,
# -0.1733183 , 0.09438939],
# [ 0.11526374, 0.09092105, -0.2086806 , ..., 0.5205145 ,
# -0.11455593, -0.05190944],
# [-0.05140354, 0.09938619, 0.07485678, ..., 0.73840886,
# -0.17298238, 0.09994634],
# ...,
# [-0.01144416, -0.17129216, -0.04012141, ..., 0.05281362,
# -0.23109615, 0.02297313],
# [-0.08355679, 0.24799444, 0.04348441, ..., 0.27940673,
# -0.14400786, -0.09187686],
# [ 0.11022831, 0.11035886, 0.19900796, ..., 0.12891224,
# -0.09379898, 0.10538024]],dtype=float32)
# array([[ 1.73330009e-01, 1.26429915e-01, -3.47578406e-01, ...,
# 8.09064806e-02, -3.02738965e-01, -1.61911864e-02],
# [ 2.47227158e-02, -6.48087710e-02, -1.97364464e-01, ...,
# 1.35158226e-01, 1.72204189e-02, -1.14456110e-01],
# [ 8.07424933e-02, 2.69261692e-02, -4.22120057e-02, ...,
# 1.01349883e-01, -1.94084793e-01, -2.64464412e-04],
# ...,
# [ 1.36009008e-01, 1.50609210e-01, -2.59797573e-01, ...,
# 1.84113771e-01, -6.85161874e-02, -1.04138054e-01],
# [ 4.83367145e-02, 1.17820159e-01, -2.43335906e-02, ...,
# 1.33836940e-01, -1.55749675e-02, -1.18981823e-01],
# [-6.68482706e-02, 4.57039356e-01, -2.20365867e-01, ...,
# 2.95841128e-01, -1.55933857e-01, 7.39804050e-03]], dtype=float32)
# ]
#
#
model = KMeans(algorithm='auto0', max_iter=300, n_clusters=2)
model.fit(bag_of_words)
我希望 Kmeans 已经过训练,因此我可以存储模型并用于预测,但我收到以下错误消息:
ValueError: setting an array element with a sequence.
【问题讨论】:
为什么(以及是什么)self.X_train
?
对不起,为了简化代码弄错了
但是X_train
是什么?之前没有出现在您的代码中
X_train
是bag_of_words
,Kmeans 集群嵌入在包含X_train
的特定类中。我没有显示 class= KmeansClass(X_train) 并调用 `class.train(),而是写了 model.fit(X_train),我将更正它
【参考方案1】:
您的问题出在w2v_model.wv(phrase)
。 Word2vec 模型,顾名思义,可以应用于单词级别。要获得短语嵌入,您需要平均(或以其他方式聚合)该短语中所有单个单词的嵌入。
所以你需要更换
bag_of_words = [w2v_model.wv(phrase) for phrase in lemmatized_words]
与
import numpy as np
bag_of_words = [np.mean([w2v_model.wv(word) for word in phrase], axis=0) for phrase in lemmatized_words]
对我来说,以下代码片段可以正常工作。它使用KeyedVectors
而不是已弃用的Word2Vec
,但其余的都是一样的。
from gensim.models import KeyedVectors
from sklearn.cluster import KMeans
import numpy as np
lemmatized_words = [["be", "information", "contract", "residential"], ["can", "send", "package", "recovery"]]
w2v_model = KeyedVectors.load_word2vec_format(wiki_path_model, binary=True)
bag_of_words = np.array([np.mean([w2v_model[word] for word in phrase if word in w2v_model], axis=0) for phrase in lemmatized_words])
print(bag_of_words.shape) # it should give (2, 300) for a 300-dimensional w2v
model = KMeans( max_iter=300, n_clusters=2)
model.fit(bag_of_words)
当然,平均(或其他聚合)会丢弃一些关于单词的信息,这些信息可能对聚类有意义。但是如果没有聚合,就无法获得可比较的词组嵌入,因为不同的词组可能有不同的长度。
如果您的平均嵌入聚类失败,我建议寻找预训练的句子嵌入(例如 Google 的 Universal Sentence Encoder,或者可能来自 BERT 的嵌入)。
【讨论】:
嗨,大卫,感谢您的回答。如果我尝试对短语中的每个单词应用 word2vec,以获得单行的多维特征,我会收到相同的错误。问题不在 w2v_model.wv(phrase) 上,而是在 KMeans 上。是否可以在每行具有多维特征的矩阵上应用 KMeans? “多维特征”到底是什么意思?我的建议是使用所有单词的平均向量作为句子嵌入。它是一维向量。例如。如果您的模型具有 300 维嵌入,则每个句子将表示为 300 个数字的列表。 我有 [[[1.12, 2.03, 3.2], [1.78, 2.3, 0.2]] (在本例中为 1x2 矩阵),而不是 [[[1.12, 2.03, 3.2], [1.78 , 2.3, 0.2]], [[1.12, 2.03, 3.2], [1.78, 2.3, 0.2]] (所以是 1x2 矩阵,但 beach 列是数组而不是浮点数)。 在这种情况下,您应该在矩阵列表中调用np.concat()
,然后再将其输入 k-means。或者使用我的代码版本(我更新了答案);它给出了正确的向量。
感谢大卫的回答。我已经使用平均值实现了您的解决方案。我的想法是尝试 KMeans 并添加零向量,以便为每个起始短语获得相同的长度。另一种选择是使用 BERT,但首先我会尝试使用这个。再次感谢您的回答以上是关于KMeans 聚类多维特征的主要内容,如果未能解决你的问题,请参考以下文章
Scikit-learn KMeans 聚类 - 用 X 特征拟合集群,用 X-1 特征预测集群成员?
ML之kmeans:通过数据预处理(分布图箱线图热图/文本转数字/构造特征/编码/PCA)利用kmeans实现汽车产品聚类分析(SSE-平均轮廓系数图/聚类三维图/雷达图/饼图柱形图)/竞品分析之详细