Metode untuk mengatasi masalah data yang hilang dalam pembelajaran mesin

15

Hampir semua basis data yang ingin kita prediksi menggunakan algoritma pembelajaran mesin akan menemukan nilai yang hilang untuk beberapa karakteristik.

Ada beberapa pendekatan untuk mengatasi masalah ini, untuk mengecualikan garis yang memiliki nilai yang hilang sampai mereka mengisi dengan nilai rata-rata dari karakteristik.

Saya ingin menggunakan pendekatan yang agak lebih kuat, yang pada dasarnya akan menjalankan regresi (atau metode lain) di mana variabel dependen (Y) akan menjadi masing-masing kolom yang memiliki nilai yang hilang tetapi hanya dengan baris tabel yang berisi semua data, dan prediksi nilai-nilai yang hilang dengan metode ini, lengkapi tabel dengan tabel dan pindah ke 'kolom' berikutnya dengan nilai-nilai yang hilang dan ulangi metode sampai semuanya diisi.

Tapi itu memberi saya beberapa keraguan.

Mengapa ada kolom yang dimulai? Saya percaya bahwa yang memiliki nilai hilang terkecil sampai yang paling banyak

Apakah ada ambang nilai yang hilang yang tidak layak untuk diselesaikan? (misalnya, jika karakteristik ini hanya memiliki 10% dari nilai yang diisi tidak akan lebih menarik untuk mengecualikannya)

Apakah ada jenis implementasi dalam paket tradisional atau metode lain yang kuat untuk hilang?

sn3fru
sumber
3
Istilah seni yang Anda cari adalah "imputasi," yang mana beragam imputasi adalah pilihan modern dan populer. Perhatikan bahwa mengecualikan pengamatan dengan pengamatan yang hilang atau mengganti pengamatan yang hilang dengan rata-rata dapat membuat bias data. Satu tempat untuk memulai adalah Gelman et al, Bayesian Data Analysis Edisi ke-3, "Bab 18: Model untuk Data yang Hilang."
Sycorax berkata Reinstate Monica
Terima kasih atas tipnya, saya akan mencari dengan istilah itu dan melihat cap18. Menghapus garis dapat membuat model bias banyak (jika kesalahan tidak acak, yang sangat mungkin) dan menempatkan rata-rata dapat menempatkan 'beban inersia' yang kuat di sekitar rata-rata, juga tergantung pada eksogenitas data yang hilang. Pertanyaan besar saya adalah pendekatan terbaik untuk menangani hal ini dan saran saya adalah menjalankan pra-regresi untuk menyelesaikan data sebelum regresi utama (apakah ada paket yang melakukan ini atau haruskah saya membuat satu?)
sn3fru
Imputasi berganda modern memperkirakan suatu model untuk data yang hilang dan tidak hilang berdampingan. Bayesian mengambil data yang hilang untuk memperkirakan distribusi atas data yang hilang, tergantung pada data yang diamati dan model untuk hilangnya. Perangkat lunak statistik dalam python meninggalkan banyak hal yang diinginkan. Untuk data TSCS, Amelia IIdi R adalah pilihan yang solid. Atau Anda bisa menggunakan roll Anda sendiri stan.
Sycorax berkata Reinstate Monica

Jawaban:

9

Teknik yang Anda gambarkan disebut imputasi dengan regresi berurutan atau imputasi ganda oleh persamaan dirantai. Teknik ini dipelopori oleh Raghunathan (2001) dan diimplementasikan dalam paket R yang berfungsi baik disebut mice(van Buuren, 2012).

Sebuah makalah oleh Schafer dan Graham (2002) menjelaskan dengan baik mengapa imputasi berarti dan penghapusan listwise (apa yang Anda sebut pengecualian jalur) biasanya bukan alternatif yang baik untuk teknik yang disebutkan di atas. Pada dasarnya rata-rata imputasi tidak bersyarat dan dengan demikian dapat membiaskan distribusi yang diperhitungkan terhadap rata-rata yang diamati. Ini juga akan mengecilkan varians, di antara dampak lain yang tidak diinginkan pada distribusi yang diperhitungkan. Selain itu, penghapusan listwise memang hanya akan berfungsi jika data hilang sepenuhnya secara acak, seperti oleh flip koin. Juga akan meningkatkan kesalahan pengambilan sampel, karena ukuran sampel berkurang.

