非负最小二乘法与普通最小二乘法比较

在机器学习和统计学中,线性回归是一种常用的预测模型,用于分析一个或多个自变量对因变量的影响。在某些情况下,希望模型的回归系数非负,即模型预测的输出值不能由负系数产生。这时,非负最小二乘法(NNLS)就派上了用场。本文将通过一个实例,展示如何使用非负最小二乘法,并将其结果与普通最小二乘法(OLS)进行比较。

生成随机数据

首先,需要生成一些随机数据来模拟实际情况。在这个例子中,生成了200个样本和50个特征的数据集。然后,为这些数据生成了真实的回归系数,并将其中小于0的系数置为0,以满足非负性的要求。接着,通过矩阵乘法和添加噪声来生成目标变量y。

import numpy as np np.random.seed(42) n_samples, n_features = 200, 50 X = np.random.randn(n_samples, n_features) true_coef = 3 * np.random.randn(n_features) true_coef[true_coef < 0] = 0 y = np.dot(X, true_coef) y += 5 * np.random.normal(size=(n_samples,))

数据集的划分

在实际应用中,需要将数据集划分为训练集和测试集,以便评估模型的性能。这里使用sklearn库中的train_test_split函数来实现这一步骤,将数据集分为50%的训练集和50%的测试集。

from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5)

非负最小二乘法的实现

接下来,使用sklearn库中的LinearRegression类来实现非负最小二乘法。通过设置positive=True参数,可以确保回归系数非负。然后,使用训练集数据来拟合模型,并使用测试集数据来预测结果。最后,计算模型的R^2分数,以评估模型的性能。

from sklearn.linear_model import LinearRegression reg_nnls = LinearRegression(positive=True) y_pred_nnls = reg_nnls.fit(X_train, y_train).predict(X_test) r2_score_nnls = r2_score(y_test, y_pred_nnls) print("NNLS R2 score", r2_score_nnls)

普通最小二乘法的实现

为了比较非负最小二乘法和普通最小二乘法的差异,还需要实现普通最小二乘法。这里同样使用LinearRegression类,但不设置positive参数。然后,使用相同的训练集和测试集数据来拟合模型和预测结果,并计算R^2分数。

reg_ols = LinearRegression() y_pred_ols = reg_ols.fit(X_train, y_train).predict(X_test) r2_score_ols = r2_score(y_test, y_pred_ols) print("OLS R2 score", r2_score_ols)

回归系数的比较

通过比较两种方法得到的回归系数,可以发现它们之间存在高度相关性。然而,由于非负性约束,非负最小二乘法会将一些系数压缩至0,从而产生稀疏的结果。这种稀疏性是许多实际应用中所期望的特性,因为它有助于提高模型的可解释性和泛化能力。

import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot(reg_ols.coef_, reg_nnls.coef_, linewidth=0, marker=".") low_x, high_x = ax.get_xlim() low_y, high_y = ax.get_ylim() low = max(low_x, low_y) high = min(high_x, high_y) ax.plot([low, high], [low, high], ls="--", c=".3", alpha=0.5) ax.set_xlabel("OLS regression coefficients", fontweight="bold") ax.set_ylabel("NNLS regression coefficients", fontweight="bold")
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485