【问题标题】:How to find a 'connection' between words for clustering sentences如何找到用于聚类句子的单词之间的“连接”
【发布时间】:2021-01-04 18:35:41
【问题描述】:

我需要连接单词 4Gmobile phonesInternet 以便将有关技术的句子聚集在一起。 我有以下句子:

4G is the fourth generation of broadband network.
4G is slow. 
4G is defined as the fourth generation of mobile technology
I bought a new mobile phone. 

我需要在同一个集群中考虑上述句子。目前它没有,可能是因为它没有找到 4G 和移动之间的关系。 我尝试先使用wordnet.synsets 查找连接4G 到互联网或手机的同义词,但不幸的是它没有找到任何连接。 将我正在做的句子聚类如下:

rom sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.metrics import adjusted_rand_score
import numpy

texts = ["4G is the fourth generation of broadband network.",
    "4G is slow.",
    "4G is defined as the fourth generation of mobile technology",
    "I bought a new mobile phone."]

# vectorization of the sentences
vectorizer = TfidfVectorizer(stop_words="english")
X = vectorizer.fit_transform(texts)
words = vectorizer.get_feature_names()
print("words", words)


n_clusters=3
number_of_seeds_to_try=10
max_iter = 300
number_of_process=2 # seads are distributed
model = KMeans(n_clusters=n_clusters, max_iter=max_iter, n_init=number_of_seeds_to_try, n_jobs=number_of_process).fit(X)

labels = model.labels_
# indices of preferible words in each cluster
ordered_words = model.cluster_centers_.argsort()[:, ::-1]

print("centers:", model.cluster_centers_)
print("labels", labels)
print("intertia:", model.inertia_)

texts_per_cluster = numpy.zeros(n_clusters)
for i_cluster in range(n_clusters):
    for label in labels:
        if label==i_cluster:
            texts_per_cluster[i_cluster] +=1 

print("Top words per cluster:")
for i_cluster in range(n_clusters):
    print("Cluster:", i_cluster, "texts:", int(texts_per_cluster[i_cluster])),
    for term in ordered_words[i_cluster, :10]:
        print("\t"+words[term])

print("\n")
print("Prediction")

text_to_predict = "Why 5G is dangerous?"
Y = vectorizer.transform([text_to_predict])
predicted_cluster = model.predict(Y)[0]
texts_per_cluster[predicted_cluster]+=1

print(text_to_predict)
print("Cluster:", predicted_cluster, "texts:", int(texts_per_cluster[predicted_cluster])),
for term in ordered_words[predicted_cluster, :10]:
print("\t"+words[term])

对此的任何帮助将不胜感激。

【问题讨论】:

  • 欢迎堆栈溢出!不幸的是,关于库或工具的问题对于这个站点来说是明确的题外话。您最好的选择可能是研究一些东西,尝试自己解决问题,如果遇到特定问题,请回复minimal reproducible example
  • @G.Anderson 我更新了问题,提供了有关我正在尝试做什么以及我尝试过的更多信息
  • 尝试词嵌入而不是 BoW 和 TfIdf。 [理论上] 嵌入对于相似词应该是相似的。
  • 我还会为您的问题添加另一条路线尝试将其重新定义为分类问题,并让模型学习如何处理不同的类。

标签: python scikit-learn nlp k-means word2vec


【解决方案1】:

正如@sergey-bushmanov 的评论所说,密集词嵌入(来自 word2vec 或类似算法)可能会有所帮助。

它们会将单词转换为密集的高维向量,其中具有相似含义/用法的单词彼此接近。甚至:空间中的某些方向通常会与词之间的关系的种类大致相关。

因此,在具有充分代表性(大而多变)的文本上训练的词向量会将 '4G''mobile' 的向量放置在稍微靠近彼此的位置,然后如果您的句子表示是从词向量引导的,这可能有助于您的集群。

使用单个词向量对句子建模的一种快速方法是使用一个句子的所有词向量的平均值作为句子向量。这太简单了,无法对多种含义进行建模(尤其是那些来自语法和词序的含义),但通常可以作为一个很好的基准,尤其是对于广泛话题的问题。

另一个计算,“Word Mover 的距离”,将句子视为词向量集(不对其进行平均),并且可以进行比简单平均更好的句子到句子距离计算——但变得非常昂贵计算更长的句子。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 2020-12-07
相关资源
最近更新 更多