Main Content

本页翻译不是最新的。点击此处可查看最新英文版本。

pdist

成对观测值之间的两两距离

说明

示例

D = pdist(X) 返回 X 中成对观测值之间的欧几里德距离。

示例

D = pdist(X,Distance) 使用 Distance 指定的方法返回距离。

示例

D = pdist(X,Distance,DistParameter) 使用 DistanceDistParameter 指定的方法返回距离。仅当 Distance'seuclidean''minkowski''mahalanobis' 时,您才能指定 DistParameter

示例

D = pdist(X,Distance,CacheSize=cache)D = pdist(X,Distance,DistParameter,CacheSize=cache) 使用大小为 cache MB 的缓存来加速欧几里德距离的计算。仅当 Distance'fasteuclidean''fastsquaredeuclidean''fastseuclidean' 时,此参数才适用。

示例

全部折叠

计算成对观测值之间的欧几里德距离,并使用 squareform 将距离向量转换为矩阵。

创建包含三个观测值和两个变量的矩阵。

rng('default') % For reproducibility
X = rand(3,2);

计算欧几里德距离。

D = pdist(X)
D = 1×3

    0.2954    1.0670    0.9448

两两距离按 (2,1)、(3,1)、(3,2) 顺序排列。通过使用 squareform,您可以轻松定位观测值 ij 之间的距离。

Z = squareform(D)
Z = 3×3

         0    0.2954    1.0670
    0.2954         0    0.9448
    1.0670    0.9448         0

squareform 返回一个对称矩阵,其中 Z(i,j) 对应于观测值 ij 之间的两两距离。例如,您可以找到观测值 2 和 3 之间的距离。

Z(2,3)
ans = 0.9448

Z 传递给 squareform 函数,以重现 pdist 函数的输出。

y = squareform(Z)
y = 1×3

    0.2954    1.0670    0.9448

squareform 的输出 ypdist 的输出 D 是相同的。

创建包含三个观测值和两个变量的矩阵。

rng('default') % For reproducibility
X = rand(3,2);

使用默认指数 2 计算闵可夫斯基距离。

D1 = pdist(X,'minkowski')
D1 = 1×3

    0.2954    1.0670    0.9448

用指数 1 计算闵可夫斯基距离,它等于城市街区距离。

D2 = pdist(X,'minkowski',1)
D2 = 1×3

    0.3721    1.5036    1.3136

D3 = pdist(X,'cityblock')
D3 = 1×3

    0.3721    1.5036    1.3136

定义一个忽略 NaN 值坐标的自定义距离函数,并使用该自定义距离函数计算两两距离。

创建包含三个观测值和两个变量的矩阵。

rng('default') % For reproducibility
X = rand(3,2);

假设第一个观测值的第一个元素缺失。

X(1,1) = NaN;

计算欧几里德距离。

D1 = pdist(X)
D1 = 1×3

       NaN       NaN    0.9448

如果观测值 ij 包含 NaN 值,函数 pdistij 之间的两两距离返回 NaN。因此,D1(1) 和 D1(2),即 (2,1) 和 (3,1) 之间的两两距离,是 NaN 值。

定义一个自定义距离函数 naneucdist,该函数忽略 NaN 值的坐标,并返回欧几里德距离。

function D2 = naneucdist(XI,XJ)  
%NANEUCDIST Euclidean distance ignoring coordinates with NaNs
n = size(XI,2);
sqdx = (XI-XJ).^2;
nstar = sum(~isnan(sqdx),2); % Number of pairs that do not contain NaNs
nstar(nstar == 0) = NaN; % To return NaN if all pairs include NaNs
D2squared = sum(sqdx,2,'omitnan').*n./nstar; % Correction for missing coordinates
D2 = sqrt(D2squared);

将函数句柄作为输入参数传递给 pdist,以使用 naneucdist 计算该距离。

D2 = pdist(X,@naneucdist)
D2 = 1×3

    0.3974    1.1538    0.9448

创建一个由点组成的大型矩阵,然后 pdist 采用默认的 "euclidean" 距离度量时所用的时间。

rng default % For reproducibility
N = 10000;
X = randn(N,1000);
D = pdist(X); % Warm up function for more reliable timing information
tic
D = pdist(X);
standard = toc
standard = 13.9567

接下来,使用 "fasteuclidean" 距离度量来测量 pdist 所用的时间。指定缓存大小为 10。

D = pdist(X,"fasteuclidean",CacheSize=10); % Warm up function
tic
D2 = pdist(X,"fasteuclidean",CacheSize=10);
accelerated = toc
accelerated = 1.4336

计算加速后的计算比标准计算快多少倍。

standard/accelerated
ans = 9.7355

对于此示例,加速版本的计算速度快三倍。

输入参数

全部折叠

输入数据,指定为大小是 m×n 的数值矩阵。行对应于单个观测值,列对应单个变量。

数据类型: single | double

距离度量,指定为字符向量、字符串标量或函数句柄,如下表中所述。

