温故知新,数学之美,机器学习中十大常用距离计算数学公式

image

欧几里得距离

欧几里得距离公式(Euclidean Distance Formula)是一种用来计算两个点之间直线距离的数学公式。它基于欧几里得几何学,即经典的平面和空间几何学。

欧几里得距离是两点之间最短的路径,它是在各维度上的差值的平方和的平方根。这是我们通常在日常生活中所理解的“直线距离”。

二维空间

对于平面上两个点A(x1,y1)和B(x2,y2)它们的欧几里得距离公式为

d=(x2x1)2+(y2y1)2

三维空间

对于空间中两个点A(x1,y1,z1)和B(x2,y2,z2),欧几里得距离的公式为:

d=(x2x1)2+(y2y1)2+(z2z1)2

高维空间

对于n维空间里面两个点A(x1,x2,,xn)和B(y1,y2,,yn),欧几里得距离的公式为:

d=(x1y1)2+(x2y2)2++(xnyn)2

适用场景

  • 几何学:最基础的几何距离概念。
  • 物理学:计算两物体之间的距离。
  • 数据科学和机器学习:用于衡量数据点之间的相似性。
  • 计算机视觉:用来计算图像中物体的空间位置。

代码实现

  1. 首先检查两个点的维度是否相同,如果不同则抛出异常。
  2. 通过遍历每个维度,计算各个坐标差的平方和。
  3. 最后,计算平方和的平方根得到两点之间的欧几里得距离。
public static double EuclideanDistance(double[] point1, double[] point2)
{
    if (point1.Length != point2.Length)
        throw new ArgumentException("Both points must have the same dimensions");

    double sum = 0;

    for (int i = 0; i < point1.Length; i++)
    {
        sum += Math.Pow(point2[i] - point1[i], 2);
    }

    return Math.Sqrt(sum);
}

对于二维点来说

double[] pointA = { 3, 4 };
double[] pointB = { 7, 1 };
double distance2D = EuclideanDistance(pointA, pointB);
Console.WriteLine($"二维空间中的距离: {distance2D}");

对于三位点来说

double[] pointA = { 1, 2, 3 };
double[] pointB = { 4, 5, 6 };
double distance3D = EuclideanDistance(pointA, pointB);
Console.WriteLine($"三维空间中的距离: {distance3D}");

曼哈顿距离

曼哈顿距离(Manhattan Distance)也称为城市街区距离L1范数。它计算的是两点之间在各个维度上的绝对差之和,常用于城市网格中的距离计算(如在棋盘格状的道路中行走的距离)

二维空间

d=|x2x1|+|y2y1|

三维空间

d=|x2x1|+|y2y1|+|z2z1|

适用场景

在网格结构中的路径规划(如自动驾驶、机器人等)

代码实现

public static double ManhattanDistance(double[] point1, double[] point2)
{
    double distance = 0;
    for (int i = 0; i < point1.Length; i++)
    {
        distance += Math.Abs(point2[i] - point1[i]);
    }
    return distance;
}

切比雪夫距离

切比雪夫距离(Chebyshev Distance)也称为棋盘距离,它表示在二维或三维网格中,从一个点移动到另一个点所需的最少步数(在国王走法中,国王每次可以在任意方向上走一格,包括对角线)

二维空间

d=max(|x2x1|,|y2y1|)

三维空间

d=max(|x2x1|,|y2y1|,|z2z1|)

适用场景

棋盘游戏(如国际象棋中的国王移动)

代码实现

public static double ChebyshevDistance(double[] point1, double[] point2)
{
    double maxDiff = 0;
    for (int i = 0; i < point1.Length; i++)
    {
        maxDiff = Math.Max(maxDiff, Math.Abs(point2[i] - point1[i]));
    }
    return maxDiff;
}

闵可夫斯基距离

闵可夫斯基距离(Minkowski Distance)是欧几里得距离和曼哈顿距离的广义形式,适用于任意维空间。它引入了一个可调参数p,通过不同的p值,可以表示不同的距离。

公式

d=(i=1n|xiyi|p)1p

常见特例:

p=1时,闵可夫斯基距离为曼哈顿距离。
p=2时,闵可夫斯基距离为欧几里得距离。
p=时,闵可夫斯基距离为切比雪夫距离。

适用场景

灵活调整距离测量标准的场景,如某些机器学习算法。

代码实现

public static double MinkowskiDistance(double[] point1, double[] point2, double p)
{
    double sum = 0;
    for (int i = 0; i < point1.Length; i++)
    {
        sum += Math.Pow(Math.Abs(point2[i] - point1[i]), p);
    }
    return Math.Pow(sum, 1 / p);
}

可以通过改变参数p来计算不同的距离,如p=1代表曼哈顿距离,p=2代表欧几里得距离。

余弦相似度

余弦相似度(Cosine Similarity)并不是真正意义上的"距离",而是度量两个向量之间的夹角。余弦值越接近1,表示两个向量越相似。它特别适用于高维空间中的文本或文档分析。

公式

Cosine Similarity=ABAB

其中AB代表两个向量的点积,AB分别为两个向量的模。

适用场景

文本分析、自然语言处理(如衡量两个文本的相似度)

代码实现

public static double CosineSimilarity(double[] vectorA, double[] vectorB)
{
    double dotProduct = 0, magnitudeA = 0, magnitudeB = 0;
    for (int i = 0; i < vectorA.Length; i++)
    {
        dotProduct += vectorA[i] * vectorB[i];
        magnitudeA += Math.Pow(vectorA[i], 2);
        magnitudeB += Math.Pow(vectorB[i], 2);
    }
    return dotProduct / (Math.Sqrt(magnitudeA) * Math.Sqrt(magnitudeB));
}

