Python实战开发及案例分析(10)—— 最小二乘法

发布于:2024-05-07 ⋅ 阅读:(30) ⋅ 点赞:(0)

        最小二乘法是一种用于拟合数据的线性回归技术,它通过最小化残差平方和来找到最佳拟合线。通常用于估计线性关系,但也可以扩展到多元回归和非线性关系中。Python 提供了多种方式来实现最小二乘法,包括使用 NumPySciPyscikit-learn

案例分析:使用 NumPy 实现最小二乘法

        我们可以使用 NumPy 的线性代数功能 np.linalg.lstsq() 来直接求解线性方程组。这个函数使用最小二乘法求解线性方程 y=β0​+β1​x。

Python 实现:

import numpy as np
import matplotlib.pyplot as plt

# 生成示例数据
np.random.seed(0)
X = 2.5 * np.random.randn(100) + 1.5  # 生成100个随机数作为X
Y = 2 * X + np.random.randn(100) * 0.5 + 0.8  # 生成Y

# 将数据转换为矩阵形式
X_mat = np.vstack([X, np.ones(len(X))]).T

# 使用 NumPy 的 lstsq 求解最小二乘法方程
coefficients, residuals, rank, s = np.linalg.lstsq(X_mat, Y, rcond=None)
slope, intercept = coefficients

# 打印回归系数
print(f"Intercept: {intercept:.3f}")
print(f"Slope: {slope:.3f}")

# 绘制结果
plt.scatter(X, Y, label='Data points')
plt.plot(X, slope * X + intercept, color='red', label='Fitted line')
plt.xlabel("X")
plt.ylabel("Y")
plt.title("Linear Regression using Least Squares")
plt.legend()
plt.show()

案例分析:使用 SciPy 实现最小二乘法

  SciPy 提供了 scipy.optimize.curve_fit 函数来拟合非线性模型。我们可以定义线性模型,然后使用该函数进行拟合。

Python 实现:

from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt

# 生成示例数据
np.random.seed(0)
X = 2.5 * np.random.randn(100) + 1.5
Y = 2 * X + np.random.randn(100) * 0.5 + 0.8

# 定义线性模型
def linear_model(x, a, b):
    return a * x + b

# 使用 curve_fit 进行拟合
params, covariance = curve_fit(linear_model, X, Y)
slope, intercept = params

# 打印回归系数
print(f"Intercept: {intercept:.3f}")
print(f"Slope: {slope:.3f}")

# 绘制结果
plt.scatter(X, Y, label='Data points')
plt.plot(X, slope * X + intercept, color='red', label='Fitted line')
plt.xlabel("X")
plt.ylabel("Y")
plt.title("Linear Regression using SciPy")
plt.legend()
plt.show()

案例分析:使用 scikit-learn 实现最小二乘法

  scikit-learn 提供了方便的接口来进行线性回归。我们可以直接使用 LinearRegression 模型进行拟合。

Python 实现:

from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt

# 生成示例数据
np.random.seed(0)
X = 2.5 * np.random.randn(100) + 1.5
Y = 2 * X + np.random.randn(100) * 0.5 + 0.8

# 将 X 转换为二维数组
X = X.reshape(-1, 1)

# 使用 scikit-learn 进行线性回归
model = LinearRegression()
model.fit(X, Y)
slope = model.coef_[0]
intercept = model.intercept_

# 打印回归系数
print(f"Intercept: {intercept:.3f}")
print(f"Slope: {slope:.3f}")

# 绘制结果
plt.scatter(X, Y, label='Data points')
plt.plot(X, model.predict(X), color='red', label='Fitted line')
plt.xlabel("X")
plt.ylabel("Y")
plt.title("Linear Regression using scikit-learn")
plt.legend()
plt.show()

结论

        通过使用 NumPySciPyscikit-learn 实现最小二乘法,可以清晰地看到不同工具的特点:

  1. NumPy 提供了最基础的线性代数功能,可以直接求解线性方程组。
  2. SciPy 提供了通用的拟合工具,支持更复杂的模型。
  3. scikit-learn 提供了方便的机器学习接口,并整合了更多评估和调优功能。

        不同的库适用于不同的场景,了解它们的特点和使用方法可以帮助我们在实际工作中更好地选择合适的工具。

