Меню

Singular matrix python ошибка

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's user avatar

strpeter

2,4323 gold badges24 silver badges46 bronze badges

asked Dec 10, 2012 at 5:47

KaliMa's user avatar

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

Michael J. Barber's user avatar

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

Procope's user avatar

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

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Sinamics g130 коды ошибок
  • Sinamics g120 ошибка f7900