python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python距离度量方法

Python七种距离度量方法全解析

作者:AI手记叨叨

这篇文章主要介绍了Python七种距离度量方法的相关资料,包括曼哈顿距离、欧氏距离、切比雪夫距离和明科夫斯基距离,并提供每种距离的具体计算示例及其应用场景,帮助大家更好地理解距离度量,需要的朋友可以参考下

前言

本文介绍了欧氏距离、曼哈顿距离、切比雪夫距离、余弦距离、闵可夫斯基距离、汉明距离、编辑距离等七种常用距离度量方法的原理、意义与应用场景,并提供了 Python 代码实现,帮助在数据科学、机器学习与工程实践中选择和使用合适的距离度量方法。

一、 欧式距离

欧氏距离是“直线距离”。在二维或三维空间中,它就是两个点之间直接用尺子量出来的最短距离。

1. 核心思想

它源于欧几里得的几何学,衡量的是空间中两个点之间的“真实”直线长度。

2. 计算方法

3. 示例代码

from math import sqrt

def euclidean_distance(p, q):
    """
    计算欧式距离
    p, q: 相同维度的数组或列表
    """
    return sqrt(sum((px - qx) ** 2 for px, qx in zip(p, q)))


p = [1, 2, 3]
q = [4, 5, 6]
print(f"欧式距离: {euclidean_distance(p, q)}")

4. 主要特点

5. 常见应用场景

二、 曼哈顿距离

曼哈顿距离,也称为“城市街区距离”或“L1距离”,是指两点在标准坐标系上的绝对轴距总和

1. 核心思想

来源于在网格状道路(如曼哈顿街区)中行走的最短路径,只能沿着水平和垂直方向移动,不能走斜线。

2. 计算方法

计算两个点在各维度上数值差的绝对值之和。

3. 示例代码

def manhattan_distance(p, q):
    """
    计算曼哈顿距离
    """
    return sum(abs(px - qx) for px, qx in zip(p, q))

# 示例
p = [1, 2, 3]
q = [4, 5, 6]
print(f"曼哈顿距离: {manhattan_distance(p, q)}")

4. 主要特点

5. 常见应用场景

三、 切比雪夫距离

切比雪夫距离,也称为“棋盘距离”,是指两点之间各坐标数值差的最大值

1. 核心思想

来源于国际象棋中“王”的移动方式,可以朝任意方向移动一格,因此在多维空间中体现为各维度差值中的最大值。

2. 计算方法

取两个点在各维度上数值差的绝对值中的最大值。

3. 示例代码

def chebyshev_distance(p, q):
    """
    计算切比雪夫距离
    """
    return max(abs(px - qx) for px, qx in zip(p, q))

# 示例
p = [1, 2, 3]
q = [4, 5, 6]
print(f"切比雪夫距离: {chebyshev_distance(p, q)}")

4. 主要特点

5. 常见应用场景

四、余弦距离

1. 核心思想

余弦距离用于衡量两个向量在方向上的差异,而不是位置或绝对长度。它基于向量夹角的余弦值,适用于高维稀疏向量比较,如文本相似性分析。

2. 计算方法

  1. 计算两个向量的点积(对应元素相乘后求和)
  2. 分别计算两个向量的模长(各元素平方和的平方根)
  3. 用点积除以两个模长的乘积,得到余弦相似度
  4. 余弦距离 = 1 - 余弦相似度

3. 示例代码

import numpy as np
from numpy.linalg import norm


def cosine_distance(a, b):
    """
    计算余弦距离 = 1 - 余弦相似度
    注:对于零向量,余弦相似度通常定义为0,因此余弦距离为1
    """
    dot_product = np.dot(a, b)
    norm_a = norm(a)
    norm_b = norm(b)

    if norm_a == 0 or norm_b == 0:
        return 1.0  # 零向量的情况

    cosine_sim = dot_product / (norm_a * norm_b)
    return 1.0 - cosine_sim


# 示例
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(f"余弦距离: {cosine_distance(a, b)}")

4. 主要特点

5. 常见应用场景

五、闵可夫斯基距离

1. 核心思想

闵可夫斯基距离是欧式距离和曼哈顿距离的一般化形式,通过参数 ( p ) 控制距离的计算方式。

2. 计算方法

  1. 计算两个点在各维度上数值差的绝对值的 p 次方
  2. 将这些 p 次方的值求和
  3. 对求和结果取 p 次方根

3. 特殊情况

4. 示例代码

from math import pow


def minkowski_distance(point1, point2, order=2):
    """
    计算闵可夫斯基距离

    参数:
    point1, point2: 要比较的点(列表或数组)
    order: 闵可夫斯基参数(order=1:曼哈顿,order=2:欧式,order=∞:切比雪夫)
    """
    if order == float('inf'):
        # 切比雪夫距离
        return max(abs(p1 - p2) for p1, p2 in zip(point1, point2))

    sum_power = sum(pow(abs(p1 - p2), order) for p1, p2 in zip(point1, point2))
    return pow(sum_power, 1.0 / order)


# 示例
p = [1, 2, 3]
q = [4, 5, 6]

print(f"闵可夫斯基距离(order=1, 曼哈顿): {minkowski_distance(p, q, order=1)}")
print(f"闵可夫斯基距离(order=2, 欧式): {minkowski_distance(p, q, order=2)}")
print(f"闵可夫斯基距离(order=3): {minkowski_distance(p, q, order=3)}")
print(f"闵可夫斯基距离(order=∞, 切比雪夫): {minkowski_distance(p, q, order=float('inf'))}")

