python-3.x - 根据绘图颜色对相似度矩阵进行排序

标签 python-3.x sorting matplotlib numpy-ndarray similarity

我有一些文档的相似性矩阵图。我想对矩阵的值进行排序,这是一个 numpynd数组,对颜色进行分组,同时保持它们的相对位置(对角线黄线)和标签。

path = "C:\\Users\\user\\Desktop\\texts\\dataset"
text_files = os.listdir(path)
#print (text_files)

tfidf_vectorizer = TfidfVectorizer()
documents = [open(f, encoding="utf-8").read() for f in text_files if f.endswith('.txt')]
sparse_matrix = tfidf_vectorizer.fit_transform(documents)

labels = []
for f in text_files:
    if f.endswith('.txt'):
        labels.append(f)

pairwise_similarity = sparse_matrix * sparse_matrix.T

pairwise_similarity_array = pairwise_similarity.toarray()
 
fig, ax = plt.subplots(figsize=(20,20))
cax = ax.matshow(pairwise_similarity_array, interpolation='spline16')
ax.grid(True)
plt.title('News articles similarity matrix')
plt.xticks(range(23), labels, rotation=90);
plt.yticks(range(23), labels);
fig.colorbar(cax, ticks=[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1])
plt.show() 
enter image description here

最佳答案

这是一种可能性。
这个想法是使用相似度矩阵中的信息,如果它们相似,则将元素彼此相邻放置。如果两个项目相似,则它们在其他元素方面也应该相似,即具有相似的颜色。
我从与所有其他元素最相似的元素开始(这个选择有点随意)[a],作为下一个元素,我从其余元素中选择与当前元素最接近的元素 [b]。

import numpy as np
import matplotlib.pyplot as plt

def create_dummy_sim_mat(n):
    sm = np.random.random((n, n))
    sm = (sm + sm.T) / 2
    sm[range(n), range(n)] = 1
    return sm

def argsort_sim_mat(sm):
    idx = [np.argmax(np.sum(sm, axis=1))]  # a
    for i in range(1, len(sm)):
        sm_i = sm[idx[-1]].copy()
        sm_i[idx] = -1
        idx.append(np.argmax(sm_i))  # b
    return np.array(idx)


n = 10
sim_mat = create_dummy_sim_mat(n=n)

idx = argsort_sim_mat(sim_mat)
sim_mat2 = sim_mat[idx, :][:, idx]  # apply reordering for rows and columns

# Plot results
fig, ax = plt.subplots(1, 2)
ax[0].imshow(sim_mat)
ax[1].imshow(sim_mat2)

def ticks(_ax, ti, la):
    _ax.set_xticks(ti)
    _ax.set_yticks(ti)
    _ax.set_xticklabels(la)
    _ax.set_yticklabels(la)

ticks(_ax=ax[0], ti=range(n), la=range(n))
ticks(_ax=ax[1], ti=range(n), la=idx)
similarity sorted

meTchaikovsky的回答我还在一个聚类相似矩阵上测试了我的想法(见第一张图片)这个方法有效但并不完美(见第二张图片)。
因为我使用两个元素之间的相似性作为它们与所有其他元素的相似性的近似值,所以很明显为什么这不能完美地工作。
因此,不是使用初始相似度对元素进行排序,而是可以计算二阶相似度矩阵,该矩阵测量相似度的相似程度( sorry )。
该度量更好地描述了您感兴趣的内容。如果两行/列具有相似的颜色,则它们应该彼此接近。对矩阵进行排序的算法与之前相同
def add_cluster(sm, c=3):
    idx_cluster = np.array_split(np.random.permutation(np.arange(len(sm))), c)
    for ic in idx_cluster:
        cluster_noise = np.random.uniform(0.9, 1.0, (len(ic),)*2)
        sm[ic[np.newaxis, :], ic[:, np.newaxis]] = cluster_noise

def get_sim_mat2(sm):
    return 1 / (np.linalg.norm(sm[:, np.newaxis] - sm[np.newaxis], axis=-1) + 1/n)

sim_mat = create_dummy_sim_mat(n=100)
add_cluster(sim_mat, c=4)
sim_mat2 = get_sim_mat2(sim_mat)

idx = argsort_sim_mat(sim_mat)
idx2 = argsort_sim_mat(sim_mat2)
sim_mat_sorted = sim_mat[idx, :][:, idx]
sim_mat_sorted2 = sim_mat[idx2, :][:, idx2]

# Plot results
fig, ax = plt.subplots(1, 3)
ax[0].imshow(sim_mat)
ax[1].imshow(sim_mat_sorted)
ax[2].imshow(sim_mat_sorted2)
similarity**2 sorted
第二种方法的结果非常好(见第三张图)
但我想存在这种方法也失败的情况,所以我会很高兴收到反馈。

编辑
我试图解释它,并确实用 [a] 和 [b] 将这些想法与代码联系起来,但显然我做得不好,所以这里有第二个更详细的解释。
您有 n元素和 n x n相似矩阵sm其中每个单元格(i, j)描述元素 i 与元素 j 的相似程度。目标是以一种可以看到相似矩阵中现有模式的方式对行/列进行排序。我实现这一目标的想法非常简单。
您从一个空列表开始并一个一个地添加元素。下一个元素的标准是与当前元素的相似度。如果在最后一步添加了元素 i,我选择元素 argmax(sm[i, :]) 作为下一个,忽略已添加到列表中的元素。我通过将这些元素的值设置为 -1 来忽略这些元素。
您可以使用功能ticks重新排序标签:
labels = np.array(labels)  # make labels an numpy array, to index it with a list
ticks(_ax=ax[0], ti=range(n), la=labels[idx])

关于python-3.x - 根据绘图颜色对相似度矩阵进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64248850/

相关文章:

python - 在 python 中使用字符串模块和 ascii 打印单词?

python - 从 os.walk 创建字典理解

python - 多个 x 轴,彼此非线性

Python、QT 和 matplotlib 散点图与 blitting

python - 如何调试 "str object is not callable"?

在不知道其名称的情况下获得第一个通过的 kwarg 的 Pythonic 方法?

python - 拆分和编辑 CSV 列并按字母顺序排列

python - 在 Python 中按元素总和对组合进行排序

c# - 对 ObservableCollection 进行排序时出现 InvalidOperationException

python-2.7 - 使用 numpy.histogram2d 和 matplotlib 绘制二维直方图时遇到问题