在机器学习和统计学中,线性回归是一种常用的预测模型,用于分析一个或多个自变量对因变量的影响。在某些情况下,希望模型的回归系数非负,即模型预测的输出值不能由负系数产生。这时,非负最小二乘法(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")