继续深入探讨最小二乘法的应用,我们可以扩展到多元线性回归和多项式回归。

案例分析:多元线性回归

        在多元线性回归中,我们会有多个自变量(特征)用于预测目标变量。我们将使用scikit-learn来实现这个过程。

多元线性回归的 Python 实现

代码实现:

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt

# 生成示例数据
np.random.seed(0)
n_samples = 100
X1 = 2.5 * np.random.randn(n_samples) + 1.5  # 第一特征
X2 = 3 * np.random.randn(n_samples) + 2.0    # 第二特征
Y = 2 * X1 + 1.5 * X2 + np.random.randn(n_samples) * 0.5 + 0.8

# 将多元特征组合成二维数组
X = np.column_stack([X1, X2])

# 划分训练集和测试集
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=42)

# 使用 scikit-learn 进行多元线性回归
model = LinearRegression()
model.fit(X_train, Y_train)

# 打印回归系数
print("Intercept:", model.intercept_)
print("Coefficients:", model.coef_)

# 预测
Y_pred = model.predict(X_test)

# 绘制结果
plt.scatter(Y_test, Y_pred)
plt.xlabel("Actual values")
plt.ylabel("Predicted values")
plt.title("Multivariate Linear Regression")
plt.plot([min(Y_test), max(Y_test)], [min(Y_test), max(Y_test)], color='red', linewidth=2)
plt.show()

案例分析:多项式回归

        多项式回归是一种扩展的线性回归模型,将特征进行多项式扩展以拟合非线性关系。可以使用PolynomialFeatures进行特征扩展,然后使用线性回归进行拟合。

多项式回归的 Python 实现

代码实现:

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

# 生成示例数据
np.random.seed(0)
n_samples = 100
X = np.linspace(-3, 3, n_samples)
Y = 0.5 * X**2 - 1.5 * X + 2 + np.random.randn(n_samples) * 1.5

# 将 X 转换为二维数组
X = X.reshape(-1, 1)

# 划分训练集和测试集
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=42)

# 创建多项式特征
poly = PolynomialFeatures(degree=2)
X_poly_train = poly.fit_transform(X_train)
X_poly_test = poly.transform(X_test)

# 使用 scikit-learn 进行多项式回归
model = LinearRegression()
model.fit(X_poly_train, Y_train)

# 打印回归系数
print("Intercept:", model.intercept_)
print("Coefficients:", model.coef_)

# 预测
Y_pred = model.predict(X_poly_test)

# 绘制结果
plt.scatter(X_test, Y_test, label='Actual values')
plt.scatter(X_test, Y_pred, color='red', label='Predicted values')
plt.xlabel("X")
plt.ylabel("Y")
plt.title("Polynomial Regression")
plt.legend()
plt.show()

结论

        通过多元线性回归和多项式回归的案例分析,我们了解到最小二乘法不仅可以用于简单的线性关系预测,还可以扩展到更复杂的模型:

  1. 多元线性回归:允许我们使用多个特征进行预测,并且能够量化每个特征对预测的影响。
  2. 多项式回归:通过特征扩展以适应非线性关系,提供更灵活的拟合能力。

        理解这些模型的特点和使用方法对于实际应用非常重要。它们在经济预测、工程模拟、医疗分析等领域都具有广泛的应用前景。

        继续深入探讨最小二乘法的应用,我们可以研究岭回归和套索回归,这两种技术通过正则化来减少过拟合,并提高模型的泛化能力。

案例分析:岭回归

岭回归(Ridge Regression)是一种线性回归方法,通过添加L2正则化项来减少模型的复杂度,从而减小过拟合的影响。

Python 实现:

代码实现:

from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt

# 生成示例数据
np.random.seed(0)
n_samples = 100
X1 = 2.5 * np.random.randn(n_samples) + 1.5  # 第一特征
X2 = 3 * np.random.randn(n_samples) + 2.0    # 第二特征
Y = 2 * X1 + 1.5 * X2 + np.random.randn(n_samples) * 0.5 + 0.8

# 将多元特征组合成二维数组
X = np.column_stack([X1, X2])

