日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python矩阵的平方_NumPy之计算两个矩阵的成对平方欧氏距离

發(fā)布時(shí)間:2024/9/30 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python矩阵的平方_NumPy之计算两个矩阵的成对平方欧氏距离 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

問題描述

設(shè)

(; 表示縱向連接) 和

, 計(jì)算矩陣

中每一個(gè)行向量和矩陣

中每一個(gè)行向量的平方歐氏距離 (pairwise squared Euclidean distance), 即計(jì)算:

(這是一個(gè)

矩陣).

這個(gè)計(jì)算在度量學(xué)習(xí), 圖像檢索, 行人重識(shí)別等算法的性能評(píng)估中有著廣泛的應(yīng)用.

公式轉(zhuǎn)化

在 NumPy 中直接利用上述原式來計(jì)算兩個(gè)矩陣的成對平方歐氏距離, 要顯式地使用二重循環(huán), 而在 Python 中循環(huán)的效率是相當(dāng)?shù)拖碌? 如果想提高計(jì)算效率, 最好是利用 NumPy 的特性將原式轉(zhuǎn)化為數(shù)組/矩陣運(yùn)算. 下面就嘗試進(jìn)行這種轉(zhuǎn)化.

先將原式展開為:

下面逐項(xiàng)地化簡或轉(zhuǎn)化為數(shù)組/矩陣運(yùn)算的形式:

式中,

表示按元素積 (element-wise product), 又稱為 Hadamard 積;

表示維的全1向量 (all-ones vector), 余者類推. 上式中

的作用是計(jì)算

每行元素的和, 返回一個(gè)列向量;

的作用類似于 NumPy 中的廣播機(jī)制, 在這里是將一個(gè)列向量擴(kuò)展為一個(gè)矩陣, 矩陣的每一列都是相同的.

所以:

上述轉(zhuǎn)化式中出現(xiàn)了

(矩陣乘) , 矩陣乘在 NumPy 等很多庫中都有高效的實(shí)現(xiàn), 對代碼的優(yōu)化是有好處的.

特別地, 當(dāng)

時(shí), 原式等于

, 注意到第一項(xiàng)和第二項(xiàng)互為轉(zhuǎn)置. 當(dāng)

(即

的每一個(gè)行向量的范數(shù)均為1時(shí)), 原式等于

,

全1矩陣.

代碼實(shí)現(xiàn)

sklearn 中已經(jīng)包含了用 NumPy 實(shí)現(xiàn)的計(jì)算 "兩個(gè)矩陣的成對平方歐氏距離" 的函數(shù) (sklearn.metrics.euclidean_distances

import numpy as np

def euclidean_distances(x, y, squared=True):

"""Compute pairwise (squared) Euclidean distances."""

assert isinstance(x, np.ndarray) and x.ndim == 2

assert isinstance(y, np.ndarray) and y.ndim == 2

assert x.shape[1] == y.shape[1]

x_square = np.sum(x*x, axis=1, keepdims=True)

if x is y:

y_square = x_square.T

else:

y_square = np.sum(y*y, axis=1, keepdims=True).T

distances = np.dot(x, y.T)

# use inplace operation to accelerate

distances *= -2

distances += x_square

distances += y_square

# result maybe less than 0 due to floating point rounding errors.

np.maximum(distances, 0, distances)

if x is y:

# Ensure that distances between vectors and themselves are set to 0.0.

# This may not be the case due to floating point rounding errors.

distances.flat[::distances.shape[0] + 1] = 0.0

if not squared:

np.sqrt(distances, distances)

return distances

如果想進(jìn)一步加速, 可以將

x_square = np.sum(x*x, axis=1, keepdims=True)

替換為

x_square = np.expand_dims(np.einsum('ij,ij->i', x, x), axis=1)

以及將

y_square = np.sum(y*y, axis=1, keepdims=True).T

替換為

y_square = np.expand_dims(np.einsum('ij,ij->i', y, y), axis=0)

使用 np.einsum 的好處是不會(huì)產(chǎn)生一個(gè)和 x 或 y 同樣形狀的臨時(shí)數(shù)組 (x*x 或 y*y 會(huì)產(chǎn)生一個(gè)和 x 或 y 同樣形狀的臨時(shí)數(shù)組).

PyTorch 中也包含了計(jì)算 "兩個(gè)矩陣的成對平方歐氏距離" 的函數(shù)

另外上述的轉(zhuǎn)化公式也可以用在其他 Python 框架 (如 TensorFlow) 或其他語言中, 這里就不展開敘述了.

版權(quán)聲明

版權(quán)聲明:自由分享,保持署名-非商業(yè)用途-非衍生,知識(shí)共享3.0協(xié)議。

如果你對本文有疑問或建議,歡迎留言!轉(zhuǎn)載請保留版權(quán)聲明!

參考

總結(jié)

以上是生活随笔為你收集整理的python矩阵的平方_NumPy之计算两个矩阵的成对平方欧氏距离的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。