Как мне связать, какое единственное значение соответствует какой записи?

Я использую подпрограмму numpy linalg lstsq для решения системы уравнений. Моя матрица A имеет размер (11046, 504), а моя матрица B имеет размер (11046, 1), а определенный ранг равен 249, поэтому примерно половина решенного массива x не особенно полезна. Я хотел бы использовать массив сингулярных значений s, чтобы обнулить решенные параметры, соответствующие сингулярным значениям, но кажется, что массив s отсортирован в порядке убывания статистической значимости. Есть ли способ выяснить, какие из моих x соответствуют каждому единственному значению s?


person Greg Hennessy    schedule 26.08.2013    source источник
comment
Не уверен, правильно ли я понял ваш вопрос, поэтому дайте мне знать, если решение, которое я предлагаю, более или менее то, что вы ищете...   -  person ThePhysicist    schedule 27.08.2013
comment
То, что вы предлагаете, похоже на то, что я хочу, мне нужно немного посмотреть, чтобы понять это, но спасибо!   -  person Greg Hennessy    schedule 27.08.2013
comment
Да, мне пришлось некоторое время подумать о проблеме, прежде чем понять ее, но я думаю, что это должно решить вашу проблему.   -  person ThePhysicist    schedule 27.08.2013
comment
Я думаю, что решение правильное, не стесняйтесь принять и проголосовать за него, кстати;)   -  person ThePhysicist    schedule 28.08.2013
comment
Я был бы рад. Как я могу это сделать? ;)   -  person Greg Hennessy    schedule 03.10.2013


Ответы (1)


Чтобы получить решение уравнения Mb = x по методу наименьших квадратов, заданное numpy.linalg.lstsq, вы также можете использовать numpy.linalg.svd, который вычисляет разложение по сингулярным числам M= U S V*. Тогда лучшее решение x определяется как x = V Sp U* b, где Sp является псевдообратным S. Имея матрицы U и V* (содержащие левый и правый сингулярные векторы вашей матрицы M) и сингулярные значения s, вы можете вычислить вектор z=V*x. Теперь все компоненты z_i из z с i > rank(M) могут быть выбраны произвольно без изменения решения, как и все компоненты x_j, которые не содержатся в z_i для i <= rank(M).

Вот пример, который демонстрирует, как получить важные компоненты x, используя примеры данных из статьи Википедии о разложении единичного значения. :

import numpy as np

M = np.array([[1,0,0,0,2],[0,0,3,0,0],[0,0,0,0,0],[0,4,0,0,0]])

#We perform singular-value decomposition of M
U, s, V = np.linalg.svd(M)

S = np.zeros(M.shape,dtype = np.float64)

b = np.array([1,2,3,4])

m = min(M.shape)

#We generate the matrix S (Sigma) from the singular values s
S[:m,:m] = np.diag(s)

#We calculate the pseudo-inverse of S
Sp = S.copy()

for m in range(0,m):
  Sp[m,m] = 1.0/Sp[m,m] if Sp[m,m] != 0 else 0

Sp = np.transpose(Sp)

Us = np.matrix(U).getH()
Vs = np.matrix(V).getH()

print "U:\n",U
print "V:\n",V
print "S:\n",S

print "U*:\n",Us
print "V*:\n",Vs
print "Sp:\n",Sp

#We obtain the solution to M*x = b using the singular-value decomposition of the matrix
print "numpy.linalg.svd solution:",np.dot(np.dot(np.dot(Vs,Sp),Us),b)

#This will print:
#numpy.linalg.svd solution: [[ 0.2         1.          0.66666667  0.          0.4       ]]

#We compare the solution to np.linalg.lstsq
x,residuals,rank,s =  np.linalg.lstsq(M,b)

print "numpy.linalg.lstsq solution:",x
#This will print:
#numpy.linalg.lstsq solution: [ 0.2         1.          0.66666667  0.          0.4       ]

#We determine the significant (i.e. non-arbitrary) components of x

Vs_significant = Vs[np.nonzero(s)]

print "Significant variables:",np.nonzero(np.sum(np.abs(Vs_significant),axis = 0))[1]

#This will print:
#Significant variables: [[0 1 2 4]]
#(i.e. x_3 can be chosen arbitrarily without altering the result)
person ThePhysicist    schedule 26.08.2013