最小绝对偏差(LAD)

最小绝对偏差 (Least Absolute Deviations, LAD) 与最小二乘法(假设误差服从高斯分布)类似:当假设线性回归的误差服从拉普拉斯分布时,最小绝对偏差回归是对参数的最大似然估计。

问题描述

min ⁡ x ∣ ∣ W x − y ∣ ∣ 1 \min_{x} \quad || Wx-y||_1 xminWxy1
等价于
min ⁡ ν s . t . ν = ∣ ∣ W x − y ∣ ∣ 1 \begin{array}{ll} \min & \nu \\ s.t. & \nu = || Wx-y||_1 \end{array} mins.t.νν=Wxy1
等价于
min ⁡ ν s . t . ∣ ∣ W x − y ∣ ∣ 1 ≤ ν \begin{array}{ll} \min & \nu \\ s.t. & || Wx-y||_1 \leq \nu \end{array} mins.t.νWxy1ν
等价于
min ⁡ ν s . t . W x − y ≤ ν , − W x + y ≤ ν , \begin{array}{ll} \min & \nu \\ s.t. & Wx-y \leq \nu, \\ & -Wx+y \leq \nu, \end{array} mins.t.νWxyν,Wx+yν,

min ⁡ ν s . t . W x − ν ≤ y , − W x − ν ≤ − y , \begin{array}{ll} \min & \nu \\ s.t. & Wx-\nu \leq y, \\ & -Wx -\nu \leq -y, \end{array} mins.t.νWxνy,Wxνy,

min ⁡ [ 0 I ] ⊤ [ x ν ] s . t . [ W − I − W − I ] [ x ν ] ≤ [ y − y ] \begin{array}{ll} \min & \left[\begin{array}{ll} 0 &I\end{array}\right]^\top \left[\begin{array}{ll} x \\ \nu \end{array}\right] \\\\ s.t. & \left[\begin{array}{cc} W & -I \\ -W & -I\end{array}\right] \left[\begin{array}{c} x \\ \nu\end{array}\right] \leq \left[\begin{array}{c} y \\ -y\end{array}\right] \end{array} mins.t.[0I][xν][WWII][xν][yy]

可见,该问题可以转化成标准的线性规划问题!!!

cvxopt 求解器

#Sources: http://cvxopt.org/examples/mlbook/l1.html?highlight=l1

from cvxopt import blas, lapack, solvers
from cvxopt import matrix, spdiag, mul, div, sparse 
from cvxopt import spmatrix, sqrt, base

def l1(P, q):
    P,q = matrix(P), matrix(q)
    m, n = P.size
    c = matrix(n*[0.0] + m*[1.0])
    h = matrix([q, -q])

    def Fi(x, y, alpha = 1.0, beta = 0.0, trans = 'N'):    
        if trans == 'N':
            u = P*x[:n]
            y[:m] = alpha * ( u - x[n:]) + beta*y[:m]
            y[m:] = alpha * (-u - x[n:]) + beta*y[m:]
        else:
            y[:n] =  alpha * P.T * (x[:m] - x[m:]) + beta*y[:n]
            y[n:] = -alpha * (x[:m] + x[m:]) + beta*y[n:]

    def Fkkt(W): 
        d1, d2 = W['d'][:m], W['d'][m:]
        D = 4*(d1**2 + d2**2)**-1
        A = P.T * spdiag(D) * P
        lapack.potrf(A)

        def f(x, y, z):
            x[:n] += P.T * ( mul( div(d2**2 - d1**2, d1**2 + d2**2), x[n:]) 
                + mul( .5*D, z[:m]-z[m:] ) )
            lapack.potrs(A, x)

            u = P*x[:n]
            x[n:] =  div( x[n:] - div(z[:m], d1**2) - div(z[m:], d2**2) + 
                mul(d1**-2 - d2**-2, u), d1**-2 + d2**-2 )

            z[:m] = div(u-x[n:]-z[:m], d1)
            z[m:] = div(-u-x[n:]-z[m:], d2)
        return f

    uls =  +q
    lapack.gels(+P, uls)
    rls = P*uls[:n] - q 

    x0 = matrix( [uls[:n],  1.1*abs(rls)] ) 
    s0 = +h
    
    Fi(x0, s0, alpha=-1, beta=1) 

    if max(abs(rls)) > 1e-10:  
        w = .9/max(abs(rls)) * rls
    else: 
        w = matrix(0.0, (m,1))
    z0 = matrix([.5*(1+w), .5*(1-w)])

    dims = {'l': 2*m, 'q': [], 's': []}
    
    s0 = np.array(s0)
    s0[s0<=0]=1e-8
    s0 =  matrix(s0)
    
    sol = solvers.conelp(c, Fi, h, dims, kktsolver = Fkkt,  
        primalstart={'x': x0, 's': s0}, dualstart={'z': z0})
    return sol['x'][:n]

测试

A = np.random.random((10,10))
x = np.random.randn((10))
y = A @ x
n = np.random.laplace(0, 0.01, 10)
y += n

res = l1(A,y)
res = np.squeeze(res)

plt.subplot(1,2,1)
plt.bar(np.arange(len(res)),res, alpha=0.5)
plt.title('solution')
plt.subplot(1,2,2)
plt.bar(np.arange(len(x)),x, alpha=0.5)
plt.title('ground truth')

在这里插入图片描述

### 使用最小绝对偏差法进行直线拟合 #### 最小绝对偏差法简介 最小绝对偏差法(Least Absolute Deviation, LAD),也称为L1范数回归,是一种用于估计模型参数的方法。相比于传统的最小二乘法,该方法通过最小化残差的绝对值之和来寻找最佳拟合直线。 对于给定的数据集 \((x_i, y_i)\),目标是最小化下述表达式的值: \[ S = \sum_{i=1}^{n}|y_i - (ax_i + b)| \] 其中 \(a\) 和 \(b\) 是待求解的斜率和截距[^2]。 由于绝对值函数不可导,在实际计算过程中通常采用线性规划或其他数值优化技术实现最优解搜索。 #### Python代码示例 下面是一个简单的Python程序,展示了如何利用`scipy.optimize.linprog()`来进行最小绝对偏差直线拟合: ```python import numpy as np from scipy import optimize def lad_line_fit(x_data, y_data): n = len(x_data) c = np.ones(n) A_ub = [] b_ub = [] for i in range(n): row_pos = [-x_data[i], -1, 1] row_neg = [x_data[i], 1, 1] A_ub.append(row_pos) A_ub.append(row_neg) b_ub.append(-y_data[i]) b_ub.append(y_data[i]) res = optimize.linprog(c=c, A_ub=A_ub, b_ub=b_ub, bounds=[(None, None), (None, None)], method='highs') a, b = res.x[:2] return a, b if __name__ == "__main__": # 测试数据点 x_test = np.array([1, 2, 3, 4, 5]) y_test = np.array([2.9, 5.1, 7.8, 9.6, 12.3]) slope, intercept = lad_line_fit(x_test, y_test) print(f"Slope: {slope:.4f}, Intercept: {intercept:.4f}") ``` 此段代码定义了一个名为`lad_line_fit`的功能函数,它接受两组输入数组作为横坐标\(x\)与纵坐标\(y\)的位置,并返回所找到的最佳拟合直线的斜率以及截距。这里采用了SciPy库中的线性规划求解器`linprog`完成最优化问题解决过程。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颹蕭蕭

白嫖?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值