为何未缩放与缩放数据集的线性回归线视觉一致,且原始图Y轴未压制X轴?
BP Diastolic与Annual Income散点图问题解答
问题描述
用户编写Python代码,分别基于原始数据集和MinMaxScaler缩放后的数据集绘制BP Diastolic与Annual Income的散点图及线性回归线,但两张图视觉效果完全一致,存在两个疑问:
- 为何未缩放与缩放数据集对应的线性回归线看起来相同?
- 为何原始数据图中数值范围更大的Y轴(Annual Income)未压制X轴(BP Diastolic)的显示?
代码与数据集
代码
from sklearn.preprocessing import StandardScaler from sklearn.preprocessing import MinMaxScaler from sklearn.datasets import load_iris import numpy as np import matplotlib.pyplot as plt import pandas as pd from sklearn.linear_model import LinearRegression pd.set_option('display.max_colwidth', None) pd.set_option('display.max_columns', None) def loadSkewedData(): skewedDF = pd.read_csv("skewedData.csv") return skewedDF skewedDataDF = loadSkewedData() scaler = MinMaxScaler() # 注释有误:MinMaxScaler是缩放到[0,1]区间,并非均值0、标准差1 scaledData = scaler.fit_transform(skewedDataDF) scaledDataDF = pd.DataFrame(scaledData, columns=skewedDataDF.columns) ax = plt.axes() ax.scatter(skewedDataDF["BP Diastolic"], skewedDataDF["Annual Income"]) plt.title("BP Diastolic vs Annual Income, Raw (unscaled) Data") plt.xlabel("BP Diastolic") plt.ylabel("Annual Income") model = LinearRegression() model.fit(np.array(skewedDataDF["BP Diastolic"]).reshape(-1, 1) , np.array(skewedDataDF["Annual Income"]).reshape(-1, 1) ) x_new = np.linspace(skewedDataDF["BP Diastolic"].min(), skewedDataDF["BP Diastolic"].max(), 100) y_new = model.predict(x_new[:, np.newaxis]) ax.plot(x_new, y_new) plt.show() # Plot scaled data ax = plt.axes() ax.scatter(scaledDataDF["BP Diastolic"], scaledDataDF["Annual Income"]) plt.title("BP Diastolic vs Annual Income, Normalized (Min/Max) Data") plt.xlabel("BP Diastolic") plt.ylabel("Annual Income") model = LinearRegression() model.fit(np.array(scaledDataDF["BP Diastolic"]).reshape(-1, 1) , np.array(scaledDataDF["Annual Income"]).reshape(-1, 1) ) x_new = np.linspace(scaledDataDF["BP Diastolic"].min(), scaledDataDF["BP Diastolic"].max(), 100) y_new = model.predict(x_new[:, np.newaxis]) ax.plot(x_new, y_new) plt.show()
数据集(skewedData.csv)
BP Diastolic,BP Cystolic,A1C,BMI,Annual Income 140, 90, 5.7, 25, 60000 145, 95, 6.0, 30, 90000 140, 80, 5.9, 23, 45000 149, 85, 5.8, 24, 109000 130, 85, 5.8, 29, 34000 132, 90, 5.5, 24, 256000 139, 90, 5.4, 27, 67000 138, 87, 5.3, 27, 55000
问题解答
1. 回归线视觉效果相同的原因
MinMaxScaler是对特征做线性缩放,公式为:
X_scaled = (X - X_min) / (X_max - X_min)
线性回归拟合的是y = a*x + b的线性关系,当x和y都经过线性变换后,新的回归方程只是原方程的线性变形。而Matplotlib绘图时,坐标轴的刻度会跟着数据缩放同步调整,所以回归线的倾斜程度在视觉上完全一致。
举个实际例子:
- 原始X(BP Diastolic)范围是[130,149],缩放后变为[0,1]
- 原始Y(Annual Income)范围是[34000,256000],缩放后变为[0,1]
原始回归方程的斜率a,在缩放后会转换为a * (X_max - X_min) / (Y_max - Y_min),但因为Y轴刻度从几万变成了0-1,X轴刻度从130-149变成0-1,这条线在图上的视觉斜率和原始图完全一样,看起来就像同一条线。
2. Y轴数值范围大但未压制X轴的原因
Matplotlib默认会自适应调整坐标轴的刻度范围和比例,目的是让数据分布清晰展示。原始数据中X轴的数值范围小(130-149),Y轴范围大(34000-256000),但Matplotlib会给两个轴分别设置合适的刻度间隔,不会强制两个轴的单位长度一致。
如果手动设置plt.axis('equal'),强制两个轴的单位长度相同,X轴才会被压缩得几乎看不见,但默认的自适应逻辑会优先保证每个轴的数据都能正常呈现,所以不会出现Y轴压制X轴的情况。
内容的提问来源于stack exchange,提问作者nicomp
相关产品推荐
相关产品推荐