汉明距离

汉明距离(Hamming Distance)用于衡量两个等长的字符串(或二进制序列)之间不同字符的个数。它常用于纠错码或信息论中。

公式

d=i=1nδ(xi,yi)

其中δ(xi,yi)xi yi时取1,当xi = yi时取0。

适用场景

编码理论、网络通信(如比特串之间的错误检测)

代码实现

public static int HammingDistance(string str1, string str2)
{
    if (str1.Length != str2.Length)
        throw new ArgumentException("Strings must be of equal length");

    int distance = 0;
    for (int i = 0; i < str1.Length; i++)
    {
        if (str1[i] != str2[i])
        {
            distance++;
        }
    }
    return distance;
}

汉明距离通常用于比较等长的二进制序列或字符串

马氏距离

马氏距离(Hamming Distance)是一种考虑数据分布的距离,它用于衡量点与分布中心之间的距离,考虑了数据的协方差结构。它在高维空间中比欧几里得距离更加精确,尤其是在多变量数据中。

公式

d=(xμ)TS1(xμ)

其中:

  • x是样本点,
  • μ是数据的均值向量,
  • S是协方差矩阵。

适用场景

多变量统计分析、异常检测

代码实现

马氏距离相对复杂,因为它需要计算协方差矩阵的逆。以下是实现的思路:

  1. 计算数据集的均值向量。
  2. 计算协方差矩阵并取其逆矩阵。
  3. 根据马氏距离公式计算距离。

由于协方差矩阵及其逆矩阵的计算在C#中需要线性代数库,如MathNet.Numerics,具体实现可以通过该库进行。

这里是一个简化版本,假设你已经计算了协方差矩阵的逆矩阵S1

public static double MahalanobisDistance(double[] point, double[] mean, double[,] invCovMatrix)
{
    double[] diff = new double[point.Length];
    for (int i = 0; i < point.Length; i++)
    {
        diff[i] = point[i] - mean[i];
    }

    double[] temp = new double[point.Length];
    for (int i = 0; i < invCovMatrix.GetLength(0); i++)
    {
        for (int j = 0; j < invCovMatrix.GetLength(1); j++)
        {
            temp[i] += diff[j] * invCovMatrix[j, i];
        }
    }

    double distance = 0;
    for (int i = 0; i < diff.Length; i++)
    {
        distance += temp[i] * diff[i];
    }

    return Math.Sqrt(distance);
}

杰卡德距离

杰卡德距离(Jaccard Distance)用于衡量两个集合的相似性或相异性,定义为交集与并集的差异程度。

公式

d=1|AB||AB|

适用场景

集合相似度分析(如推荐系统、信息检索)

代码实现

杰卡德距离用于集合,你可以使用HashSet来计算交集和并集

public static double JaccardDistance<T>(HashSet<T> set1, HashSet<T> set2)
{
    var intersection = new HashSet<T>(set1);
    intersection.IntersectWith(set2);

    var union = new HashSet<T>(set1);
    union.UnionWith(set2);

    return 1.0 - (double)intersection.Count / union.Count;
}

动态时间规整距离

动态时间规整距离(Dynamic Time Warping, DTW)是用于比较两个时间序列的距离度量,特别是当两个序列的长度不同时,它通过"对齐"时间序列来最小化距离。

公式

d=DTW(A,B)

其中AB是待比较的时间序列

适用场景

语音识别、时间序列分析

代码实现

DTW的实现需要动态规划算法,计算时间序列的最小对齐路径。下面是一个简单的实现:

public static double DynamicTimeWarping(double[] sequence1, double[] sequence2)
{
    int n = sequence1.Length;
    int m = sequence2.Length;
    double[,] dtw = new double[n + 1, m + 1];

    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= m; j++)
            dtw[i, j] = double.PositiveInfinity;

    dtw[0, 0] = 0;

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            double cost = Math.Abs(sequence1[i - 1] - sequence2[j - 1]);
            dtw[i, j] = cost + Math.Min(Math.Min(dtw[i - 1, j], dtw[i, j - 1]), dtw[i - 1, j - 1]);
        }
    }

    return dtw[n, m];
}

布哈曼距离

布哈曼距离(Bhattacharyya Distance)用于度量两个概率分布的相似度,通常用于图像分析和模式识别。

公式

d=ln(p(x)q(x))

适用场景

模式识别、图像处理

代码实现

布哈曼距离常用于概率分布的比较,以下是实现两个概率分布的距离度量:

public static double BhattacharyyaDistance(double[] p, double[] q)
{
    double sum = 0;
    for (int i = 0; i < p.Length; i++)
    {
        sum += Math.Sqrt(p[i] * q[i]);
    }
    return -Math.Log(sum);
}

参考

posted @   TaylorShi  阅读(248)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2022-10-19 乘风破浪,遇见最佳跨平台跨终端框架.Net Core/.Net生态 - 浅析ASP.NET Core远程过程调用,HttpClientFactory和gRPC最佳实践
2022-10-19 乘风破浪,遇见最美Windows 11之现代Windows桌面应用开发 - 接入微软桌面应用程序身份验证(Microsoft.Identity.Client)
2021-10-19 乘风破浪,遇见最美Windows 11之现代Windows桌面应用开发 - Visual Studio扩展开发
点击右上角即可分享
微信分享提示