必学!线性回归 10 种图表!!

文摘   科技   2024-09-01 21:57   北京  

核心点:学习线性回归,必须要弄到这10种图表!

哈喽,我是cos大壮~

这段时间,不少同学提到了一些图表的问题。

每次在使用matplotlib画图,运用这些图表说明问题的时候,很多时候是模糊的,比如说什么时候画什么图合适?

其实这个根据你自己的需求,自己的想法来就行。

今天的话,我这里举例在线性回归中,最常用的一些图表,应该可以cover绝大多数情况了。其他算法模型适用的图表,咱们在后面再给大家进行总结~

至于数据集,表现方式,大家可以根据我给出的代码继续调整即可!

那么,在线性回归学习中,以下10种图表是很重要的:

  • 散点图
  • 线性趋势线图
  • 残差图(Residual plot)
  • 正态概率图
  • 学习曲线
  • 方差-偏差权衡图
  • 残差对预测值图
  • 部分回归图
  • 杠杆图
  • Cook's 距离图

老规矩大家伙如果觉得近期文章还不错!欢迎大家点个赞、转个发~

有同学想要获取 PDF 文档,记得文末私信即可!

OK,咱们一起来看看~

01

散点图

散点图(Scatter plot)是一种展示两个变量之间关系的图表。它通过在坐标系中以点的形式表示数据,其中每个点的位置由两个变量的值决定,从而展示它们之间的关系。

在线性回归中,散点图通常用于可视化数据集中两个变量之间的关系,并帮助我们判断是否适合使用线性模型进行建模。

咱们使用sklearn库中的load_diabetes数据集。然后,将选择数据集中的一个特征作为自变量X,另一个特征作为因变量y。后面的案例,也用这个数据集给大家进行演示~

from sklearn.datasets import load_diabetes

# 加载数据集
diabetes = load_diabetes()
X = diabetes.data[:, 2]  # 使用第三个特征作为自变量
y = diabetes.target

# 手动实现简单线性回归算法
def simple_linear_regression(X, y):
    # 计算均值
    X_mean = sum(X) / len(X)
    y_mean = sum(y) / len(y)
    
    # 计算斜率和截距
    numerator = sum((X - X_mean) * (y - y_mean))
    denominator = sum((X - X_mean) ** 2)
    slope = numerator / denominator
    intercept = y_mean - slope * X_mean
    
    return slope, intercept

# 获取回归直线的斜率和截距
slope, intercept = simple_linear_regression(X, y)

现在,画出散点图并添加回归直线。

import matplotlib.pyplot as plt

# 绘制散点图
plt.scatter(X, y, color='blue', label='Data points')
# 添加回归直线
plt.plot(X, slope*X + intercept, color='red', label='Regression line')
plt.xlabel('X label')
plt.ylabel('y label')
plt.title('Scatter plot with regression line')
plt.legend()
plt.show()

为什么使用散点图?

因为散点图可以直观地展示数据的分布情况,同时通过添加回归直线,我们可以更好地理解数据的趋势和线性关系。这种图表有助于我们验证线性回归模型的有效性,并且可以用来预测新的数据点。

02

线性趋势线图

线性趋势线图(Linear trend line plot)是一种在散点图中添加一条直线来表示数据的线性趋势的图表。这条直线通常被称为趋势线或回归线,它可以帮助我们更清晰地看到数据的整体趋势,特别是在数据点分布较为杂乱或噪声较多时。

在线性回归中,线性趋势线图用于可视化数据集中自变量和因变量之间的线性关系,以及线性回归模型拟合的效果。

from sklearn.datasets import load_diabetes

# 加载数据集
diabetes = load_diabetes()
X = diabetes.data[:, 2]  # 使用第三个特征作为自变量
y = diabetes.target

# 手动实现简单线性回归算法
def simple_linear_regression(X, y):
    # 计算均值
    X_mean = sum(X) / len(X)
    y_mean = sum(y) / len(y)
    
    # 计算斜率和截距
    numerator = sum((X - X_mean) * (y - y_mean))
    denominator = sum((X - X_mean) ** 2)
    slope = numerator / denominator
    intercept = y_mean - slope * X_mean
    
    return slope, intercept

# 获取回归直线的斜率和截距
slope, intercept = simple_linear_regression(X, y)

