2014-06-30 2 views
1

Я хочу рассчитать ближайшие косинусные соседи вектора из строк матрицы и проверять производительность нескольких функций Python для этого.Расчет эффективного косинусового расстояния

def cos_loop_spatial(matrix, vector): 
    """ 
    Calculating pairwise cosine distance using a common for loop with the numpy cosine function. 
    """ 
    neighbors = [] 
    for row in range(matrix.shape[0]): 
     neighbors.append(scipy.spatial.distance.cosine(vector, matrix[row,:])) 
    return neighbors 

def cos_loop(matrix, vector): 
    """ 
    Calculating pairwise cosine distance using a common for loop with manually calculated cosine value. 
    """ 
    neighbors = [] 
    for row in range(matrix.shape[0]): 
     vector_norm = np.linalg.norm(vector) 
     row_norm = np.linalg.norm(matrix[row,:]) 
     cos_val = vector.dot(matrix[row,:])/(vector_norm * row_norm) 
     neighbors.append(cos_val) 
    return neighbors 

def cos_matrix_multiplication(matrix, vector): 
    """ 
    Calculating pairwise cosine distance using matrix vector multiplication. 
    """ 
    dotted = matrix.dot(vector) 
    matrix_norms = np.linalg.norm(matrix, axis=1) 
    vector_norm = np.linalg.norm(vector) 
    matrix_vector_norms = np.multiply(matrix_norms, vector_norm) 
    neighbors = np.divide(dotted, matrix_vector_norms) 
    return neighbors 

cos_functions = [cos_loop_spatial, cos_loop, cos_matrix_multiplication] 

# Test performance and plot the best results of each function 
mat = np.random.randn(1000,1000) 
vec = np.random.randn(1000) 
cos_performance = {} 
for func in cos_functions: 
    func_performance = %timeit -o func(mat, vec) 
    cos_performance[func.__name__] = func_performance.best 

pd.Series(cos_performance).plot(kind='bar') 

result

cos_matrix_multiplication функция явно самый быстрый из них, но мне интересно, если у вас есть предложения дальнейшего повышения эффективности для матрицы векторных расчетов косинус расстояния.

+0

Поскольку у вас есть рабочий код и вы хотите его улучшить, вам может быть повезло с обзором кода. – wnnmaw

+0

@wnnmaw Ах, я попробую удачу, спасибо! –

ответ

2

scipy.spatial.distance.cdist(mat, vec[np.newaxis,:], metric='cosine'), в основном вычисляет попарное расстояние между каждыми парами двух наборов векторов, представленными строками из двух входных матриц.

Смежные вопросы