如何在log10对数坐标系中正确绘制线性回归线?
问题描述
我正在绘制两组数据freq(频率)和data(对应频率的数值观测值)的关系图,希望在log-log对数坐标系中使用stats.linregress执行普通最小二乘线性回归。我先将freq和data转换为np.log10形式,计划用plt.loglog绘制对数坐标系下的直线回归线,但红色回归线与绿色实际数据点相距甚远,请问如何修正使回归线贴合实际数据?
原可复现代码:
import numpy as np import matplotlib.pyplot as plt from scipy import stats # Data freq = [0.0102539, 0.0107422, 0.0112305, 0.0117188, 0.012207, 0.0126953, 0.0131836] data = [4.48575, 4.11893, 3.69591, 3.34766, 3.18452, 3.23554, 3.43357] # Plot log10 of freq vs. data plt.loglog(freq, data, c="green") # Linear regression log_freq = np.log10(freq) log_data = np.log10(data) reg = stats.linregress(log_freq, log_data) slope = reg[0] intercept = reg[1] plt.plot(freq, slope*log_freq + intercept, color="red")
问题原因
你的代码存在两个关键错误:
- 绘制回归线时,直接使用了对数域的计算结果
slope*log_freq + intercept,但这个值是对数尺度的y值,而plt.plot会把它当作原始数值处理,相当于把对数结果直接放到了原始尺度坐标系中,数值完全不匹配。 - 绘制回归线时用了
plt.plot而非和原始数据一致的plt.loglog,且未将回归结果转换回原始数值尺度。
修正方案
需要把对数回归得到的结果转换回原始数值尺度,再绘制回归线,修正后的代码如下:
import numpy as np import matplotlib.pyplot as plt from scipy import stats # 数据 freq = [0.0102539, 0.0107422, 0.0112305, 0.0117188, 0.012207, 0.0126953, 0.0131836] data = [4.48575, 4.11893, 3.69591, 3.34766, 3.18452, 3.23554, 3.43357] # 绘制原始数据的log-log图 plt.loglog(freq, data, c="green", label="原始数据") # 对数转换后执行线性回归 log_freq = np.log10(freq) log_data = np.log10(data) reg = stats.linregress(log_freq, log_data) slope = reg.slope intercept = reg.intercept # 将对数域的回归结果转换回原始数值尺度 reg_line = 10 ** (slope * log_freq + intercept) # 绘制回归线 plt.loglog(freq, reg_line, color="red", label="回归线") plt.legend() plt.xlabel("频率") plt.ylabel("观测值") plt.show()
关键修正点
- 用
10 ** (slope * log_freq + intercept)将对数回归的计算结果转换回原始数值尺度,确保和原始数据处于同一尺度下。 - 使用
plt.loglog绘制回归线,和原始数据的绘图逻辑保持一致,保证在log-log坐标系中显示正确。
内容的提问来源于stack exchange,提问作者Philipp
相关产品推荐
相关产品推荐

