Python中计算皮尔逊相关系数时遇到负数求根的问题如何解决?

print (738.0-pow(340.0,2)/len(v1)),(3782.6436028-pow(1634.18064594,2)/len(v1))

print sum1sq, sum1, sum2sq, sum2

print ‘=’*30

print sum2sq

print pow(sum2, 2) / 706

print sum2sq - pow(sum2, 2) / 706

print ‘=’ * 30

下面是执行的结果


574.260623229 1.68902261066e-08

738.0 340.0 3782.6436028 1634.18064594

==============================

3782.6436028

3782.6436028

-7.32143234927e-11

==============================


上面的代码一一对应 我不明白

为什么会变成负数 而我写固定的数能计算正确 有没有大佬解惑 谢谢啦
Python中计算皮尔逊相关系数时遇到负数求根的问题如何解决?


7 回复

不太懂你说的东西,不过我看到

3782.6436028
3782.6436028

这两个是一样的?什么东西变成了负数?


遇到负数求根的问题,通常是因为在计算皮尔逊相关系数时,公式中的分母出现了负值,导致无法进行平方根运算。皮尔逊相关系数的计算公式为:

[ r = \frac{\sum (x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum (x_i - \bar{x})^2 \sum (y_i - \bar{y})^2}} ]

分母中的两个平方和 (\sum (x_i - \bar{x})^2) 和 (\sum (y_i - \bar{y})^2) 理论上应为非负数,但计算中可能因浮点误差或数据问题导致负值。以下是完整的解决方案:

import numpy as np

def pearson_correlation(x, y):
    """
    计算皮尔逊相关系数,避免负数求根问题
    """
    # 转换为numpy数组
    x = np.asarray(x)
    y = np.asarray(y)
    
    # 检查数据长度
    if len(x) != len(y):
        raise ValueError("x和y的长度必须相同")
    
    # 计算均值
    mean_x = np.mean(x)
    mean_y = np.mean(y)
    
    # 计算偏差
    dev_x = x - mean_x
    dev_y = y - mean_y
    
    # 计算分子
    numerator = np.sum(dev_x * dev_y)
    
    # 计算分母的两部分
    sum_sq_dev_x = np.sum(dev_x ** 2)
    sum_sq_dev_y = np.sum(dev_y ** 2)
    
    # 处理可能的负值(通常由浮点误差引起)
    sum_sq_dev_x = max(0, sum_sq_dev_x)
    sum_sq_dev_y = max(0, sum_sq_dev_y)
    
    # 检查分母是否为零
    if sum_sq_dev_x == 0 or sum_sq_dev_y == 0:
        return 0.0  # 如果任一变量的方差为零,相关系数为0
    
    # 计算相关系数
    denominator = np.sqrt(sum_sq_dev_x * sum_sq_dev_y)
    correlation = numerator / denominator
    
    # 确保结果在[-1, 1]范围内
    correlation = max(-1.0, min(1.0, correlation))
    
    return correlation

# 测试示例
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]
print(f"皮尔逊相关系数: {pearson_correlation(x, y)}")  # 应输出1.0

# 测试有浮点误差的情况
x = [1.0000001, 2.0000002, 3.0000003]
y = [1.0, 2.0, 3.0]
print(f"皮尔逊相关系数: {pearson_correlation(x, y)}")

关键点:

  1. 使用max(0, value)确保平方和非负
  2. 检查分母为零的情况
  3. 将结果限制在[-1, 1]范围内
  4. 使用numpy提高计算精度

如果使用numpy或scipy,可以直接用内置函数:

from scipy import stats
import numpy as np

x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 6, 8, 10])
r, p_value = stats.pearsonr(x, y)
print(f"scipy计算结果: r={r}, p={p_value}")

总结:确保平方和非负并处理边界情况。

目测浮点数精度问题 有精度要求改用 Decimal

应该是浮点数精度问题

就是两个相同的数最后进行减法计算 得出负数

数值运算误差。

首先这两个数并不相同。

回到顶部