现在,可以画出线性趋势线图来表示算法的效果。

import seaborn as sns
import matplotlib.pyplot as plt

# 绘制线性趋势线图,样本点为红色,拟合线为蓝色
sns.regplot(x=X, y=y, color='red', scatter_kws={'color''blue''s'10})  # s设置散点的大小
plt.xlabel('X label')
plt.ylabel('y label')
plt.title('Linear trend line plot')
plt.show()

为什么使用线性趋势线图?

因为线性趋势线图可以帮助我们更直观地看到数据的整体趋势,特别是在数据点分布较为杂乱或噪声较多时,趋势线可以帮助我们更清晰地理解数据的线性关系,并验证线性回归模型的有效性。这种图表有助于我们预测新的数据点并评估模型的拟合效果。

03

残差图

残差图(Residual plot)通过将数据点的残差(预测值与实际值之间的差异)绘制在纵轴上,自变量的值(或者预测值)绘制在横轴上,来展示模型的拟合情况和误差分布。在理想情况下,残差应该随机地分布在横轴上,没有明显的模式,如果残差图显示出某种模式,则可能表示模型存在问题。

from sklearn.datasets import load_diabetes

# 加载数据集
diabetes = load_diabetes()
X = diabetes.data[:, 2]  # 使用第三个特征作为自变量
y = diabetes.target

# 手动实现简单线性回归算法
def simple_linear_regression(X, y):
    # 计算均值
    X_mean = sum(X) / len(X)
    y_mean = sum(y) / len(y)
    
    # 计算斜率和截距
    numerator = sum((X - X_mean) * (y - y_mean))
    denominator = sum((X - X_mean) ** 2)
    slope = numerator / denominator
    intercept = y_mean - slope * X_mean
    
    return slope, intercept

# 获取回归直线的斜率和截距
slope, intercept = simple_linear_regression(X, y)

# 计算预测值
y_pred = slope * X + intercept

# 计算残差
residuals = y - y_pred

现在,我们可以画出残差图来表示算法的效果。

import matplotlib.pyplot as plt

# 绘制残差图
plt.scatter(X, residuals, color='blue')
plt.axhline(y=0, color='red', linestyle='--')  # 添加水平参考线
plt.xlabel('X label')
plt.ylabel('Residuals')
plt.title('Residual plot')
plt.show()

为什么使用残差图?

因为残差图可以帮助我们检验线性回归模型是否合适。在理想情况下,残差应该随机地分布在横轴上,没有明显的模式。如果残差图显示出某种模式(如残差随自变量增大而增大或减小),则可能表示模型存在问题,需要进一步改进。这种图表有助于我们评估模型的拟合效果和准确性。

04

正态概率图

正态概率图(Normal probability plot)是一种用于检验数据是否符合正态分布的图表。在正态概率图中,将数据的标准化值(即Z分数)绘制在纵轴上,理论上的正态分布的分位数对应值(即标准正态分布的分位数)绘制在横轴上。如果数据符合正态分布,那么点应该沿着一条直线大致分布。

在线性回归中,正态概率图用于检验模型的残差是否符合正态分布。如果残差符合正态分布,则说明模型的假设是合理的,可以进行进一步的分析和预测。

from sklearn.datasets import load_diabetes

# 加载数据集
diabetes = load_diabetes()
X = diabetes.data[:, 2]  # 使用第三个特征作为自变量
y = diabetes.target

# 手动实现简单线性回归算法
def simple_linear_regression(X, y):
    # 计算均值
    X_mean = sum(X) / len(X)
    y_mean = sum(y) / len(y)
    
    # 计算斜率和截距
    numerator = sum((X - X_mean) * (y - y_mean))
    denominator = sum((X - X_mean) ** 2)
    slope = numerator / denominator
    intercept = y_mean - slope * X_mean
    
    return slope, intercept

# 获取回归直线的斜率和截距
slope, intercept = simple_linear_regression(X, y)

# 计算预测值
y_pred = slope * X + intercept

# 计算残差
residuals = y - y_pred

现在,画出正态概率图来表示算法的效果。

import scipy.stats as stats
import matplotlib.pyplot as plt

