ValueError: Input berisi NaN, infinity atau nilai yang terlalu besar untuk dtype ('float32')


42

Saya mendapat ValueError saat memprediksi data uji menggunakan model RandomForest.

Kode saya:

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)

Kesalahan:

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

Bagaimana cara menemukan nilai buruk dalam dataset uji? Juga, saya tidak ingin menghapus catatan ini, dapatkah saya menggantinya dengan nilai tengah atau median?

Terima kasih.

Jawaban:


45

Dengan np.isnan(X)Anda mendapatkan topeng boolean kembali dengan True untuk posisi yang mengandung NaNs.

Dengan np.where(np.isnan(X))Anda mendapatkan kembali tuple dengan i, j koordinat NaNs.

Akhirnya, dengan np.nan_to_num(X)Anda "ganti nan dengan nol dan inf dengan angka yang terbatas".

Atau, Anda dapat menggunakan:

  • sklearn.impute.SimpleImputer untuk imputasi rata-rata / median dari nilai yang hilang, atau
  • panda ' pd.DataFrame(X).fillna(), jika Anda membutuhkan sesuatu selain mengisinya dengan nol.

Saya lebih suka kondisi identitas untuk memeriksa nan, jika x! = X kembali Tidak ada, berkali-kali np.isnan (x) gagal untuk saya, tidak ingat alasannya
Itachi

1
Tidak disarankan untuk mengganti nilai NaN dengan nol. Nilai NaN mungkin masih memiliki signifikansi dalam hilang dan menusuk mereka dengan nol mungkin adalah hal terburuk yang dapat Anda lakukan dan metode imputasi terburuk yang Anda gunakan. Anda tidak hanya akan memperkenalkan nol secara sewenang-wenang yang mungkin memengaruhi variabel Anda, tetapi 0 bahkan mungkin bukan nilai yang dapat diterima dalam variabel Anda, artinya variabel Anda mungkin tidak memiliki nol yang benar.
Hussam

Saya menyadari bahwa saya tidak memberikan panduan apa pun. Jika Anda ingin menyalahkan data Anda, gunakan rata-rata bergulir menggunakan .rolling()untuk mengganti nilai yang hilang dengan nilai rata-rata dari jendela bergulir. Jika Anda menginginkan sesuatu yang lebih kuat, gunakan modul <b> missingpy </b> yang dapat Anda gunakan MissForestuntuk imputasi berbasis hutan acak.
Hussam

7

Dengan asumsi X_testadalah kerangka data panda, Anda dapat menggunakan DataFrame.fillnauntuk mengganti nilai NaN dengan mean:

X_test.fillna(X_test.mean())

X_test adalah array yang numpy. Baru saja memperbarui df_test di pertanyaan awal, masih mengalami kesalahan yang sama ...
Edamame

7

Bagi siapa saja yang melakukan hal ini, untuk benar-benar mengubah yang asli:

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

Untuk menimpa yang asli:

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

Untuk memeriksa apakah Anda berada dalam salinan vs tampilan:

X_test._is_view

2
Meskipun ini benar secara teknis, itu salah secara praktis. Anda tidak dapat mengisi As X_test dengan rata-rata X_test, karena dalam kehidupan nyata Anda tidak akan memiliki rata-rata X_test ketika Anda memprediksi sampel. Anda harus menggunakan rata-rata X_train karena ini adalah satu-satunya data yang Anda miliki (dalam 99% skenario)
Omri374

4

Jangan lupa

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

Yang mengembalikan topeng boolean yang menunjukkan nilai np.nan.

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

Yang mengembalikan baris tempat np.nan muncul. Kemudian dengan pengindeksan sederhana Anda dapat menandai semua poin Anda yang np.nan.

df.loc[row_mask,col_mask]

3

Jangan lupa untuk memeriksa nilai inf juga. Satu-satunya hal yang berhasil untuk saya:

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

Dan bahkan lebih baik jika Anda menggunakan 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

Ketika number_features akan menjadi array dari label number_features, misalnya:

number_features = ['median_income', 'gdp']

2

Saya menghadapi masalah serupa dan melihat bahwa numpy menangani NaN dan Inf secara berbeda.
Jika Anda memiliki data Inf, coba ini:

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

Ini akan memberikan tuple lokasi tempat di mana nilai-nilai NA ada.

Jika Anda memiliki data Nan, coba ini:

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

1

Dalam kebanyakan kasus, menyingkirkan nilai tak terbatas dan nol memecahkan masalah ini.

singkirkan nilai yang tak terbatas.

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

singkirkan nilai-nilai nol seperti yang Anda suka, nilai spesifik seperti 999, berarti, atau buat fungsi Anda sendiri untuk menyalahkan nilai yang hilang

df.fillna(999, inplace=True)

atau

df.fillna(df.mean(), inplace=True)


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.