矩阵必须是正定的(Math.Net C# 库)

Matrix must be positive definite (Math.Net C# library)

我在使用 C# 的 Math.Net 数值库时遇到了一个奇怪的问题。直到最近我的代码都运行良好(据我所知没有任何变化)但我现在从标题中尝试计算多元回归的行中收到错误消息。

每个列表有 493 个 double 值所以有人知道我可以做些什么来解决这些问题吗?

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);

"Matrix not positive definite" 可能意味着你有少于 n 个独立方程,这反过来意味着你没有 n 个独立数据,这可能意味着你的数据在某些方面有缺陷(例如,它们被读入不正确,它们实际上完全相同或类似)。

也许您可以编辑您的问题以显示您正在处理的数据是什么。可能您的起始数据少于 n 个。

我解决了这个问题,方法是即时切换不同的方程式,看看哪个方程式返回了正确的答案并且没有抛出这个异常。这是我对这个问题的解决方案,希望能帮助其他人。

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;
    }

只是为那些不记得线性代数或学生时代的高级统计数据的人(像我)添加一个解决方案。

  1. 如果您还没有,请在 Excel
  2. 中应用 "Analysis ToolPak" 插件
  3. 将自变量和因变量粘贴到工作表中
  4. 转到数据 -> 数据分析 -> 回归
  5. 提供它要求的范围和运行回归
  6. 在回归结果中,您会发现一个或多个 p 值或 t 统计量 return 出现 div/0 或 NUM 错误。
  7. 从您对 MathNet 回归的调用中删除那些自变量,然后再次 运行。

这应该可以解决问题。

然后我继续添加一个迭代 try 和 catch,它会根据具体情况删除自变量,然后再次 运行 它。

IHTH