Para penulis yang dikutip di atas biasanya merekomendasikan dimulai dengan variabel yang menampilkan nilai yang paling sedikit hilang. Juga, teknik ini biasanya diterapkan dengan cara Bayesian (yaitu perpanjangan saran Anda). Variabel dikunjungi lebih sering dalam prosedur imputasi, tidak hanya sekali. Secara khusus, setiap variabel diselesaikan dengan menarik dari distribusi prediktif posterior kondisionalnya, dimulai dengan variabel yang menampilkan nilai yang paling sedikit hilang. Setelah semua variabel dalam set data telah selesai, algoritma kembali dimulai pada variabel pertama dan kemudian mengulangi sampai konvergensi. Para penulis telah menunjukkan bahwa algoritma ini adalah Gibbs, sehingga biasanya konvergen ke distribusi multivariat yang benar dari variabel.

Biasanya, karena ada beberapa asumsi yang tidak dapat diuji yang terlibat, khususnya yang hilang pada data acak (yaitu apakah data diamati atau tidak tergantung pada data yang diamati saja, dan bukan pada nilai yang tidak dilindungi). Juga prosedur dapat sebagian tidak kompatibel, itulah sebabnya mereka disebut PIGS (sebagian Gibbs sampler tidak kompatibel).

Dalam praktiknya, imputasi berganda Bayesian masih merupakan cara yang baik untuk menangani masalah data yang hilang non-monoton multivariat. Juga, ekstensi non-parametrik seperti pencocokan rata-rata prediktif membantu mengendurkan asumsi pemodelan regresi.


Raghunathan, TE, Lepkowski, J., van Hoewyk, J., & Solenberger, P. (2001). Teknik multivariat untuk mengalikan nilai yang hilang dengan menggunakan serangkaian model regresi. Metodologi Survei, 27 (1), 85–95.

Schafer, JL, & Graham, JW (2002). Data tidak ada: Pandangan kami tentang keadaan terkini. Metode Psikologis, 7 (2), 147–177. https://doi.org/10.1037/1082-989X.7.2.147

van Buuren, S. (2012). Imputasi Fleksibel atas Data yang Hilang. Boca Raton: CRC Press.

Tomka
sumber
1
tanggapan yang sangat baik, di satu sisi saya senang telah maju setidaknya ke arah yang harus saya ikuti, di sisi lain saya sedih tidak memiliki pendekatan ramah yang saya tidak berpikir. Pada prediksi interaktif data yang hilang dengan metode bayes, bagaimana saya bisa mereproduksi sesuatu seperti ini dengan python? Apakah ini juga regresi? dan setelah memperkirakan semua data yang mungkin hilang, haruskah saya memeriksa prediktor sehingga data baru juga berpartisipasi dalam prediksi itu? Terima kasih banyak atas bantuannya, saya yakin ini akan bermanfaat bagi banyak orang.
sn3fru
1
@ sn3fru Nah, pertanyaan-pertanyaan ini dijawab dalam referensi, di antara tempat-tempat lain. Saya tidak sadar jika implementasi Python ada, tetapi mereplikasi seharusnya tidak terlalu sulit. Saya kira itu akan memerlukan sedikit mempelajari detail dari algoritma. Secara umum setiap model Bayesian dapat digunakan untuk membuat beberapa impute, tetapi micealgoritma tersebut menggunakan regresi atau pencocokan prediktif rata-rata. Anda awalnya menyelesaikan data yang hilang dengan menarik dari distribusi yang diamati dan kemudian menyalahkan secara berurutan. Setelah selesai Anda ulangi, tetapi menggunakan nilai yang baru diperhitungkan. Data baru berpartisipasi, ya
Tomka
4

Saya tidak menemukan apa pun yang memecahkan masalah saya, jadi saya menulis sebuah fungsi yang menggabungkan beberapa solusi untuk kerangka data Pandas dengan nilai numerik yang hilang (dengan fancyimpute) dan kategorikal (dengan hutan acak).

import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
import fancyimpute as fi

def separe_numeric_categoric(df):
    numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
    df_n = df.select_dtypes(include=numerics)
    df_c = df.select_dtypes(exclude=numerics)
    print(f'The DF have {len(list(df_n))} numerical features and {len(list(df_c))} categorical fets')
    return df_n, df_c


def find_missing(df):
    total = df.isnull().sum().sort_values(ascending=False)
    percent = (df.isnull().sum()/df.isnull().count()).sort_values(ascending=False)
    filter(lambda x: x>=minimum, percent)
    return percent