# 绘制正态概率图
stats.probplot(residuals, dist="norm", plot=plt)
plt.xlabel('Theoretical quantiles')
plt.ylabel('Ordered residuals')
plt.title('Normal probability plot')
plt.show()

为什么使用正态概率图?

因为正态概率图可以帮助我们检验模型的残差是否符合正态分布。如果点大致沿着一条直线分布,那么残差就符合正态分布,说明模型的假设是合理的。这种图表有助于我们验证模型的假设,评估模型的拟合效果和准确性。

05

学习曲线

学习曲线(Learning curve)是一种展示模型在训练集和验证集上表现随训练样本数量变化的图表。它通常将训练集和验证集的误差(如均方误差)或准确率作为纵轴,训练样本数量作为横轴,可以帮助我们分析模型的拟合情况和泛化能力。

在线性回归中,学习曲线可以帮助我们判断模型是否过拟合或欠拟合。 当模型在训练集上表现良好但在验证集上表现较差时,可能存在过拟合;而当模型在两个集合上表现都较差时,可能存在欠拟合。通过观察学习曲线,可以调整模型的复杂度或者增加训练样本数量来改善模型的表现。

from sklearn.datasets import load_diabetes
from sklearn.model_selection import learning_curve
from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt

# 加载数据集
diabetes = load_diabetes()
X = diabetes.data[:, 2]  # 使用第三个特征作为自变量
y = diabetes.target

# 创建线性回归模型
model = LinearRegression()

# 计算学习曲线
train_sizes, train_scores, valid_scores = learning_curve(model, X[:, np.newaxis], y, train_sizes=[50100200300], cv=5)

# 计算训练集和验证集的平均误差
train_mean = np.mean(train_scores, axis=1)
train_std = np.std(train_scores, axis=1)
valid_mean = np.mean(valid_scores, axis=1)
valid_std = np.std(valid_scores, axis=1)

# 绘制学习曲线
plt.figure(figsize=(106))
plt.fill_between(train_sizes, train_mean - train_std, train_mean + train_std, alpha=0.1, color="r")
plt.fill_between(train_sizes, valid_mean - valid_std, valid_mean + valid_std, alpha=0.1, color="g")
plt.plot(train_sizes, train_mean, 'o-', color="r", label="Training score")
plt.plot(train_sizes, valid_mean, 'o-', color="g", label="Cross-validation score")
plt.xlabel("Training examples")
plt.ylabel("Score")
plt.title("Learning curve")
plt.legend(loc="best")
plt.show()

为什么使用学习曲线?

因为学习曲线可以帮助我们分析模型在不同训练样本数量下的表现,进而判断模型是否过拟合或欠拟合。通过观察学习曲线,我们可以选择合适的模型复杂度或增加训练样本数量来改善模型的表现,从而提高模型的泛化能力。这种图表有助于我们优化模型并提高预测的准确性。

06

方差-偏差权衡图

方差-偏差权衡图(Bias-variance tradeoff plot)是一种用于可视化模型的偏差和方差之间的权衡关系的图表。在机器学习中,一个模型的总误差可以分解为三部分:偏差(Bias)、方差(Variance)和不可避免的误差。偏差衡量了模型预测的平均准确度和真实数值之间的差距,方差衡量了模型在不同训练数据集上的变化程度。偏差-方差权衡是一个重要的概念,它告诉我们在训练模型时要权衡这两种误差,并避免过拟合(高方差、低偏差)或欠拟合(低方差、高偏差)。

在线性回归中,方差-偏差权衡图可以帮助我们选择合适的模型复杂度。当模型过于简单时(高偏差),可能会出现欠拟合;当模型过于复杂时(高方差),可能会出现过拟合。通过观察方差-偏差权衡图,我们可以找到一个适当的模型复杂度,以获得最佳的预测性能。

from sklearn.datasets import load_diabetes
from sklearn.model_selection import validation_curve
from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt

# 加载数据集
diabetes = load_diabetes()
X = diabetes.data[:, 2]  # 使用第三个特征作为自变量
y = diabetes.target

# 创建线性回归模型
model = LinearRegression()

# 计算方差-偏差权衡图
param_range = np.arange(110)
train_scores, valid_scores = validation_curve(model, X[:, np.newaxis], y, param_name="fit_intercept", param_range=param_range, cv=5, scoring="neg_mean_squared_error")

