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.

sejenis kacang-kacangan dari Jepang
sumber

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.
fernando
sumber
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())
kmandov
sumber
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
Nama Umum
sumber
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]
bmc
sumber
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']
Kohn1001
sumber
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())
Prakash Vanapalli
sumber
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)
Natheer Alabsi
sumber
1

Jika nilai Anda lebih besar dari float32, coba jalankan scaler terlebih dahulu. Itu akan agak tidak biasa untuk memiliki penyimpangan yang mencakup lebih dari float32.

Piotr Rarus - Pasang kembali Monica
sumber
0

Berikut adalah kode untuk cara "Ganti NaN dengan nol dan tak terbatas dengan angka hingga yang besar." menggunakan numpy.nan_to_num .

df[:] = np.nan_to_num(df)

Lihat juga jawaban fernando .

Domi W
sumber