计算机系统应用教程网站

网站首页 > 技术文章 正文

数据分析-多项式回归分析Python 多项式回归代码

btikc 2024-10-25 10:53:37 技术文章 6 ℃ 0 评论

回归分析是一种重要的统计方法,用于研究因变量与自变量之间的关系。这个系列估计还需要一段时间才能写完。今天继续多项式回归。多项式回归是回归分析的一种扩展形式,通过引入自变量的高次项来捕捉数据中的非线性关系。

多项式回归是线性回归的一种扩展形式,它通过引入自变量的多项式项来拟合非线性关系。与简单线性回归不同,多项式回归能够捕捉更复杂的趋势和模式。

多项式回归模型的一般形式为:

其中,是因变量,是自变量,0-d是模型参数,是多项式的阶数,?是误差项。

【多项式回归的假设】

多项式回归与线性回归有类似的假设:

线性假设:因变量与自变量的关系可以通过多项式形式表示。

独立性:观测值之间相互独立。

同方差性:误差项的方差恒定。

正态性:误差项服从正态分布。

【多项式回归的优缺点】

优点:

1.能捕捉自变量与因变量之间的非线性关系;

2.适用于复杂数据模式的建模。

缺点:

1.容易出现过拟合,尤其是在阶数较高时;

2.对数据量较小或噪声较大的情况不太适用。

【案例演示】

还是那个广告投入和销售额的模拟数据,形式很简单,直接开始模拟数据↓

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
np.random.seed(21)
n_samples = 300
X = np.random.rand(n_samples, 1) * 10  # 广告支出
y = 2 + 1.5 * X + X**2 + np.random.randn(n_samples, 1) * 10  # 销售额,加入噪声
data = pd.DataFrame(np.hstack([X, y]), columns=['广告支出', '销售额'])

在做数据分析之前,先看一下数据的分布情况,然后才大概知道选择什么样的模型↓

# 绘制数据分布图
plt.scatter(data['广告支出'], data['销售额'], color='blue')
plt.title('广告支出 vs 销售额')
plt.xlabel('广告支出')
plt.ylabel('销售额')
plt.show()

从数据图形可以看出,广告投入和销售额之间存在着明显的正相关,但是有一定的弧度,不是线性相关。这种可以使用多项式回归来实现,但是我们不知道是几项的多项式,就只能先试一下,从3阶开始,建立模型↓

# 多项式回归模型拟合
degree = 3  # 多项式阶数
poly_features = PolynomialFeatures(degree=degree)
X_poly = poly_features.fit_transform(X)
# 线性回归模型
model = LinearRegression()
model.fit(X_poly, y)
# 预测值
y_pred = model.predict(X_poly)

然后是几个重要的模型拟合参数↓

# 模型评估
mse = mean_squared_error(y, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y, y_pred)
print(f'MSE: {mse}')
print(f'R2: {r2}')

MSE: 97.92045846453856

R2: 0.9245052141637775

可以看到R^2还是很好,说明模型拟合效果还不错,再绘制一下预测数据和实际数据的图形看一下↓

plt.scatter(data['广告支出'], data['销售额'], color='blue')
plt.plot(data['广告支出'], y_pred, color='red', linewidth=2)
plt.title('广告支出 vs 销售额 (多项式回归)')
plt.xlabel('广告支出')
plt.ylabel('销售额')
plt.show()

但是我们这里只是凭直接选择了3次方,但是实际什么数值最合适,需要多尝试几个数字才行。我们这里就使用5个阶数来看一下效果就行了↓

from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import cross_val_score
# 尝试不同的多项式阶数
degrees = [1, 2, 3, 4, 5]
results = []
for degree in degrees:
    poly_features = PolynomialFeatures(degree=degree)
    X_poly = poly_features.fit_transform(X)
    # 线性回归模型
    model = LinearRegression()
    model.fit(X_poly, y)
    y_pred = model.predict(X_poly)
    
    # 评估指标
    mse = mean_squared_error(y, y_pred)
    rmse = np.sqrt(mse)
    mae = mean_absolute_error(y, y_pred)
    r2 = r2_score(y, y_pred)
    # 交叉验证
    cv_scores = cross_val_score(model, X_poly, y, cv=5, scoring='neg_mean_squared_error')
    cv_rmse = np.sqrt(-cv_scores).mean()
    
    results.append((degree, mse, rmse, mae, r2, cv_rmse))
    print(f'Degree: {degree}')
    print(f'MSE: {mse:.4f}')
    print(f'RMSE: {rmse:.4f}')
    print(f'MAE: {mae:.4f}')
    print(f'R2: {r2:.4f}')
    print(f'CV RMSE: {cv_rmse:.4f}')
    print('-' * 30)
