【问题标题】:LinAlgError: SVD did not converge in Linear Least Squares when trying polyfitLinAlgError:尝试 polyfit 时 SVD 未收敛于线性最小二乘
【发布时间】:2016-06-05 12:46:32
【问题描述】:

如果我尝试运行下面的脚本,我会收到错误:LinAlgError: SVD did not converge in Linear Least Squares。我在类似的数据集上使用了完全相同的脚本,并且可以正常工作。我试图在我的数据集中搜索 Python 可能解释为 NaN 的值,但我找不到任何东西。

我的数据集非常大,无法手动检查。 (但我认为我的数据集很好)。我还检查了stageheight_maskeddischarge_masked 的长度,但它们是相同的。有谁知道为什么我的脚本有错误,我该怎么办?

import numpy as np
import datetime
import matplotlib.dates
import matplotlib.pyplot as plt
from scipy import polyfit, polyval

kwargs = dict(delimiter = '\t',\
     skip_header = 0,\
     missing_values = 'NaN',\
     converters = {0:matplotlib.dates.strpdate2num('%d-%m-%Y %H:%M')},\
     dtype = float,\
     names = True,\
     )

rating_curve_Gillisstraat = np.genfromtxt('G:\Discharge_and_stageheight_Gillisstraat.txt',**kwargs)

discharge = rating_curve_Gillisstraat['discharge']   #change names of collumns
stageheight = rating_curve_Gillisstraat['stage'] - 131.258

#mask NaN
discharge_masked = np.ma.masked_array(discharge,mask=np.isnan(discharge)).compressed()
stageheight_masked = np.ma.masked_array(stageheight,mask=np.isnan(discharge)).compressed()

#sort
sort_ind = np.argsort(stageheight_masked)
stageheight_masked = stageheight_masked[sort_ind]
discharge_masked = discharge_masked[sort_ind]

#regression
a1,b1,c1 = polyfit(stageheight_masked, discharge_masked, 2)
discharge_predicted = polyval([a1,b1,c1],stageheight_masked)

print 'regression coefficients'
print (a1,b1,c1)

#create upper and lower uncertainty
upper = discharge_predicted*1.15
lower = discharge_predicted*0.85

#create scatterplot

plt.scatter(stageheight,discharge,color='b',label='Rating curve')
plt.plot(stageheight_masked,discharge_predicted,'r-',label='regression line')
plt.plot(stageheight_masked,upper,'r--',label='15% error')
plt.plot(stageheight_masked,lower,'r--')
plt.axhline(y=1.6,xmin=0,xmax=1,color='black',label='measuring range')
plt.title('Rating curve Catsop')
plt.ylabel('discharge')
plt.ylim(0,2)
plt.xlabel('stageheight[m]')
plt.legend(loc='upper left', title='Legend')
plt.grid(True)
plt.show()

【问题讨论】:

  • 我很确定 polyfit 不支持掩码数组,因此它会将 NaN 视为任何其他值。您还需要检查无限值(例如使用np.isinf)。

标签: python scipy regression


【解决方案1】:

我没有您的数据文件,但几乎总是这样,当您收到该错误时,您的数据中有 NaN 或无穷大。查找使用 pd.notnull 或 np.isfinite 的两个

【讨论】:

    【解决方案2】:

    由于ski_squaw 提到该错误大部分时间是由于NaN,但是对我而言,此错误是在Windows 更新之后出现的。我使用的是 numpy 1.16 版。将我的 numpy 版本移动到 1.19.3 解决了这个问题。 (在cmd中运行pip install numpy==1.19.3 --user

    这个 gitHub 问题更详细地解释了它: https://github.com/numpy/numpy/issues/16744

    Numpy 1.19.3 不能在 Linux 上运行,1.19.4 不能在 Windows 上运行。

    【讨论】:

      【解决方案3】:

      正如其他人指出的那样,问题很可能是存在没有数字的行供算法使用。这是大多数回归的问题。

      这就是问题所在。那么解决方案就是为此做点什么。这取决于数据。通常,您可以将 NaN 替换为 0,例如使用 Pandas .fillna(0)。有时,您可能需要插入缺失值,而 Pandas .interpolate() 可能也是最简单的解决方案。或者,当它不是时间序列时,您可以简单地删除其中包含 NaN 的行,例如使用 Pandas .dropna() 方法。或者,有时不是关于 NaN,而是关于 infs 或其他,然后还有其他解决方案:https://stackoverflow.com/a/55293137/12213843

      具体采用哪种方式,取决于数据。由您来解释数据。领域知识对于很好地解释数据大有帮助。

      【讨论】:

        【解决方案4】:

        我在 Windows 8 上开发了一个代码。 所以现在我使用的是Windows 10,问题就出现了! 正如@Joris 所说,它已解决。

        pip install numpy==1.19.3

        【讨论】:

        • 虽然这是对该问题的有效答案,但至少在您的用例中,它不会添加@Joris 的答案中尚不存在的新信息。最好不要发布这样的重复答案。
        【解决方案5】:

        修复后的示例:

        def calculating_slope(x):
                x = x.replace(np.inf, np.nan).replace(-np.inf, np.nan).dropna()
                if len(x)>1:
                    slope = np.polyfit(range(len(x)), x, 1)[0]
                else: 
                    slope = 0
                return slope
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-27
          相关资源
          最近更新 更多