线性回归实现总是比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

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

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