# 计算训练集和验证集的平均误差
train_mean = -np.mean(train_scores, axis=1)
train_std = np.std(train_scores, axis=1)
valid_mean = -np.mean(valid_scores, axis=1)
valid_std = np.std(valid_scores, axis=1)

# 绘制方差-偏差权衡图
plt.figure(figsize=(106))
plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, alpha=0.1, color="r")
plt.fill_between(param_range, valid_mean - valid_std, valid_mean + valid_std, alpha=0.1, color="g")
plt.plot(param_range, train_mean, 'o-', color="r", label="Training score")
plt.plot(param_range, valid_mean, 'o-', color="g", label="Cross-validation score")
plt.xlabel("Model complexity")
plt.ylabel("Negative Mean Squared Error")
plt.title("Bias-variance tradeoff plot")
plt.legend(loc="best")
plt.show()

为什么使用方差-偏差权衡图?

因为方差-偏差权衡图可以帮助我们选择合适的模型复杂度,避免模型过拟合或欠拟合。通过观察方差-偏差权衡图,我们可以找到一个平衡点,以获得最佳的预测性能。这种图表有助于我们优化模型并提高预测的准确性。

07

残差对预测值图

残差对预测值图(Residuals vs Fitted plot)是一种用于检验线性回归模型是否适合的图表。它将模型预测值(拟合值)绘制在横轴上,残差(预测值与实际值之间的差异)绘制在纵轴上,用于观察残差是否随着预测值的增大而呈现出某种模式。

在线性回归中,残差对预测值图可以帮助我们检验模型的假设是否成立。理想情况下,残差应该随机地分布在横轴上,没有明显的模式。如果残差对预测值图显示出某种模式(如残差随着预测值的增大而增大或减小),则可能表示模型存在问题,需要进一步改进。

from sklearn.datasets import load_diabetes
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

# 加载数据集
diabetes = load_diabetes()
X = diabetes.data[:, 2]  # 使用第三个特征作为自变量
y = diabetes.target

# 创建线性回归模型
model = LinearRegression()
model.fit(X.reshape(-11), y)

# 计算预测值
y_pred = model.predict(X.reshape(-11))

# 计算残差
residuals = y - y_pred

# 绘制残差对预测值图
plt.figure(figsize=(86))
plt.scatter(y_pred, residuals, color='blue')
plt.axhline(y=0, color='red', linestyle='--')
plt.xlabel('Fitted values')
plt.ylabel('Residuals')
plt.title('Residuals vs Fitted plot')
plt.show()

为什么使用残差对预测值图?

因为残差对预测值图可以帮助我们检验模型的假设是否成立。如果残差随着预测值的增大而呈现出某种模式,可能表示模型存在问题,需要进一步改进。这种图表有助于我们验证模型的有效性,并且可以用来预测新的数据点。

08

部分回归图

部分回归图(Partial Regression Plot)是一种用于检验一个自变量对因变量的影响,同时控制其他自变量影响的图表。它通过绘制一个自变量与因变量之间的关系图,同时控制其他自变量的影响,来帮助我们理解这个自变量独立于其他变量时对因变量的影响程度。

在线性回归中,部分回归图可以帮助我们识别单个自变量对因变量的影响,排除了其他自变量的影响。这对于理解每个自变量的独立作用非常有帮助,并可以帮助我们判断模型是否正确地捕捉到了变量之间的关系。

from sklearn.datasets import load_diabetes
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
import matplotlib.pyplot as plt
import numpy as np

# 加载数据集
diabetes = load_diabetes()
X = diabetes.data[:, 2]  # 使用第三个特征作为自变量
y = diabetes.target

# 创建多项式特征
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X.reshape(-11))

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_poly, y, test_size=0.2, random_state=42)

# 创建线性回归模型
model = LinearRegression()
model.fit(X_train, y_train)

# 绘制部分回归图
plt.figure(figsize=(86))
plt.scatter(X[:, 1], y, color='blue', label='Actual data')
plt.scatter(X[:, 1], model.predict(X_poly), color='red', label='Predicted data')
plt.xlabel('Partial Regression')
plt.ylabel('Target')
plt.title('Partial Regression Plot')
plt.legend()
plt.show()

为什么使用部分回归图?

