Вычислите матрицу сходства попарных косинусов с помощью pytorch и numpy и реализуйте кластеризацию kmeans с помощью numpy.

  И sklearn, и scipy предоставляют библиотеки кластеризации kmeans, но все они напрямую вычисляют евклидово расстояние, расстояние Мина или сходство косинуса на основе вектора. Если вы используете другие функции измерения или размерность вектора очень велика, вам необходимо сначала рассчитать измерение. При дистанционной и последующей кластеризации кажется, что ни одна из этих библиотечных функций не может быть реализована напрямую, поэтому я сам написал одну с помощью numpy, и она работает очень быстро. Запишите его здесь для дальнейшего использования:

import numpy as np
import matplotlib.pyplot as plt
import time
t0 = time.time()

Num = 512
corr = np.load('corrs20000.npy')  #相关系数矩阵
u = np.arange(Num)                #设置初始中心点
#u = np.random.choice(20000,Num,replace=False)
for n in range(1000):                  #设置1000次循环
    cluster = [[v] for v in u]         #每个簇放在一个列表中,总体再有一个大列表存放
    others = np.array([v for v in range(20000) if v not in u])  #其他未归类的点
    temp = corr[:,u]
    temp = temp[others,:]              #通过两步提取出所有其他未归类点和各中心点的子相关矩阵
    inds = temp.argmax(axis=1)         #计算每个未归类点与各中心点的最大关系那个点的序号
    new_u = []
    for i in range(Num):              #对每个簇分别计算(暂未想到矢量化方法)
        ind = np.where(inds==i)[0]     #提取各簇中所有新点在未归类点中的序号
        points = others[ind]           #根据序号查找对应的未归类点实际编号
        cluster[i] = cluster[i] + points.tolist()  #把本簇未归类点加入到簇中
        temp = corr[cluster[i],:]
        temp = temp[:,cluster[i]]      #通过两步计算提取本簇各点子相关矩阵
        ind_ = temp.sum(axis=0).argmax()   #计算各点和其他各点的总相关系数之和,取最大的一个的序号
        ind_new_center = cluster[i][ind_]  #根据序号转换为实际编号,得到新的本簇中心点
        new_u.append(ind_new_center)       #加入到新中心点向量
    new_u = np.asarray(new_u,dtype=np.int32)
    if (new_u==u).sum() == Num:            #如果新的中心点向量已不再变化,停止循环
        break
    print(n,(new_u==u).sum(),time.time()-t0)
    u = new_u.copy()                   #计算全部结束后得到cluster就是各簇的点集和,u是中心点向量

-------------------------- Последующее дополнение:
  Однако быстро вычислите матрицу автокорреляции набора векторов или взаимную попарную корреляцию двух наборов векторов. векторы Матрица коэффициентов также очень часто используется.Использование torch.cosine_similarity в pytorch позволяет рассчитывать только между двумя векторами и не может обрабатываться пакетами целиком.Если расчет выполняется в цикле или вектор расширяется на метод повторения, скорость расчета явно ниже. Вот метод пакетного расчета с использованием torch.matmul, который можно рассчитать в cuda, и скорость очень высокая. Запись резервной копии:

def pairs_cosineSimilarity_matrix_pytorch(v1,v2):
    #v.shape = (N, vector_dims)
    v1 = v1.permute(1,0).unsqueeze(2).float()
    v2 = v2.permute(1,0).unsqueeze(1).float()
    
    part1 = torch.matmul(v1,v2).sum(0)
    part2 = torch.matmul(v1.pow(2).sum(0).pow(0.5),v2.pow(2).sum(0).pow(0.5))
    
    return part1 / (part2+1e-15)

Supongo que te gusta

Origin blog.csdn.net/Brikie/article/details/119191143
Recomendado
Clasificación