【发布时间】:2021-06-25 08:08:31
【问题描述】:
我尝试进行自己的线性回归,但我发现 LinearRegression 与 sklearn 存在差异。事实上,这就是我自己的线性回归:
>>> beta = estimate_beta(X_train.values, y_train.values)
>>> (X_test*beta).sum(axis = 1)
1142949 777.876173
696990 1010.574350
1437036 852.938428
1404619 439.875784
1151040 1002.271470
...
848794 396.552199
291118 3137.906208
128267 541.926482
459668 752.088114
1120216 424.453391
Length: 482738, dtype: float64
这与 sklearn 返回的内容非常不同:
array([[3.24519438],
[2.12164625],
[0.98814432],
...,
[1.13965629],
[2.09961495],
[1.84152796]])
当然还有真正的价值观:
array([[2.],
[1.],
[1.],
...,
[1.],
[4.],
[2.]])
我自己的模型为什么会得到与实际值相差甚远的结果?
这是我的模型:
import numpy as np
def predict(x_i, beta):
"""assumes that the first element of each x_i is 1"""
return np.dot(x_i, beta)
def error(x_i, y_i, beta):
return y_i - predict(x_i, beta)
def squared_error(x_i, y_i, beta):
return error(x_i, y_i, beta) ** 2
def squared_error_gradient(x_i, y_i, beta):
"""The gradient (with respect to beta)
correspond to the ith squared error term"""
return [-2 * x_ij * error(x_i, y_i, beta)
for x_ij in x_i]
def estimate_beta(x, y):
beta_initial = [random.random() for x in x[0]]
return minimize_stochastic(squared_error,
squared_error_gradient,
x, y,
beta_initial,
0.01)
def in_random_order(data):
"""generator that returns the elements of data in random order"""
indexes = [i for i, _ in enumerate(data)] # create a list of indexes
random.shuffle(indexes) # suffle them
for i in indexes:
yield data[i]
def minimize_stochastic(target_fn, gradient_fn, x, y, theta_0, alpha_0=0.01):
data = zip(x, y)
theta = theta_0 # the initial guess
alpha = alpha_0 # initial step size
min_theta, min_value = None, float("inf") # the minimum so far
iterations_with_no_improvement = 0
# if we ever go 100 iterations with no improvement, stop
while iterations_with_no_improvement <100:
value = sum(target_fn(x_i, y_i, theta) for x_i, y_i in data)
if value < min_value:
# if we've found a new minimum, remeber it
# and go back to the original step size
min_theta, min_value = theta, value
iterations_with_no_improvement = 0
alpha = alpha_0
else:
# otherwise we're not improving, so try shinking the step_size
iterations_with_no_improvement += 1
alpha *= 0.9
# and take a gradient step for each of the data points
for x_i, y_i in in_random_order(data):
gradient_i = gradient_fn(x_i, y_i, theta)
theta = np.substract(theta, alpha * gradient_i)
return min_theta
我尝试了一个最小且可重现的代码:
>>>x = [[1, 49, 4, 2500],[1, 12, 2, 125], [1, 35, 2, 3790], [1, 60, 4, 4500], [1, 10, 4, 5000]]
>>>spendings_customer = [2000, 0, 3600, 0, 3500]
>>>import random
>>>random.seed(0)
>>>beta = estimate_beta(x, spendings_customer)
返回给我:
[0.8444218515250481,
0.7579544029403025,
0.420571580830845,
0.25891675029296335]
这很奇怪……
具有来自损失的粗麻布的学习率
问题可能是因为我的学习率太大了。成本函数的最佳学习率严格小于 2/λ,其中 λ 是 Hessian 的最大特征值。我想获得我的梯度下降算法的学习率。所以我尝试使用this answer 来计算它:
$$H_L(w) = X^T X$$
# Hessian is X.t*X
h = np.dot(X_test.T,X_test)
from numpy import linalg as LA
w, v = LA.eig(np.array(h))
max(w)
返回:
(74119951381184.84+0j)
所以我将 alpha_0 更改为小于 2/λ 但预测看起来仍然与实际结果有很大不同:
1142949 1883.752457
696990 1015.531962
1437036 3342.723244
1404619 397.374124
1151040 3485.172794
...
848794 2366.912144
291118 2037.073368
128267 1853.395186
459668 4395.533697
1120216 786.328257
Length: 482738, dtype: float64
【问题讨论】:
-
不太清楚你在问什么。您可以轻松地测试,“否”,
zip是一次性的。 围绕单独使用zip的大量代码与是/否问题有什么关系? -
这能回答你的问题吗? python3 zip result used twice
-
我意识到我关于学习率的问题实际上与 zip 迭代器有一个初始问题(因为我正在将 Python2 代码改编为 python3 代码)。这就是我最近改变我的问题而不是删除它的原因,@MisterMiyagi
标签: python-3.x machine-learning linear-regression