python - scikit - error sklearn ValueError: la entrada contiene NaN, infinito o un valor demasiado grande para dtype(''float64'')
scikit learn 0.19 0 (11)
Estoy usando sklearn y tengo un problema con la propagación de afinidad. He creado una matriz de entrada y sigo recibiendo el siguiente error.
ValueError: Input contains NaN, infinity or a value too large for dtype(''float64'').
he corrido
np.isnan(mat.any()) #and gets False
np.isfinite(mat.all()) #and gets True
Traté de usar
mat[np.isfinite(mat) == True] = 0
para eliminar los valores infinitos pero esto tampoco funcionó. ¿Qué puedo hacer para deshacerme de los valores infinitos en mi matriz, para poder usar el algoritmo de propagación de afinidad?
Estoy usando anaconda y python 2.7.9.
Con esta versión de Python 3:
/opt/anaconda3/bin/python --version
Python 3.6.0 :: Anaconda 4.3.0 (64-bit)
Mirando los detalles del error, encontré las líneas de códigos que causan la falla:
/opt/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py in _assert_all_finite(X)
56 and not np.isfinite(X).all()):
57 raise ValueError("Input contains NaN, infinity"
---> 58 " or a value too large for %r." % X.dtype)
59
60
ValueError: Input contains NaN, infinity or a value too large for dtype(''float64'').
A partir de esto, pude extraer la forma correcta de probar lo que estaba sucediendo con mis datos utilizando la misma prueba que falla dada por el mensaje de error:
np.isfinite(X)
Luego, con un bucle rápido y sucio, pude encontrar que mis datos realmente contienen
nans
:
print(p[:,0].shape)
index = 0
for i in p[:,0]:
if not np.isfinite(i):
print(index, i)
index +=1
(367340,)
4454 nan
6940 nan
10868 nan
12753 nan
14855 nan
15678 nan
24954 nan
30251 nan
31108 nan
51455 nan
59055 nan
...
Ahora todo lo que tengo que hacer es eliminar los valores en estos índices.
En mi caso, el problema era que muchas funciones scikit devuelven matrices numpy, que carecen de índice de pandas. Así que hubo una falta de coincidencia de índice cuando utilicé esos arreglos numpy para construir nuevos marcos de datos y luego intenté mezclarlos con los datos originales.
Esta es la comprobación en la que falla:
Que dice
def _assert_all_finite(X):
"""Like assert_all_finite, but only for ndarray."""
X = np.asanyarray(X)
# First try an O(n) time, O(1) space solution for the common case that
# everything is finite; fall back to O(n) space np.isfinite to prevent
# false positives from overflow in sum method.
if (X.dtype.char in np.typecodes[''AllFloat''] and not np.isfinite(X.sum())
and not np.isfinite(X).all()):
raise ValueError("Input contains NaN, infinity"
" or a value too large for %r." % X.dtype)
Así que asegúrese de tener valores que no sean NaN en su entrada. Y todos esos valores son en realidad valores flotantes. Ninguno de los valores debe ser Inf tampoco.
Esta es mi función (basada en
this
) para limpiar el conjunto de datos de
nan
,
Inf
y celdas faltantes (para conjuntos de datos asimétricos):
import pandas as pd
def clean_dataset(df):
assert isinstance(df, pd.DataFrame), "df needs to be a pd.DataFrame"
df.dropna(inplace=True)
indices_to_keep = ~df.isin([np.nan, np.inf, -np.inf]).any(1)
return df[indices_to_keep].astype(np.float64)
Esto puede suceder dentro de scikit, y depende de lo que estés haciendo. Recomiendo leer la documentación de las funciones que está utilizando. Puede estar usando uno que depende, por ejemplo, de que su matriz sea positiva definida y no cumpla con ese criterio.
EDITAR : ¿Cómo podría extrañar eso?
np.isnan(mat.any()) #and gets False
np.isfinite(mat.all()) #and gets True
Obviamente está mal. Derecho sería:
np.any(np.isnan(mat))
y
np.all(np.isfinite(mat))
Desea verificar si alguno de los elementos es NaN, y no si el valor de retorno de
any
función es un número ...
Las dimensiones de mi matriz de entrada estaban sesgadas, ya que mi csv de entrada tenía espacios vacíos.
Recibí el mismo mensaje de error cuando uso
sklearn
con
pandas
.
Mi solución es restablecer el índice de mi dataframe
df
antes de ejecutar cualquier código sklearn:
df = df.reset_index()
Encontré este problema muchas veces cuando eliminé algunas entradas en mi
df
, como
df = df[df.label==''desired_one'']
Tengo el mismo error.
funcionó con
df.fillna(-99999, inplace=True)
antes de hacer cualquier reemplazo, sustitución, etc.
Tuve el error después de intentar seleccionar un subconjunto de filas:
df = df.reindex(index=my_index)
Resulta que
my_index
contenía valores que no estaban contenidos en
df.index
, por lo que la función reindex insertó algunas filas nuevas y las llenó con
nan
.
Tuve el mismo error, y en mi caso X e y eran marcos de datos, así que primero tuve que convertirlos en matrices:
X = X.as_matrix().astype(np.float)
y = y.as_matrix().astype(np.float)
tratar
mat.sum()
Si la suma de sus datos es infinita (mayor que el valor flotante máximo que es 3.402823e + 38) obtendrá ese error.
vea la función _assert_all_finite en validation.py del código fuente scikit:
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))