我使用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。


当前回答

在我的例子中,算法要求数据在(0,1)之间不包含。我非常残酷的解决方案是在所有期望值中添加一个小随机数:

y_train = pd.DataFrame(y_train).applymap(lambda x: x + np.random.rand()/100000.0)["col_name"]
y_train[y_train >= 1] = 0.999999

而y_train在[0,1]的范围内。

这当然不适合所有的情况,因为你会弄乱你的输入数据,但如果你有稀疏的数据,只需要一个快速的预测,这是一个解决方案

其他回答

当我使用sklearn与熊猫时,我得到了同样的错误消息。我的解决方案是在运行任何sklearn代码之前重置我的dataframe df的索引:

df = df.reset_index()

在删除df中的一些条目时,我多次遇到这个问题,例如

df = df[df.label=='desired_one']

try

mat.sum()

如果你的数据和是无穷大(大于最大浮点值3.402823e+38),你会得到这个错误。

请参阅scikit源代码中的validation.py中的_assert_all_finite函数:

if is_float and np.isfinite(X.sum()):
    pass
elif is_float:
    msg_err = "Input contains {} or a value too large for {!r}."
    if (allow_nan and np.isinf(X).any() or
            not allow_nan and not np.isfinite(X).all()):
        type_err = 'infinity' if allow_nan else 'NaN, infinity'
        # print(X.sum())
        raise ValueError(msg_err.format(type_err, X.dtype))

我发现在一个新列上调用pct_change后,nan存在于一行中。我用下面的代码删除nan行

df = df.replace([np.inf, -np.inf], np.nan)
df = df.dropna()
df = df.reset_index()

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

这可能发生在scikit内部,这取决于您正在做什么。我建议阅读您正在使用的函数的文档。你可能会使用一个,例如,你的矩阵是正定的,不满足那个条件。

编辑:我怎么能错过呢?

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

显然是错误的。正确的是:

np.any(np.isnan(mat))

and

np.all(np.isfinite(mat))

您想要检查是否有任何元素是NaN,而不是任何函数的返回值是否为数字…