# 划分训练集和测试集
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=42)

# 使用 Ridge 回归
ridge = Ridge(alpha=1.0)  # 调整 alpha 值以改变正则化强度
ridge.fit(X_train, Y_train)

# 打印回归系数
print("Intercept:", ridge.intercept_)
print("Coefficients:", ridge.coef_)

# 预测
Y_pred = ridge.predict(X_test)

# 绘制结果
plt.scatter(Y_test, Y_pred)
plt.xlabel("Actual values")
plt.ylabel("Predicted values")
plt.title("Ridge Regression")
plt.plot([min(Y_test), max(Y_test)], [min(Y_test), max(Y_test)], color='red', linewidth=2)
plt.show()

案例分析:套索回归

        套索回归(Lasso Regression)通过添加L1正则化项,使得某些系数变为零,从而可以用于特征选择和减少过拟合的影响。

Python 实现:

代码实现:

from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt

# 生成示例数据
np.random.seed(0)
n_samples = 100
X1 = 2.5 * np.random.randn(n_samples) + 1.5  # 第一特征
X2 = 3 * np.random.randn(n_samples) + 2.0    # 第二特征
Y = 2 * X1 + 1.5 * X2 + np.random.randn(n_samples) * 0.5 + 0.8

# 将多元特征组合成二维数组
X = np.column_stack([X1, X2])

# 划分训练集和测试集
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=42)

# 使用 Lasso 回归
lasso = Lasso(alpha=0.1)  # 调整 alpha 值以改变正则化强度
lasso.fit(X_train, Y_train)

# 打印回归系数
print("Intercept:", lasso.intercept_)
print("Coefficients:", lasso.coef_)

# 预测
Y_pred = lasso.predict(X_test)

# 绘制结果
plt.scatter(Y_test, Y_pred)
plt.xlabel("Actual values")
plt.ylabel("Predicted values")
plt.title("Lasso Regression")
plt.plot([min(Y_test), max(Y_test)], [min(Y_test), max(Y_test)], color='red', linewidth=2)
plt.show()

案例分析:弹性网络回归

        弹性网络回归(ElasticNet Regression)结合了岭回归和套索回归的特点,通过同时添加L1和L2正则化项进行正则化。

Python 实现:

代码实现:

from sklearn.linear_model import ElasticNet
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt

# 生成示例数据
np.random.seed(0)
n_samples = 100
X1 = 2.5 * np.random.randn(n_samples) + 1.5  # 第一特征
X2 = 3 * np.random.randn(n_samples) + 2.0    # 第二特征
Y = 2 * X1 + 1.5 * X2 + np.random.randn(n_samples) * 0.5 + 0.8

# 将多元特征组合成二维数组
X = np.column_stack([X1, X2])

# 划分训练集和测试集
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=42)

# 使用 ElasticNet 回归
elasticnet = ElasticNet(alpha=0.1, l1_ratio=0.5)  # l1_ratio 调整 L1/L2 正则化的权重
elasticnet.fit(X_train, Y_train)

# 打印回归系数
print("Intercept:", elasticnet.intercept_)
print("Coefficients:", elasticnet.coef_)

# 预测
Y_pred = elasticnet.predict(X_test)

# 绘制结果
plt.scatter(Y_test, Y_pred)
plt.xlabel("Actual values")
plt.ylabel("Predicted values")
plt.title("ElasticNet Regression")
plt.plot([min(Y_test), max(Y_test)], [min(Y_test), max(Y_test)], color='red', linewidth=2)
plt.show()

结论

        通过分析和实现岭回归、套索回归以及弹性网络回归,可以了解到:

  1. 岭回归(Ridge Regression)

    • 添加L2正则化项,减小系数的幅度,提高模型的稳定性。
  2. 套索回归(Lasso Regression)

    • 添加L1正则化项,使部分系数变为零,进行特征选择。
  3. 弹性网络回归(ElasticNet Regression)

    • 同时添加L1和L2正则化项,结合岭回归和套索回归的优点。

        正则化技术在实际数据建模中非常重要,可以提高模型的泛化能力,减少过拟合影响。通过灵活调整正则化项的权重,可以在模型复杂性和拟合能力之间找到平衡。