ValueError: a entrada contém NaN, infinito ou um valor muito grande para dtype ('float32')


41

Eu obtive o ValueError ao prever dados de teste usando um modelo RandomForest.

Meu código:

clf = RandomForestClassifier(n_estimators=10, max_depth=6, n_jobs=1, verbose=2)
clf.fit(X_fit, y_fit)

df_test.fillna(df_test.mean())
X_test = df_test.values  
y_pred = clf.predict(X_test)

O erro:

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

Como encontro os valores incorretos no conjunto de dados de teste? Além disso, não quero descartar esses registros. Posso apenas substituí-los pela média ou mediana?

Obrigado.

Respostas:


45

Com np.isnan(X)você começa uma volta máscara booleano com True para posições contendo NaNs.

Com np.where(np.isnan(X))você, você volta uma tupla com i, j coordenadas de NaNs.

Finalmente, com np.nan_to_num(X)você "substitua nan por zero e inf por números finitos".

Como alternativa, você pode usar:

  • sklearn.impute.SimpleImputer para imputação média / mediana de valores ausentes ou
  • pandas ' pd.DataFrame(X).fillna(), se você precisar de algo diferente de preenchê-lo com zeros.

Eu prefiro condição de identidade para verificar nan, se x = x retorno Nenhum, muitas vezes np.isnan (x) não tinha conseguido para mim, não me lembro o motivo!
— Itachi

11
Não é aconselhável substituir os valores de NaN por zeros. Os valores de NaN ainda podem ter significado em estar faltando e imputá-los com zeros é provavelmente a pior coisa que você pode fazer e o pior método de imputação usado. Você não apenas introduzirá zeros arbitrariamente, o que pode distorcer sua variável, mas 0 pode até não ser um valor aceitável em suas variáveis, o que significa que sua variável pode não ter um zero verdadeiro.
— hussam

Percebi que não forneci nenhuma orientação. Se você deseja imputar seus dados, use uma média móvel usando .rolling()para substituir o valor ausente pelo valor médio de uma janela contínua. Se você quiser algo mais robusto, use o módulo <b> missingpy </b>, MissForestpara uma imputação baseada em floresta aleatória.
— hussam

7

Supondo que X_testseja um dataframe de pandas, você pode usar DataFrame.fillnapara substituir os valores de NaN pela média:

X_test.fillna(X_test.mean())

X_test é a matriz numpy. Acaba de atualizar o df_test na pergunta original, ainda tenho o mesmo erro ...
— Edamame

6

Para alguém que esteja passando por isso, para modificar o original:

X_test.fillna(X_train.mean(), inplace=True)

Para substituir o original:

X_test = X_test.fillna(X_train.mean())

Para verificar se você está em uma cópia versus uma visualização:

X_test._is_view

2
Embora isso seja verdade tecnicamente, está errado na prática. Você não pode preencher os X_test NAs com a média X_test, porque na vida real você não terá a média X_test quando estiver prevendo uma amostra. Você deve usar a média X_train porque este é os únicos dados que você realmente tem na mão (em 99% dos cenários)
— Omri374

4

Não esqueça

col_mask=df.isnull().any(axis=0) 

O que retorna uma máscara booleana indicando valores np.nan.

row_mask=df.isnull().any(axis=1)

Que retornam as linhas em que np.nan apareceu. Então, através da indexação simples, você pode sinalizar todos os seus pontos que são np.nan.

df.loc[row_mask,col_mask]

2

Eu enfrentei um problema semelhante e vi que o numpy lida com NaN e Inf de maneira diferente.
No caso de seus dados terem Inf, tente o seguinte:

np.where(x.values >= np.finfo(np.float64).max)
Where x is my pandas Dataframe 

Isso fornecerá uma tupla de localização dos locais onde os valores de NA estão presentes.

No caso de seus dados terem Nan, tente o seguinte:

np.isnan(x.values.any())

2

Não se esqueça de verificar também os valores inf. A única coisa que funcionou para mim:

df[df==np.inf]=np.nan
df.fillna(df.mean(), inplace=True)

E melhor ainda, se você estiver usando o sklearn

def replace_missing_value(df, number_features):

    imputer = Imputer(strategy="median")
    df_num = df[number_features]
    imputer.fit(df_num)
    X = imputer.transform(df_num)
    res_def = pd.DataFrame(X, columns=df_num.columns)
    return res_def

Quando number_features seria uma matriz dos rótulos number_features, por exemplo:

number_features = ['median_income', 'gdp']

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.