Skip to content

空间分布模式分析——最邻近指数法 #32

Description

@ZhangAilan

最邻近指数(Nearest Neighbor Index, NNI)是一种用于判断点模式空间分布特征(聚集、随机、均匀)的经典方法。其基本思想是:

对于一组空间点,计算每个点到最近邻的距离,然后与完全随机分布下的期望距离进行比较,得出一个指数值 NNI。

  • NNI < 1 表示聚集分布;
  • NNI ≈ 1 表示随机分布;
  • NNI > 1 表示均匀分布。

1)计算研究区面积,使用点坐标的最小外接矩形
2)计算最邻近距离,from scipy.spatial.distance import cdist,计算所有点之间的欧几里得距离矩阵
3)计算最邻近距离的平均值,作为观测平均距离
4)使用公式E(d)=1/(2*sqrt(n/A)),n为点数量,A为研究区面积计算随机分布情况下的平均期望距离
5)根据R=观测平均距离/期望平均距离计算最邻近指数NNI
6)Z检验值:表明地震空间分布的聚集效应是显著的
7)p值:空间数据为随机分布的概率

结果

数据点数量: 412
研究区域面积: 24284430.17 平方公里
点密度: 1.70e-11 点/平方米

距离统计:
平均观测距离: 36617.0250 米
平均期望距离: 121390.6830 米

指数和检验:
最邻近指数 (R): 0.3016
Z统计量: -27.1178
p值: 0.000000

空间分布模式: 强聚集分布
统计显著性: 极显著 (p < 0.01)

分析结论:
地震点呈现显著的强聚集分布,说明地震事件在空间上不是随机分布的,而是存在明显的聚集现象。
def calculate_study_area(coords):
    """
    计算研究区域面积
    使用最小外接矩形作为研究区域
    
    Args:
        coords: 点坐标数组
        
    Returns:
        area: 研究区域面积(平方米)
    """
    print("\n计算研究区域面积:")
    print("-" * 40)
    
    if coords is None:
        print("错误: 坐标数据为空")
        return None
    
    # 获取坐标范围
    x_min, y_min = coords.min(axis=0)
    x_max, y_max = coords.max(axis=0)
    
    # 计算矩形面积
    width = x_max - x_min
    height = y_max - y_min
    area = width * height
    
    print(f"研究区域宽度: {width:.2f} 米")
    print(f"研究区域高度: {height:.2f} 米")
    print(f"研究区域面积: {area:.2e} 平方米")
    print(f"研究区域面积: {area / 1e6:.2f} 平方公里")
    
    return area


def calculate_nearest_distances(coords):
    """
    计算每个点到其最近邻点的距离
    
    Args:
        coords: 点坐标数组
        
    Returns:
        nearest_distances: 最近邻距离数组
    """
    print("\n计算最近邻距离:")
    print("-" * 40)
    
    if coords is None:
        print("错误: 坐标数据为空")
        return None
    
    # 计算所有点之间的距离矩阵
    distance_matrix = cdist(coords, coords)
    
    # 将对角线设为无穷大(避免点到自身的距离为0)
    np.fill_diagonal(distance_matrix, np.inf)
    
    # 找到每个点的最近邻距离
    nearest_distances = np.min(distance_matrix, axis=1)
    
    print(f"最近邻距离统计:")
    print(f"  最小距离: {nearest_distances.min():.2f} 米")
    print(f"  最大距离: {nearest_distances.max():.2f} 米")
    print(f"  平均距离: {nearest_distances.mean():.2f} 米")
    print(f"  标准差: {nearest_distances.std():.2f} 米")
    
    return nearest_distances


def calculate_mean_observed_distance(nearest_distances):
    """
    计算平均观测距离
    
    Args:
        nearest_distances: 最近邻距离数组
        
    Returns:
        mean_observed: 平均观测距离
    """
    mean_observed = np.mean(nearest_distances)
    
    print(f"\n平均观测距离: {mean_observed:.4f} 米")
    return mean_observed


def calculate_mean_expected_distance(n_points, study_area):
    """
    计算平均期望距离(随机分布情况下)
    公式: E(d) = 1 / (2 * sqrt(ρ))
    其中 ρ = n / A (点密度)
    
    Args:
        n_points: 点数量
        study_area: 研究区域面积
        
    Returns:
        mean_expected: 平均期望距离
    """
    if study_area is None or n_points == 0:
        print("错误: 研究区域面积或点数量为空")
        return None
    
    # 计算点密度
    density = n_points / study_area
    
    # 计算平均期望距离
    mean_expected = 1 / (2 * math.sqrt(density))
    
    print(f"点密度: {density:.2e} 点/平方米")
    print(f"平均期望距离: {mean_expected:.4f} 米")
    
    return mean_expected


def calculate_nearest_neighbor_index(mean_observed_distance, mean_expected_distance):
    """
    计算最邻近指数
    公式: R = 观测平均距离 / 期望平均距离
    
    Args:
        mean_observed_distance: 平均观测距离
        mean_expected_distance: 平均期望距离
        
    Returns:
        nn_index: 最邻近指数
    """
    if mean_observed_distance == 0 or mean_expected_distance == 0:
        print("错误: 观测距离或期望距离为零")
        return None
    
    nn_index = mean_observed_distance / mean_expected_distance
    
    print(f"\n最邻近指数 (R): {nn_index:.4f}")
    
    # 解释结果
    if nn_index < 1:
        interpretation = "聚集分布 (Clustered)"
    elif nn_index == 1:
        interpretation = "随机分布 (Random)"
    else:
        interpretation = "离散分布 (Dispersed)"
    
    print(f"分布模式: {interpretation}")
    
    return nn_index


def calculate_z_test(mean_observed_distance, mean_expected_distance, n_points, study_area):
    """
    计算Z检验统计量和p值
    公式: Z = (观测距离 - 期望距离) / 标准误
    标准误 = 0.26136 / sqrt(n * ρ)
    
    Args:
        mean_observed_distance: 平均观测距离
        mean_expected_distance: 平均期望距离
        n_points: 点数量
        study_area: 研究区域面积
        
    Returns:
        z_score: Z统计量
        p_value: p值
    """
    if (mean_observed_distance == 0 or 
        mean_expected_distance == 0 or 
        study_area is None or 
        n_points == 0):
        print("错误: 缺少必要的参数")
        return None, None
    
    # 计算点密度
    density = n_points / study_area
    
    # 计算标准误
    standard_error = 0.26136 / math.sqrt(n_points * density)
    
    # 计算Z统计量
    z_score = (mean_observed_distance - mean_expected_distance) / standard_error
    
    # 计算p值(双尾检验)
    p_value = 2 * (1 - stats.norm.cdf(abs(z_score)))
    
    print(f"\nZ检验结果:")
    print(f"标准误: {standard_error:.6f}")
    print(f"Z统计量: {z_score:.4f}")
    print(f"p值: {p_value:.6f}")
    
    # 显著性检验结果
    alpha_levels = [0.01, 0.05, 0.10]
    print(f"\n显著性检验结果:")
    for alpha in alpha_levels:
        if p_value < alpha:
            significance = f"在{alpha}水平上显著"
        else:
            significance = f"在{alpha}水平上不显著"
        print(f"  α = {alpha}: {significance}")
    
    return z_score, p_value

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions