Матрица должна быть положительно определенной (библиотека Math.Net C#)

Я столкнулся со странной проблемой с библиотекой Math.Net Numerics для C#. Мой код работал отлично до недавнего времени (насколько я могу судить, ничего не изменилось), но теперь я получаю сообщение об ошибке из заголовка в строке, где он пытается вычислить множественную регрессию.

Каждый список содержит 493 двойных значения. Кто-нибудь знает, что я могу сделать, чтобы решить эти проблемы?

Vector<double> vectorArrayBuy = CreateVector.Dense(listMRInfoBuy.ElementAt(0).OutputBuy.ToArray());

var matrixArrayBuy = CreateMatrix.DenseOfColumnArrays(listMRInfoBuy.ElementAt(0).ListValuesBuy.ToArray(), listMRInfoBuy.ElementAt(1).ListValuesBuy.ToArray(), listMRInfoBuy.ElementAt(2).ListValuesBuy.ToArray(),
                                listMRInfoBuy.ElementAt(3).ListValuesBuy.ToArray(), listMRInfoBuy.ElementAt(4).ListValuesBuy.ToArray(), listMRInfoBuy.ElementAt(5).ListValuesBuy.ToArray(), listMRInfoBuy.ElementAt(6).ListValuesBuy.ToArray(),
                                listMRInfoBuy.ElementAt(7).ListValuesBuy.ToArray(), listMRInfoBuy.ElementAt(8).ListValuesBuy.ToArray(), listMRInfoBuy.ElementAt(9).ListValuesBuy.ToArray(), listMRInfoBuy.ElementAt(10).ListValuesBuy.ToArray(),
                                listMRInfoBuy.ElementAt(11).ListValuesBuy.ToArray());

var itemsBuy = MultipleRegression.NormalEquations(matrixArrayBuy, vectorArrayBuy);

2 ответа

Решение

Я исправил эту проблему, переключив на лету различные уравнения, чтобы увидеть, какое из них вернуло правильные ответы и не выбросило это исключение. Вот мое решение этой проблемы, которое, я надеюсь, поможет кому-то еще.

public Vector<double> CalculateWithQR(Matrix<double> x, Vector<double> y)
    {
        Vector<double> result = null;

        try
        {
            result = MultipleRegression.QR(x, y);

            // check for NaN and infinity
            for (int i = 0; i < result.Count; i++)
            {
                var value = result.ElementAt(i);

                if (Double.IsNaN(value) || Double.IsInfinity(value))
                {
                    return null;
                }
            }
        }
        catch (Exception ex)
        {
        }

        return result;
    }

    public Vector<double> CalculateWithNormal(Matrix<double> x, Vector<double> y)
    {
        Vector<double> result = null;

        try
        {
            result = MultipleRegression.NormalEquations(x, y);

            // check for NaN and infinity
            for (int i = 0; i < result.Count; i++)
            {
                var value = result.ElementAt(i);

                if (Double.IsNaN(value) || Double.IsInfinity(value))
                {
                    return null;
                }
            }
        }
        catch (Exception ex)
        {
        }

        return result;
    }

    public Vector<double> CalculateWithSVD(Matrix<double> x, Vector<double> y)
    {
        Vector<double> result = null;

        try
        {
            result = MultipleRegression.Svd(x, y);

            // check for NaN and infinity
            for (int i = 0; i < result.Count; i++)
            {
                var value = result.ElementAt(i);

                if (Double.IsNaN(value) || Double.IsInfinity(value))
                {
                    return null;
                }
            }
        }
        catch (Exception ex)
        {
        }

        return result;
    }

    public Vector<double> FindBestMRSolution(Matrix<double> x, Vector<double> y)
    {
        Vector<double> result = null;

        try
        {
            result = CalculateWithNormal(x, y);

            if (result != null)
            {
                return result;
            }
            else
            {
                result = CalculateWithSVD(x, y);

                if (result != null)
                {
                    return result;
                }
                else
                {
                    result = CalculateWithQR(x, y);

                    if (result != null)
                    {
                        return result;
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }

        return result;
    }

"Матрица не является положительно определенной", вероятно, означает, что у вас меньше n независимых уравнений, что, в свою очередь, означает, что у вас нет n независимых данных, что, вероятно, означает, что ваши данные в некотором роде являются дефектными (например, они были прочитаны неверно, и они на самом деле все то же самое или что-то в этом роде).

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

Просто добавляю решение для тех (вроде меня), кто не помнит линейную алгебру или продвинутую статистику из школьных лет.

  1. Если вы еще этого не сделали, примените надстройку "Analysis ToolPak" в Excel.
  2. Вставьте свои независимые и зависимые переменные в рабочий лист
  3. Перейдите в Данные -> Анализ данных -> Регрессия.
  4. Укажите запрашиваемые диапазоны и запустите регрессию.
  5. В результатах регрессии вы обнаружите, что одно или несколько p-значений или t-stats возвращают ошибку div/0 или NUM.
  6. Удалите эти независимые переменные из вашего вызова регрессии MathNet и запустите снова.

Это должно исправить это.

Затем я добавил итеративную попытку и поймать, которая удаляла бы независимые переменные в зависимости от конкретных обстоятельств и запускала ее снова.

IHTH

Другие вопросы по тегам