回归模型中成本函数的L1范数而不是L2范数

时间:2018-08-16 18:12:02

标签: python machine-learning regression least-squares

我想知道Python中是否有一个函数可以做与scipy.linalg.lstsq相同的工作,但是使用“最小绝对偏差”回归而不是“最小二乘”回归(OLS)。我想使用L1规范,而不是L2规范。

实际上,我有3d点,我想要它们中最适合的平面。通用方法是通过最小二乘方法,例如Github link。但是众所周知,这并不总是总能提供最佳的拟合度,尤其是当我们在数据集中拥有闯入者时。并且最好计算最小的绝对偏差。 here进一步说明了这两种方法之间的区别。

由于它是Ax = b矩阵方程,并且需要循环以使结果最小化,因此无法通过MAD之类的函数进行求解。我想知道是否有人知道Python中的相关功能-可能在线性代数包中-可以计算“最小绝对偏差”回归?

2 个答案:

答案 0 :(得分:4)

使用data-iso2="in"和自定义scipy.optimize.minimize来滚动自己并不困难。

让我们首先导入必需品,

cost_function

并定义一个自定义成本函数(以及用于获取拟合值的便利包装),

from scipy.optimize import minimize
import numpy as np

然后,如果您有一些def fit(X, params): return X.dot(params) def cost_function(params, X, y): return np.sum(np.abs(y - fit(X, params))) (设计矩阵)和X(观察),我们可以执行以下操作,

y

output = minimize(cost_function, x0, args=(X, y)) y_hat = fit(X, output.x) 是最佳参数的合适初始猜测(您可以在这里接受@JamesPhillips的建议,并使用OLS方法中的拟合参数)。

在任何情况下,当使用某些人为的示例进行测试运行时,

x0

我发现

X = np.asarray([np.ones((100,)), np.arange(0, 100)]).T
y = 10 + 5 * np.arange(0, 100) + 25 * np.random.random((100,))

然后

      fun: 629.4950595335436
 hess_inv: array([[  9.35213468e-03,  -1.66803210e-04],
       [ -1.66803210e-04,   1.24831279e-05]])
      jac: array([  0.00000000e+00,  -1.52587891e-05])
  message: 'Optimization terminated successfully.'
     nfev: 144
      nit: 11
     njev: 36
   status: 0
  success: True
        x: array([ 19.71326758,   5.07035192])

拟合值显示为蓝色,数据显示为黑色。

enter image description here

答案 1 :(得分:0)

您可以使用scipy.minimize函数解决问题。您必须设置要最小化的函数(在本例中为Z = aX + bY + c形式的平面)和误差函数(L1范数),然后以某个起始值运行最小化器。

import numpy as np
import scipy.linalg
from scipy.optimize import minimize
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

def fit(X, params):
    # 3d Plane Z = aX + bY + c
    return X.dot(params[:2]) + params[2]

def cost_function(params, X, y):
    # L1- norm
    return np.sum(np.abs(y - fit(X, params)))

我们生成3d点

# Generating  3-dim points
mean = np.array([0.0,0.0,0.0])
cov = np.array([[1.0,-0.5,0.8], [-0.5,1.1,0.0], [0.8,0.0,1.0]])
data = np.random.multivariate_normal(mean, cov, 50)# some 3-dim points
mean = np.array([0.0,0.0,0.0])

最后,我们运行最小化器

output = minimize(cost_function, [0.5,0.5,0.5], args=(np.c_[data[:,0], data[:,1]], data[:, 2]))
y_hat = fit(np.c_[data[:,0], data[:,1]], output.x)

X,Y = np.meshgrid(np.arange(min(data[:,0]), max(data[:,0]), 0.5),    np.arange(min(data[:,1]), max(data[:,1]), 0.5))
XX = X.flatten()
YY = Y.flatten()


# # evaluate it on grid
Z = output.x[0]*X + output.x[1]*Y + output.x[2]
fig = plt.figure(figsize=(10,10))
ax = fig.gca(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, alpha=0.2)
ax.scatter(data[:,0], data[:,1], data[:,2], c='r')
plt.show()

enter image description here

注意:我已经使用了先前的响应代码和来自github的code作为开始