вычислить матрицу сходства косинусов без скучности, sklearn.metrics.pairwise - PullRequest
0 голосов
/ 04 ноября 2018

Допустим, у меня есть такая матрица:

[[5.05537647 4.96643654 4.88792309 4.48089566 4.4469417  3.7841264]
[4.81800568 4.75527558 4.69862751 3.81999698 3.7841264 3.68258605]
[4.64717983 4.60021917 4.55716111 4.07718641 4.0245128 4.69862751]
[4.51752158 4.35840703 4.30839634 3.97312429 3.9655597 3.68258605]
[4.38592909 4.33261686 4.2856032 4.26411249 4.24381326 3.7841264]]

Мне нужно вычислить косинусное сходство между строками матрицы, но без использования косинусного сходства из "scipy" и "sklearn.metrics.pairwise". Но я могу использовать «математику».

Я пробовал это с этим кодом, но я не могу понять, как я могу перебирать каждую строку матрицы.

import math

def cosine_similarity(matrix):

  for row1 in matrix:
    for row2 in matrix:
      sum1, sum2, sum3 = 0, 0, 0
      for i in range(len(row1)):
        a = row1[i]; b = row2[i]
        sum1 += a*a
        sum2 += b*b
        sum3 += a*b
    return sum3 / math.sqrt(sum1*sum2)

 cosine_similarity(matrix)

У вас есть идеи, как я могу это сделать? Спасибо!

1 Ответ

0 голосов
/ 04 ноября 2018

Вы можете использовать векторизованную операцию, поскольку у вас есть пустая матрица. Кроме того, math.sqrt не разрешает векторизованную операцию, поэтому вы можете использовать np.sqrt для векторизации операции квадратного корня. Ниже приведен код, в котором вы сохраняете индексы подобия в списке и возвращаете его.

import numpy as np    

def cosine_similarity(matrix):
    sim_index = []
    for row1 in matrix:
        for row2 in matrix:
            sim_index.append(sum(row1*row2)/np.sqrt(sum(row1**2) * sum(row2**2)))
    return sim_index

cosine_similarity(matrix)

# 1.0,0.9985287276116063,0.9943589065201967,0.9995100043150523,0.9986115804314727,0.9985287276116063,1.0,0.9952419798474134,0.9984515542959852,0.9957338741601842,0.9943589065201967,0.9952419798474134,1.0,0.9970632589904104,0.9962784686967592,0.9995100043150523,0.9984515542959852,0.9970632589904104,1.0,0.9992584450362125,0.9986115804314727,0.9957338741601842,0.9962784686967592,0.9992584450362125,1.0

Далее краткий код, используя понимание списка

sim_index = np.array([sum(r1*r2)/np.sqrt(sum(r1**2) * sum(r2**2)) for r1 in matrix for r2 in matrix])

Окончательный список преобразуется в массив для изменения формы для построения графиков.

Визуализация матрицы сходства : Здесь, поскольку каждая строка полностью идентична самой себе, индекс сходства равен 1 (желтый цвет). Следовательно, диагональ построенной матрицы полностью желтая (индекс = 1).

import matplotlib.pyplot as plt
plt.imshow(sim_index.reshape((5,5)))
plt.colorbar()

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...