Reputation: 89
So currently I'm working with code looking like:
Q,R = np.linalg.qr(matrix)
Qb = np.dot(Q.T, new_mu[b][n])
x_qr = np.linalg.solve(R, Qb)
mu.append(x_qr)
The code works fine as long as my matrix is square, but as soon as it's not, the system is not solvable and I got errors. If I've understood it right I can't use linalg.solve
on non-full rank matrices, but is there a way for me to get across this obstacle without using a lstsquare
solution?
Upvotes: 3
Views: 4757
Reputation: 579
you should try to incorporate rank-revealing QR decomposition with column-pivoting (e.g. like here) to below-mentioned solve
or Normal Equation solution, lstsq as I remember, probably, uses SVD-decomposition to get rank of linear system (that in general is considered to result in more numerically stable solutions) - remember rank-nullity theorem
p.s.
from LS Normal Equation intercept, *coef = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)
we can use equation (X.T.dot(X)).dot(β) = (X.T).dot(y)
from scipy import linalg
import numpy as np
from sklearn.datasets import make_regression
# Generate a regression problem
X, y = make_regression(
n_samples=50,
n_features=2,
n_informative=2,
noise = 10,
random_state=25
)
X_b = np.column_stack((np.ones(len(y)), X)) # for intercept
########################## solve for non-square
XtX = X_b.T.dot(X_b)
XtY = X_b.T.dot(y)
x1 = np.linalg.solve(XtX, XtY);
print(x1)
########################## least-squares - compute vector x such that 2-norm is minimized
x2, sse, rank, sva = linalg.lstsq(X_b, y)
print(x2)
########### check
# euclidean distance - here shows x_solve ~ x_lstsq
print("distance between vectors: ", np.linalg.norm(x1-x2,2))
print(np.allclose(x1, x2))
## distance between vectors: - as is tiny difference
## True
######################### check with ML
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(X, y)
print(f"Intercept: {lr.intercept_}\n\
Coefficients: {lr.coef_}")
Upvotes: 0
Reputation: 10489
No, this is not possible, as specified in the np.linalg.solve
docs.
The issue is that given Ax = b
, if A
is not square, then your equation is either over-determined or under-determined, assuming that all rows in A
are linearly independent. This means that there does not exist a single x
that solves this equation.
Intuitively, the idea is that if you have n
(length of x
) variables that you are trying to solve for, then you need exactly n
equations to find a unique solution for x
, assuming that these equations are not "redundant". In this case, "redundant" means linearly dependent: one equation is equal to the linear combination of one or more of the other equations.
In this scenario, one possibly useful thing to do is to find the x
that minimizes norm(b - Ax)^2
(i.e. linear least squares solution):
x, _, _, _ = np.linalg.lsq(A, b)
Upvotes: 5