scipy中的线性最小二乘 - QR分解与其他方法的准确性

时间:2013-04-18 03:11:25

标签: scipy linear-algebra

我尝试使用以下方法解决scipy中的线性最小二乘问题Ax = b:

x = numpy.linalg.inv(A.T.dot(A)).dot(A.T).dot(b) #Usually not recommended

x = numpy.linalg.lstsq(A, b)

两者都给出了几乎相同的结果。我也尝试手动使用QR算法,即:

Qmat, Rmat = la.qr(A)

bpr = dot(Qmat.T,b)
n=len(bpr)
x = np.zeros(n)
for i in xrange(n-1, -1,-1):
    x[i] = bpr[i]
    for j in xrange(i+1, n):
        x[i] -= Rmat[i, j]*x[j]
    x[i] /= Rmat[i,i]

然而,这种方法给出了非常不准确的结果(错误大约为1e-2)。我在代码或数学上犯了n00b错误吗?或者,这个方法是一个问题,还是scipy本身?

我的numpy版本是1.6.1(来自http://www.lfd.uci.edu/~gohlke/pythonlibs/的mkl编译版本),x86_64上的Python 2.7.3。

2 个答案:

答案 0 :(得分:2)

如果您使用这些二进制文件,则QR因子分解由英特尔MKL计算,可能是正确的。

对我来说,上面的代码为随机矩阵提供了正确结果的1e-12范围内的解决方案。您使用哪些矩阵进行测试,以及如何衡量错误?

有些情况下,最小二乘问题是病态的。例如, 对于具有大空值空间的矩阵,舍入误差会影响结果。考虑秩-1矩阵:

np.random.seed(1234)
v = np.random.rand(100)
A = v[:,None] * v[None,:]
b = np.random.randn(100)

x = scipy.linalg.lstsq(A, b)[0]
print(np.linalg.norm(A.dot(x) - b))
# -> 9.63612833771

# xp obtained using your above code
print(np.linalg.norm(A.dot(xp) - b))
# -> 3262.61161684

你的home-brewn三角形求解比lstsq中使用的更精心编写的LAPACK例程更容易出现舍入误差,因此它的准确性会稍差。

答案 1 :(得分:0)

您也可以尝试使用截断的特征分解。这意味着使用top k eigen value。我使用以下代码来规范最小二乘回归,y = kc

enter image description here

其中u是特征向量,lambda是特征值

线性模型的核矩阵:

k=np.dot(X,X.T)

然后是eigendecompostion:

 w, v = scipy.linalg.eigh(k, eigvals=(lo, hi))

然后

temp= np.dot(np.dot(v,np.diag(1.0/w)),v.T)
c=np.dot(temp,y)

对于正则化,你应该在核矩阵的对角线上添加一个小值(如0.001),否则你会有负特征值,这会阻止你的核矩阵不是正定的。