# 将结果转换为DataFrame
results_df = pd.DataFrame(results,
                          columns=['Degree', 'MSE', 'RMSE', 'MAE', 'R2', 'CV RMSE'])

通过交叉验证的结果,我们可以选择具有最低交叉验证均方根误差(CV RMSE)的多项式阶数。这里我们可以发现,2阶的效果是最优的,所以我们就选择2阶来作为模型的最优解。

选择具有最低交叉验证均方根误差(CV RMSE)的多项式阶数的原因如下:

1. 减少过拟合和欠拟合

过拟合:

当多项式阶数过高时,模型可能会过度拟合训练数据,即模型过于复杂,能很好地拟合训练数据中的噪声,但在新数据上表现不佳。这会导致模型对训练数据有很高的R2值或很低的训练误差,但对新数据的预测性能差,表现为高的测试误差。

欠拟合:

当多项式阶数过低时,模型可能无法捕捉数据中的真实模式,即模型过于简单,不能很好地拟合训练数据中的趋势。这会导致模型在训练数据和新数据上的性能都较差。

通过交叉验证,我们可以同时考虑模型在训练数据和新数据上的表现。交叉验证的思想是将数据分成多个子集,在每个子集上进行训练和测试,以此来评估模型的泛化能力。

2. 提供更可靠的模型评估

交叉验证(如k折交叉验证)通过多次将数据划分为训练集和验证集,计算每次验证集上的误差,并取平均值。相比单一的训练/测试划分,交叉验证能更可靠地评估模型的性能,因为它减小了因数据划分不同带来的随机性。

3. 均方根误差(RMSE)作为评价指标的优点

均方根误差(RMSE)是衡量模型预测误差的标准指标,它反映了预测值与实际值之间的平均差距。选择最低CV RMSE的多项式阶数可以帮助我们找到误差最小的模型,即在新数据上预测最准确的模型。

【数据预测】

模型阶数最后确定后,就可以进行数据的预测了↓

# 选择最佳阶数
best_degree = results_df.loc[results_df['CV RMSE'].idxmin(), 'Degree']
print(f'最佳多项式阶数: {best_degree}')


# 使用最佳阶数重新训练模型
poly_features = PolynomialFeatures(degree=int(best_degree))
X_poly = poly_features.fit_transform(X)
model = LinearRegression()
model.fit(X_poly, y)
# 新数据生成
X_new = np.linspace(0, 10, 100).reshape(-1, 1)
X_new_poly = poly_features.transform(X_new)
y_new_pred = model.predict(X_new_poly)

【最后绘制图形】

# 绘制预测结果
plt.scatter(data['广告支出'], data['销售额'], color='blue')
plt.plot(X_new, y_new_pred, color='red', linewidth=2)
plt.title(f'广告支出 vs 销售额 (多项式阶数: {int(best_degree)})')
plt.xlabel('广告支出')
plt.ylabel('销售额')
plt.show()

我们了解了多项式回归的理论基础、模型构建方法以及如何评估模型性能。我们使用Python进行了实战演练,模拟了电商数据,并通过交叉验证选择了最佳的多项式阶数。最终,我们使用最佳模型对新数据进行了预测。通过这些步骤,我们展示了如何应用多项式回归来捕捉数据中的非线性关系,并为实际的数据分析提供了指导。

链接是我使用PowerBI整合的历史文章,按类型分类,可以根据需求查询:Microsoft Power BI↓

https://app.powerbi.com/view?r=eyJrIjoiNjI2NWQ3NjktYjU0ZC00ZWZhLTgzMDgtMGI4ZTk1ZDlkODM3IiwidCI6IjI3NDQ3MWQ0LTM4ZDQtNDVlZS1hMmJkLWU1NTVhOTBkYzM4NiJ9

End

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表