5. 主要特点

6. 常见应用场景

六、汉明距离

1. 核心思想

汉明距离用于比较两个等长字符串或序列的不同位置数量,主要用于编码理论和信息论。

2. 计算方法

比较两个字符串或序列对应位置上的字符或数值,统计不相等的位数的总数。

3. 示例代码

def hamming_distance(s1, s2):
    """
    计算汉明距离(适用于等长序列)
    """
    if len(s1) != len(s2):
        raise ValueError("序列长度必须相等")

    return sum(c1 != c2 for c1, c2 in zip(s1, s2))


# 示例(字符串)
s1 = "karolin"
s2 = "kathrin"
print(f"字符串汉明距离: {hamming_distance(s1, s2)}") 

# 示例(二进制列表)
binary1 = [1, 0, 1, 0, 1]
binary2 = [0, 1, 0, 1, 0]
print(f"二进制汉明距离: {hamming_distance(binary1, binary2)}") 

4. 主要特点

5. 常见应用场景

七、编辑距离

1. 核心思想

编辑距离衡量两个字符串之间的相似度,定义为将一个字符串转换为另一个字符串所需的最少编辑操作次数(插入、删除、替换)。

2. 计算方法

使用动态规划算法:

  1. 创建一个二维表格,行数=源字符串长度+1,列数=目标字符串长度+1
  2. 初始化第一行和第一列(从空字符串转换的代价)
  3. 逐行逐列填充表格:
    • 如果字符相同,直接取左上角值(表示无需编辑)。
    • 如果字符不同,取左方(删除)、上方(插入)、左上方(替换)三个值的最小值加1。
  4. 表格右下角的值即为编辑距离

3. 示例代码

def edit_distance(s1, s2):
    """
    计算编辑距离(Levenshtein距离)
    """
    m, n = len(s1), len(s2)
    dp = [[0] * (n + 1) for _ in range(m + 1)]
    
    # 初始化边界条件
    for i in range(m + 1):
        dp[i][0] = i
    for j in range(n + 1):
        dp[0][j] = j
    
    # 动态规划填表
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if s1[i-1] == s2[j-1]:
                dp[i][j] = dp[i-1][j-1]  # 字符相同,无需编辑
            else:
                dp[i][j] = min(
                    dp[i-1][j] + 1,    # 删除
                    dp[i][j-1] + 1,    # 插入
                    dp[i-1][j-1] + 1   # 替换
                )
    return dp[m][n]


def normalized_edit_distance(s1, s2):
    """
    计算归一化编辑距离(范围[0, 1])
    """
    max_len = max(len(s1), len(s2))
    if max_len == 0:
        return 0.0
    return edit_distance(s1, s2) / max_len


# 示例
s1 = "kitten"
s2 = "sitting"
print(f"编辑距离: {edit_distance(s1, s2)}")  # 输出: 3
print(f"归一化编辑距离: {normalized_edit_distance(s1, s2):.4f}")  # 输出: 0.4286

4. 主要特点

5. 常见应用场景

八、 比较

核心思想计算复杂度异常值敏感性适用数据类型应用场景别名/类别
欧式距离两点之间的“直线距离”中等(平方、求和、开方)敏感(平方放大异常值)各向同性空间几何距离、KNN、聚类、图像处理L2距离、直线距离
曼哈顿距离两点在网格路径上的“城市街区距离”低(绝对值、求和)较不敏感网格/正交空间路径规划、网格导航、图像处理、数据挖掘L1距离、城市街区距离
切比雪夫距离两点在各维度上差异的最大值低(比较、取最大值)依赖最大差异维度最大差异主导空间棋盘AI、质量控制、图像形态学棋盘距离、L∞距离
余弦距离向量方向相似性中等不敏感高维稀疏向量文本挖掘、推荐系统、文档聚类余弦相似度的补
闵可夫斯基距离参数化的通用距离族中等(取决于p)敏感(p≠∞时)连续数值数据参数化距离分析、机器学习Minkowski距离族
汉明距离离散序列差异计数对位置差异敏感等长序列编码理论、基因组比对、错误检测汉明差异
编辑距离字符串转换的最少编辑操作数中等(O(m×n),动态规划)对编辑位置敏感,对数值不敏感字符串/序列(可不等长)拼写纠错、生物序列比对、文本相似度、模糊匹配Levenshtein距离、字符串编辑距离

九、选择

  1. 欧式距离:最自然的空间距离,适用于物理空间或各向同性特征空间
  2. 曼哈顿距离:适用于网格路径、特征独立的场景
  3. 切比雪夫距离:关注最大差异的场景,如质量控制
  4. 余弦距离:适合文本、高维稀疏数据的方向比较
  5. 闵可夫斯基距离:需要灵活调整距离特性的参数化方法
  6. 汉明距离:离散序列、编码、二进制数据的比较
  7. 编辑距离:字符串处理、文本相似度、生物信息学

不同的距离度量适用于不同的数据特性和任务需求。在实际应用中,通常需要根据数据分布、特征关系和具体任务来选择合适的距离函数。

到此这篇关于Python七种距离度量方法的文章就介绍到这了,更多相关Python距离度量方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文