我使用sklearn和有一个问题的亲和传播。我已经建立了一个输入矩阵,我一直得到以下错误。

ValueError: Input contains NaN, infinity or a value too large for dtype('float64').

我已经跑了

np.isnan(mat.any()) #and gets False
np.isfinite(mat.all()) #and gets True

我试着用

mat[np.isfinite(mat) == True] = 0

去除掉无限值,但这也没用。 我要怎么做才能去掉矩阵中的无穷大值,这样我就可以使用亲和传播算法了?

我使用anaconda和python 2.7.9。


当前回答

如果您正在运行一个估计器,可能是您的学习率太高了。我意外地将错误的数组传递给了网格搜索,最终训练的学习率为500,我可以看到这导致了训练过程中的问题。

基本上,不仅你的输入必须全部有效,中间数据也必须有效。

其他回答

在大多数情况下,消除无限和空值可以解决这个问题。

去掉无穷值。

df.replace([np.inf, -np.inf], np.nan, inplace=True)

以您喜欢的方式摆脱空值,特定的值,如999,平均值,或创建自己的函数来输入缺失的值

df.fillna(999, inplace=True)

泡芙! !在我的情况下,问题是关于NaN值…

您可以使用此函数列出具有NaN的列

your_data.isnull().sum()

然后你可以在数据集文件中填充这些NAN值。

下面是如何“将NaN替换为零,将无穷大替换为大的有限数”的代码。

your_data[:] = np.nan_to_num(your_data)

从numpy.nan_to_num

我得到了同样的错误。它适用于df。fillna(-99999, inplace=True),然后再做任何替换,替换等

在处理这个问题很长一段时间后,我意识到这是因为在训练集和测试集的分割中,所有数据行的数据列都是相同的。然后在某些算法中进行一些计算可能会导致无穷大的结果。如果您正在使用的数据的关闭行更可能是相似的,那么重新排列数据会有所帮助。这是scikit的一个漏洞。我使用的是0.23.2版本。

注意:此解决方案仅适用于有意在数据集中保留NaN条目的情况。

这个错误发生在我使用一些scikit-learn功能时(在我的情况下:GridSearchCV)。在底层,我使用了一个xgboost XGBClassifier,它可以优雅地处理NaN数据。然而,GridSearchCV使用sklearn.utils.validation模块,通过调用_assert_all_finite函数强制缺少输入数据中的缺失数据。这最终导致了一个错误:

ValueError: Input contains NaN, infinity or a value too large for dtype('float64')

旁注:_assert_all_finite接受allow_nan参数,如果设置为True,则不会引起问题。但是,scikit-learn API不允许我们控制这个参数。

解决方案

我的解决方案是使用patch模块静默_assert_all_finite函数,这样它就不会引发ValueError。下面是一个片段

import sklearn
with mock.patch("sklearn.utils.validation._assert_all_finite"):
    # your code that raises ValueError

这将用一个虚拟模拟函数替换_assert_all_finite,因此它不会被执行。

请注意,补丁不是一个推荐的做法,可能会导致不可预知的行为!


编辑: 这个Pull Request应该可以解决这个问题(尽管截至2022年1月修复程序还没有发布)