def count_missing(df):
    missing = find_missing(df)
    total_columns_with_missing = 0
    for i in (missing):
        if i>0:
            total_columns_with_missing += 1
    return total_columns_with_missing


def remove_missing_data(df,minimum=.1):
    percent = find_missing(df)
    number = len(list(filter(lambda x: x>=(1.0-minimum), percent)))
    names = list(percent.keys()[:number])
    df = df.drop(names, 1, errors='ignore')
    print(f'{number} columns exclude because haven`t minimium data.')
    return df


def one_hot(df, cols):
    for each in cols:
        dummies = pd.get_dummies(df[each], prefix=each, drop_first=False)
        df = pd.concat([df, dummies], axis=1)
    df = df.drop(cols, axis=1)
    return df



def impute_missing_data(df,minimium_data=.1):
    columns_missing = count_missing(df)
    print(f'Total columns with missing values: {count_missing(df)} of a {len(list(df))} columns in df')

    # remove features without minimium size of information
    df = remove_missing_data(df,minimium_data)

    numerical_df, categorical_df = separe_numeric_categoric(df)

    # Autocomplete using MICE for numerical features.
    try:
        df_numerical_complete = fi.MICE(verbose=False).complete(numerical_df.values)
        n_missing = count_missing(df)
        print(f'{columns_missing-n_missing} numerical features imputated')

        # Complete the columns name.
        temp = pd.DataFrame(columns=numerical_df.columns, data=df_numerical_complete)

        # df temp com os dados numericos completados e os categóricos.
        df = pd.concat([temp, categorical_df], axis=1)

    except Exception as e:
        print(e)
        print('Without Missing data in numerical features')

    missing = find_missing(df)
    names = missing.keys()
    n = 0
    for i, c in enumerate(missing):
        if c > 0:
            col = names[i]
            print(f'Start the prediction of {col}')
            clf = RandomForestClassifier()
            le = LabelEncoder()
            ## inverter a ordem da predição das categóricas pode melhorar a precisao.
            categorical_train = list(categorical_df.loc[:,categorical_df.columns != col])

            temp = one_hot(df,categorical_train)
            df1 = temp[temp[col].notnull()]
            df2 = temp[temp[col].isnull()]
            df1_x = df1.loc[:, df1.columns != col]
            df2_x = df2.loc[:, df1.columns != col]

            df1_y = df1[col]
            le.fit(df1_y)
            df1_y = le.transform(df1_y)
            clf.fit(df1_x, df1_y)
            df2_yHat = clf.predict(df2_x)
            df2_yHat = le.inverse_transform(df2_yHat)
            df2_yHat = pd.DataFrame(data=df2_yHat, columns=[col])
            df1_y = le.inverse_transform(df1_y)
            df1_y = pd.DataFrame(data=df1_y,columns=[col])

            df2_x.reset_index(inplace=True)   
            result2 = pd.concat([df2_yHat, df2_x], axis=1)
            try:
                del result2['index']
            except:
                pass

            df1_x.reset_index(inplace=True)
            result1 = pd.concat([df1_y, df1_x], axis=1)
            try:
                del result1['index']
            except:
                pass

            result = pd.concat([result1, result2])
            result = result.set_index(['Id'])
            df.reset_index()            
            try:
                df.set_index(['Id'],inplace=True)
            except:
                pass
            df[col] = result[col]

            n += 1

    print(f'Number of columns categorical with missing data solved: {n}')

    return df


df = impute_missing_data(df)
sn3fru
sumber
Bagus, ini dapat membantu orang lain (saya tidak memeriksanya) - mungkin juga menarik bagi Anda untuk menghubungi pembuat Rfungsi mice, Stef van Buuren. Dia mungkin tertarik pada kode Python Anda dan / atau mengarahkan Anda ke pekerjaan orang lain dalam hal ini. stefvanbuuren.nl
tomka
Saya tidak tahu apakah mereka akan tertarik pada sesuatu yang begitu sederhana, saya hanya berbagi di sini karena dapat membantu orang lain yang membutuhkan penyelesaian yang hilang dalam kerangka data Pandas.
sn3fru
Yah mereka mungkin tertarik untuk mengimplementasikannya di Python secara umum dan mereka mungkin tahu apakah seseorang sudah melakukannya. Saya telah menghubungi Stef sebelumnya dan dia sangat responsif dan membantu. Jika ada implementasi Python, mungkin bermanfaat juga untuk membagikannya di sini di bawah utas ini. Lihat misalnya pypi.python.org/pypi/fancyimpute/0.0.4
tomka