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中计算皮尔逊相关系数时遇到负数求根的问题如何解决?
不太懂你说的东西,不过我看到
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)}")
关键点:
- 使用
max(0, value)确保平方和非负 - 检查分母为零的情况
- 将结果限制在[-1, 1]范围内
- 使用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
应该是浮点数精度问题
就是两个相同的数最后进行减法计算 得出负数
数值运算误差。
首先这两个数并不相同。