因为部分回归图可以帮助我们理解单个自变量对因变量的影响,同时控制其他自变量的影响。这种图表有助于我们深入分析每个自变量的独立作用,并且可以帮助我们验证模型是否正确地捕捉到了变量之间的关系。

09

杠杆图

杠杆图(Leverage plot)是一种用于检验每个数据点对线性回归模型的影响程度的图表。它通过绘制每个数据点的杠杆值(leverage)来帮助我们识别在模型拟合中具有较大影响力的数据点。杠杆值反映了每个数据点对模型参数估计的影响程度,具有高杠杆值的数据点可能会对模型的拟合产生较大影响。

在线性回归中,杠杆图可以帮助我们识别可能具有异常影响力的数据点,这些数据点可能导致模型的不稳定性或偏差。 通过观察杠杆图,我们可以检查这些数据点,并决定是否需要对它们进行处理(如排除或转换)以改善模型的性能。

from sklearn.datasets import load_diabetes
from sklearn.linear_model import LinearRegression
import statsmodels.api as sm
from statsmodels.graphics.regressionplots import plot_leverage_resid2
import matplotlib.pyplot as plt

# 加载数据集
diabetes = load_diabetes()
X = diabetes.data[:, 2]  # 使用第三个特征作为自变量
y = diabetes.target

# 创建线性回归模型
X = sm.add_constant(X)  # 添加截距项
model = sm.OLS(y, X).fit()

# 绘制杠杆图
plot_leverage_resid2(model)
plt.xlabel('Leverage')
plt.ylabel('Standardized Residuals Squared')
plt.title('Leverage Plot')
plt.show()

为什么使用杠杆图?

因为杠杆图可以帮助我们识别对模型具有较大影响力的数据点。通过观察杠杆图,我们可以检查这些数据点,并决定是否需要对它们进行处理以改善模型的性能。这种图表有助于我们识别潜在的异常数据点,并优化模型的拟合效果。

10

Cook's 距离图

Cook's 距离图(Cook's distance plot)是一种用于检验线性回归模型中每个数据点对模型参数估计的影响程度的图表。它通过计算每个数据点对模型参数的影响程度,来帮助我们识别可能具有较大影响力的数据点。

在线性回归中,Cook's 距离可以用来衡量删除某个数据点后模型参数的变化程度,从而评估该数据点对整个模型的影响程度。通常情况下,Cook's 距离大于1的数据点可能具有较大影响力,需要进行进一步分析。

from sklearn.datasets import load_diabetes
from statsmodels.regression.linear_model import OLS
import statsmodels.api as sm
import matplotlib.pyplot as plt

# 加载数据集
diabetes = load_diabetes()
X = diabetes.data[:, 2]  # 使用第三个特征作为自变量
y = diabetes.target

# 添加截距项
X = sm.add_constant(X)

# 拟合线性回归模型
model = OLS(y, X).fit()

# 计算 Cook's 距离
influence = model.get_influence()
cook_distance = influence.cooks_distance[0]

# 绘制 Cook's 距离图
plt.figure(figsize=(86))
plt.stem(cook_distance, markerfmt=",")
plt.xlabel('Data points')
plt.ylabel("Cook's distance")
plt.title("Cook's Distance Plot")
plt.show()

为什么使用Cook's 距离图?

因为Cook's 距离图可以帮助我们识别可能对模型具有较大影响力的数据点。通过观察Cook's 距离,我们可以找出这些数据点,并进一步分析它们对模型的影响,以优化模型的拟合效果。这种图表有助于我们识别潜在的异常数据点,并改进模型的性能。


最后

下一期,咱们会逐步分享,在其他算法模型的场景下,适合的图表有哪些。
喜欢本文的朋友可以收藏、点赞、转发起来!
需要本文PDF的同学,扫码备注「图表」即可~ 
关注本号,带来更多算法干货实例,提升工作学习效率!
最后,给大家准备了《机器学习学习小册》PDF版本16大块的内容,124个问题总结

推荐阅读

原创、超强、精华合集
100个超强机器学习算法模型汇总
机器学习全路线
机器学习各个算法的优缺点
7大方面,30个最强数据集
6大部分,20 个机器学习算法全面汇总
铁汁,都到这了,别忘记点赞呀~

深夜努力写Python
Python、机器学习算法
 最新文章