描述
'euclidean'

欧几里德距离(默认值)

'squaredeuclidean'

平方欧几里德距离。(此选项仅用于提高效率。它不满足三角不等式。)

'seuclidean'

标准化的欧几里德距离。每个观测值间坐标差都通过除以标准差 S = std(X,'omitnan') 中的对应元素来缩放。使用 DistParameterS 指定不同值。

'fasteuclidean'当预测变量的数目至少为 10 时,使用替代算法计算的欧几里德距离,该算法可以节省时间。在某些情况下,这种更快的算法会降低准确度。以 'fast' 开头的算法不支持稀疏数据。有关详细信息,请参阅 算法
'fastsquaredeuclidean'当预测变量的数目至少为 10 时,使用替代算法计算的平方欧几里德距离,该算法可以节省时间。在某些情况下,这种更快的算法会降低准确度。以 'fast' 开头的算法不支持稀疏数据。有关详细信息,请参阅 算法
'fastseuclidean'当预测变量的数目至少为 10 时,使用替代算法计算的标准化的欧几里德距离,该算法可以节省时间。在某些情况下,这种更快的算法会降低准确度。以 'fast' 开头的算法不支持稀疏数据。有关详细信息,请参阅 算法
'mahalanobis'

马氏距离,使用 X 的样本协方差 C = cov(X,'omitrows') 计算。使用 DistParameterC 指定一个不同值,其中矩阵 C 是对称正定矩阵。

'cityblock'

城市街区距离

'minkowski'

闵可夫斯基距离。默认指数是 2。使用 DistParameter 指定其他指数 P,其中 P 是表示指数的正标量值。

'chebychev'

切比雪夫距离(最大坐标差)

'cosine'

1 减去点之间夹角的余弦值(视为向量)

'correlation'

1 减去点之间的样本相关性(视为值序列)

'hamming'

汉明距离,即相异坐标所占的百分比

'jaccard'

1 减去杰卡德系数,即非零相异坐标所占的百分比

'spearman'

1 减去样本观测值之间的斯皮尔曼秩相关(视为值序列)

@distfun

自定义距离函数句柄。距离函数的形式如下

function D2 = distfun(ZI,ZJ)
% calculation of distance
...
其中

  • ZI 是包含单个观测值的 1×n 向量。

  • ZJ 是包含多个观测值的 m2×n 矩阵。distfun 必须接受具有任意数目的观测值的矩阵 ZJ

  • D2 是距离的 m2×1 向量,D2(k) 是观测值 ZIZJ(k,:) 之间的距离。

对于非稀疏数据,使用内置距离度量计算距离通常比使用函数句柄更快。

有关定义,请参阅距离度量

当您使用 'seuclidean''minkowski''mahalanobis' 时,您可以指定额外的输入参数 DistParameter 来控制这些度量。您也可以像使用其他度量一样来使用这些度量,但这种情况下使用的是 DistParameter 的默认值。

示例: 'minkowski'

数据类型: char | string | function_handle

距离度量参数值,指定为正标量、数值向量或数值矩阵。仅当您将 Distance 指定为 'seuclidean''minkowski''mahalanobis' 时,此参数才有效。

  • 如果 Distance'seuclidean'DistParameter 是对应于每个维度的缩放因子的向量,指定为正向量。默认值为 std(X,'omitnan')

  • 如果 Distance'minkowski'DistParameter 是闵可夫斯基距离的指数,指定为正标量。默认值为 2。

  • 如果 Distance'mahalanobis'DistParameter 是协方差矩阵,指定为数值矩阵。默认值为 cov(X,'omitrows')DistParameter 必须是对称正定矩阵。

示例: 'minkowski',3

数据类型: single | double

格拉姆矩阵的大小,以 MB 为单位,指定为正标量或 "maximal"。仅当 Distance 参数为 'fasteuclidean''fastsquaredeuclidean''fastseuclidean' 时,pdist 函数才能使用 CacheSize=cache

如果 cache"maximal"pdist 尝试为大小为 M×M 的整个中间矩阵分配足够的内存,其中 M 是输入数据 X 的行数。高速缓存的大小不必大到足以容纳整个中间矩阵,但必须至少大到足以容纳一个 M×1 向量。否则,pdist 使用标准算法来计算欧几里德距离。

如果距离参数为 'fasteuclidean''fastsquaredeuclidean''fastseuclidean',并且 cache 值太大或为 "maximal",则 pdist 可能会尝试分配超出可用内存容量的格拉姆矩阵。在这种情况下,MATLAB® 会引发错误。

示例: "maximal"

数据类型: double | char | string

输出参数

全部折叠

两两距离,以长度为 m(m–1)/2 的数值行向量形式返回,对应于成对观测值,其中 m 是 X 中的观测值数目。

距离按 (2,1)、(3,1)、...、(m,1)、(3,2)、...、(m,2)、...、(m,m–1) 顺序排列,即按列向排列 m×m 距离矩阵的左下三角元素。观测值 i 和 j 之间的两两距离对应于 D((i-1)*(m-i/2)+j-i),其中 i≤j

