线性回归实现总是比sklearn表现差

我在Python中使用梯度下降法实现了线性回归。为了评估其表现,我将其与scikit-learn的LinearRegression()类进行了比较。不知为何,sklearn的平均均方误差(MSE)总是比我的程序低3(我使用波士顿房价数据集进行测试)。我知道目前我没有进行梯度检查来确认是否收敛,但我允许进行多次迭代,并且将学习率设置得足够低,应该可以收敛。我的学习算法实现中是否有明显的错误?这是我的代码:

import numpy as npfrom sklearn.linear_model import LinearRegressiondef getWeights(x):    lenWeights = len(x[1,:]);    weights = np.random.rand(lenWeights)    bias = np.random.random();    return weights,biasdef train(x,y,weights,bias,maxIter):    converged = False;    iterations = 1;    m = len(x);    alpha = 0.001;    while not converged:            for i in range(len(x)):                # Dot product of weights and training sample                hypothesis = np.dot(x[i,:], weights) + bias;                # Calculate gradient                error = hypothesis - y[i];                grad = (alpha * 1/m) * ( error * x[i,:] );                # Update weights and bias                weights = weights - grad;                bias = bias - alpha * error;                iterations = iterations + 1;                if iterations > maxIter:                    converged = True;                    break    return weights, biasdef predict(x, weights, bias):    return np.dot(x,weights) + biasif __name__ == '__main__':    data = np.loadtxt('housing.txt');    x = data[:,:-1];    y = data[:,-1];    for i in range(len(x[1,:])):        x[:,i] = ( (x[:,i] - np.min(x[:,i])) / (np.max(x[:,i]) - np.min(x[:,i])) );    initialWeights,initialBias = getWeights(x);    weights,bias = train(x,y,initialWeights,initialBias,55000);    pred = predict(x, weights,bias);    MSE = np.mean(abs(pred - y));    print "This Program MSE: " + str(MSE)    sklearnModel = LinearRegression();    sklearnModel = sklearnModel.fit(x,y);    sklearnModel = sklearnModel.predict(x);    skMSE = np.mean(abs(sklearnModel - y));    print "Sklearn MSE: " + str(skMSE)

回答:

首先,确保你计算的目标函数值是正确的。线性回归的目标函数应该是.5*np.mean((pred-y)**2),而不是np.mean(abs(pred - y))

你实际上是在运行随机梯度下降(SGD)算法(对单个样本进行梯度迭代),这与“梯度下降”是有区别的。

SGD是一种很好的学习方法,但作为优化方法却不尽如人意——它可能需要很多次迭代才能收敛到经验误差的最小值(http://leon.bottou.org/publications/pdf/nips-2007.pdf)。

为了使SGD收敛,学习率必须受到限制。通常,学习率设置为基础学习率除以迭代次数,像你的代码中的alpha/(iterations+1)这样。

你还在梯度中包含了1/m的倍数,这在SGD更新中通常不使用。

为了测试你的SGD实现,而不是在你训练过的数据集上评估误差,应该将数据集分成训练集和测试集,并在训练后用这两种方法在测试集上评估误差。训练/测试集的分割将允许你估计你的算法作为学习算法的表现(估计期望误差),而不是作为优化算法(最小化经验误差)。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注