What does the error Numpy error: Matrix is singular mean specifically (when using the linalg.solve function)? I have looked on Google but couldn’t find anything that made it clear when this error occurs.
strpeter
2,4323 gold badges24 silver badges46 bronze badges
asked Dec 10, 2012 at 5:47
1
A singular matrix is one that is not invertible. This means that the system of equations you are trying to solve does not have a unique solution; linalg.solve can’t handle this.
You may find that linalg.lstsq provides a usable solution.
answered Dec 10, 2012 at 6:09
6
This function inverts singular matrices as well using numpy.linalg.lstsq:
def inv(m):
a, b = m.shape
if a != b:
raise ValueError("Only square matrices are invertible.")
i = np.eye(a, a)
return np.linalg.lstsq(m, i)[0]
answered May 17, 2017 at 14:02
![]()
ProcopeProcope
911 silver badge7 bronze badges
17 авг. 2022 г.
читать 1 мин
Одна ошибка, с которой вы можете столкнуться в Python:
numpy.linalg.LinAlgError: Singular matrix
Эта ошибка возникает, когда вы пытаетесь инвертировать сингулярную матрицу, которая по определению является матрицей с нулевым определителем и не может быть инвертирована.
В этом руководстве рассказывается, как устранить эту ошибку на практике.
Как воспроизвести ошибку
Предположим, мы создаем следующую матрицу с помощью NumPy:
import numpy as np
#create 2x2 matrix
my_matrix = np.array([[1., 1.], [1., 1.]])
#display matrix
print(my_matrix)
[[1. 1.]
[1. 1.]]
Теперь предположим, что мы пытаемся использовать функцию inv() из NumPy для вычисления обратной матрицы:
from numpy import inv
#attempt to invert matrix
inv(my_matrix)
numpy.linalg.LinAlgError: Singular matrix
Мы получаем ошибку, потому что созданная нами матрица не имеет обратной матрицы.
Примечание.Ознакомьтесь с этой страницей Wolfram MathWorld, на которой показаны 10 различных примеров матриц, не имеющих обратной матрицы.
По определению матрица сингулярна и не может быть обращена, если ее определитель равен нулю.
Вы можете использовать функцию det() из NumPy для вычисления определителя данной матрицы, прежде чем пытаться ее инвертировать:
from numpy import det
#calculate determinant of matrix
det(my_matrix)
0.0
Определитель нашей матрицы равен нулю, что объясняет, почему мы сталкиваемся с ошибкой.
Как исправить ошибку
Единственный способ обойти эту ошибку — просто создать невырожденную матрицу.
Например, предположим, что мы используем функцию inv() для инвертирования следующей матрицы:
import numpy as np
from numpy. linalg import inv, det
#create 2x2 matrix that is not singular
my_matrix = np.array([[1., 7.], [4., 2.]])
#display matrix
print(my_matrix)
[[1. 7.]
[4. 2.]]
#calculate determinant of matrix
print(det(my_matrix))
-25.9999999993
#calculate inverse of matrix
print(inv(my_matrix))
[[-0.07692308 0.26923077]
[ 0.15384615 -0.03846154]]
Мы не получаем никакой ошибки при инвертировании матрицы, потому что матрица не является единственной.
Дополнительные ресурсы
В следующих руководствах объясняется, как исправить другие распространенные ошибки в Python:
Как исправить: объект numpy.float64 не вызывается
Как исправить: объект ‘numpy.ndarray’ не вызывается
Как исправить: объект numpy.float64 не может быть интерпретирован как целое число
Hi, this is a (simplified) case I encountered while working on seaborn.pairplot.
data: data.1000.txt
singular.py:
import pandas import seaborn data = pandas.read_table("data.1000.txt", index_col="cell") seaborn.pairplot(data.drop(columns="cluster").iloc[:,0:6], hue="batch")
commands:
~/w/experiments $ python3 --version
Python 3.6.6
~/w/experiments $ pip3 show seaborn
Name: seaborn
Version: 0.9.0
Summary: seaborn: statistical data visualization
Home-page: https://seaborn.pydata.org
Author: Michael Waskom
Author-email: mwaskom@nyu.edu
License: BSD (3-clause)
Location: /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages
Requires: numpy, scipy, pandas, matplotlib
Required-by:
~/w/experiments $ python3 singular.py
Traceback (most recent call last):
File "singular.py", line 4, in <module>
seaborn.pairplot(data.drop(columns="cluster").iloc[:,0:6], hue="batch")
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/seaborn/axisgrid.py", line 2111, in pairplot
grid.map_diag(kdeplot, **diag_kws)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/seaborn/axisgrid.py", line 1399, in map_diag
func(data_k, label=label_k, color=color, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/seaborn/distributions.py", line 691, in kdeplot
cumulative=cumulative, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/seaborn/distributions.py", line 294, in _univariate_kdeplot
x, y = _scipy_univariate_kde(data, bw, gridsize, cut, clip)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/seaborn/distributions.py", line 366, in _scipy_univariate_kde
kde = stats.gaussian_kde(data, bw_method=bw)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/scipy/stats/kde.py", line 172, in __init__
self.set_bandwidth(bw_method=bw_method)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/scipy/stats/kde.py", line 499, in set_bandwidth
self._compute_covariance()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/scipy/stats/kde.py", line 510, in _compute_covariance
self._data_inv_cov = linalg.inv(self._data_covariance)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/scipy/linalg/basic.py", line 975, in inv
raise LinAlgError("singular matrix")
numpy.linalg.linalg.LinAlgError: singular matrix
Я пытаюсь запустить grangercausalitytests в двух временных рядах:
import numpy as np
import pandas as pd
from statsmodels.tsa.stattools import grangercausalitytests
n = 1000
ls = np.linspace(0, 2*np.pi, n)
df1 = pd.DataFrame(np.sin(ls))
df2 = pd.DataFrame(2*np.sin(1+ls))
df = pd.concat([df1, df2], axis=1)
df.plot()
grangercausalitytests(df, maxlag=20)
Однако я получаю
Granger Causality
number of lags (no zero) 1
ssr based F test: F=272078066917221398041264652288.0000, p=0.0000 , df_denom=996, df_num=1
ssr based chi2 test: chi2=272897579166972095424217743360.0000, p=0.0000 , df=1
likelihood ratio test: chi2=60811.2671, p=0.0000 , df=1
parameter F test: F=272078066917220553616334520320.0000, p=0.0000 , df_denom=996, df_num=1
Granger Causality
number of lags (no zero) 2
ssr based F test: F=7296.6976, p=0.0000 , df_denom=995, df_num=2
ssr based chi2 test: chi2=14637.3954, p=0.0000 , df=2
likelihood ratio test: chi2=2746.0362, p=0.0000 , df=2
parameter F test: F=13296850090491009488285469769728.0000, p=0.0000 , df_denom=995, df_num=2
...
/usr/local/lib/python3.5/dist-packages/numpy/linalg/linalg.py in _raise_linalgerror_singular(err, flag)
88
89 def _raise_linalgerror_singular(err, flag):
---> 90 raise LinAlgError("Singular matrix")
91
92 def _raise_linalgerror_nonposdef(err, flag):
LinAlgError: Singular matrix
И я не уверен, почему это так.
2 ответа
Лучший ответ
Проблема возникает из-за идеальной корреляции между двумя рядами ваших данных. Из трассировки вы можете видеть, что внутренний тест Уолда используется для вычисления оценок максимального правдоподобия для параметров временного ряда с запаздыванием. Для этого необходима оценка ковариационной матрицы параметров (которая тогда близка к нулю) и ее обратная (как вы также можете видеть в строке invcov = np.linalg.inv(cov_p) в трассировке). Эта почти нулевая матрица теперь является сингулярной для некоторого максимального числа запаздывания (> = 5), и, таким образом, тест вылетает. Если вы добавите немного шума к своим данным, ошибка исчезнет:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import grangercausalitytests
n = 1000
ls = np.linspace(0, 2*np.pi, n)
df1Clean = pd.DataFrame(np.sin(ls))
df2Clean = pd.DataFrame(2*np.sin(ls+1))
dfClean = pd.concat([df1Clean, df2Clean], axis=1)
dfDirty = dfClean+0.00001*np.random.rand(n, 2)
grangercausalitytests(dfClean, maxlag=20, verbose=False) # Raises LinAlgError
grangercausalitytests(dfDirty, maxlag=20, verbose=False) # Runs fine
22
jotasi
1 Июн 2017 в 13:46
Еще одна вещь, за которой нужно следить, это дубликаты столбцов. Повторяющиеся столбцы будут иметь коэффициент корреляции 1,0, что приведет к сингулярности. В противном случае также возможно, что у вас есть 2 функции, которые идеально взаимосвязаны. И простой способ проверить это с помощью df.corr() и найти пары столбцов с корреляцией = 1,0.
1
user12081571
17 Сен 2019 в 19:38