您可以使用 squareform 函数将 D 转换为对称矩阵。Z = squareform(D) 返回 m×m 矩阵,其中 Z(i,j) 对应于观测值 i 和 j 之间的两两距离。

如果观测值 i 或 j 包含 NaN,则对于内置距离函数,D 中的对应值为 NaN

D 通常在聚类或多维尺度分析中用作相异度矩阵。有关详细信息,请参阅Hierarchical Clustering以及 cmdscalecophenetlinkagemdscaleoptimalleaforder 的函数参考页。这些函数接受 D 作为输入参数。

详细信息

全部折叠

距离度量

距离度量是定义两个观测值之间距离的函数。pdist 支持各种距离度量:欧几里德距离、标准化的欧几里德距离、马氏距离、城市街区距离、闵可夫斯基距离、切比雪夫距离、余弦距离、相关性距离、汉明距离、杰卡德距离和斯皮尔曼距离。

给定 m×n 数据矩阵 X,它被视为 m 个 (1×n) 行向量 x1、x2、...、xm,向量 xs 和 xt 之间的各种距离定义如下:

  • 欧几里德距离

    dst2=(xsxt)(xsxt).

    欧几里德距离是闵可夫斯基距离的特例,其中 p = 2

  • 标准化的欧几里德距离

    dst2=(xsxt)V1(xsxt),

    其中 V 是 n×n 对角矩阵,它的第 j 个对角线元素是 (S(j))2,其中 S 是对应于每个维度的缩放因子的向量。

  • 马氏距离

    dst2=(xsxt)C1(xsxt),

    其中 C 是协方差矩阵。

  • 城市街区距离

    dst=j=1n|xsjxtj|.

    城市街区距离是闵可夫斯基距离的特例,其中 p = 1

  • 闵可夫斯基距离

    dst=j=1n|xsjxtj|pp.

    对于特例 p = 1,闵可夫斯基距离即城市街区距离。对于特例 p = 2,闵可夫斯基距离即欧几里德距离。对于特例 p = ∞,闵可夫斯基距离即切比雪夫距离。

  • 切比雪夫距离

    dst=maxj{|xsjxtj|}.

    切比雪夫距离是闵可夫斯基距离的特例,其中 p = ∞

  • 余弦距离

    dst=1xsxt(xsxs)(xtxt).

  • 相关性距离

    dst=1(xsx¯s)(xtx¯t)(xsx¯s)(xsx¯s)(xtx¯t)(xtx¯t),

    其中

    x¯s=1njxsjx¯t=1njxtj

  • 汉明距离

    dst=(#(xsjxtj)/n).

  • 杰卡德距离

    dst=#[(xsjxtj)((xsj0)(xtj0))]#[(xsj0)(xtj0)].

  • 斯皮尔曼 距离

    dst=1(rsr¯s)(rtr¯t)(rsr¯s)(rsr¯s)(rtr¯t)(rtr¯t),

    其中

    • rsj 是对 x1j、x2j、...xmj 应用 tiedrank 计算所得的 xsj 的秩。

    • rs 和 rt 是 xs 和 xt 的基于坐标轴的秩向量,即 rs = (rs1, rs2, ... rsn)。

    • r¯s=1njrsj=(n+1)2.

    • r¯t=1njrtj=(n+1)2.

算法

全部折叠

快速欧几里德距离算法

fast 开头的 Distance 参数(如 'fasteuclidean''fastseuclidean')的值在计算欧几里德距离时使用的算法会使用额外的内存来节省计算时间。此算法在 Albanie 的文献 [1] 中和其他位置称为“欧几里德距离矩阵技巧”。内部测试表明,当预测变量的数目至少为 10 时,该算法可以节省时间。

为了求得所有点 xi 和 xj 之间距离的矩阵 D(其中每个 xi 具有 n 个变量),该算法使用以下方程中的最后一行来计算距离:

Di,j2=xixj2=(xixj)T(xixj)=xi22xiTxj+xj2.

方程最后一行中的矩阵 xiTxj 称为格拉姆矩阵。当您计算并使用格拉姆矩阵而不是通过平方与求和来计算平方距离时,计算平方距离集的速度更快,但在数值上稳定性稍差。有关讨论,请参阅 Albanie 的文献 [1]

为了存储格拉姆矩阵,软件使用默认大小为 1e3 MB 的缓存。您可以使用 cache 参数设置缓存大小。如果 cache 的值太大或为 "maximal"pdist 可能会尝试分配超出可用内存容量的格拉姆矩阵。在这种情况下,MATLAB 会引发错误。

参考

[1] Albanie, Samuel. Euclidean Distance Matrix Trick. June, 2019. Available at https://www.robots.ox.ac.uk/%7Ealbanie/notes/Euclidean_distance_trick.pdf.

扩展功能

版本历史记录

在 R2006a 之前推出

全部展开