Makine öğreniminde veri eksikliği problemini çözme yöntemleri


15

Makine öğrenme algoritmalarını kullanarak tahminlerde bulunmak istediğimiz herhangi bir veritabanı, bazı özellikler için eksik değerler bulacaktır.

Bu sorunu ele almak, eksik değerlere sahip satırları karakteristiklerin ortalama değerleriyle dolana kadar hariç tutmak için birkaç yaklaşım vardır.

Temelde bağımlı değişken (Y) eksik değerleri olan sütunların her biri ancak tablonun satırları ile olacak bir regresyon (veya başka bir yöntem) çalıştıracak biraz daha sağlam bir yaklaşım için kullanmak istiyorum tüm verileri içeren ve bu yöntemle eksik değerleri tahmin eden tabloyu tablodan tamamlayın ve eksik değerlerle bir sonraki 'sütuna' gidin ve her şey dolana kadar yöntemi tekrarlayın.

Ama bu bana bazı şüpheler veriyor.

Neden herhangi bir sütun başlıyor? En küçük eksik değerlere sahip olanın

Eksik değerleri denemeye değmeyecek herhangi bir eksik değer eşiği var mı? (örneğin, bu özellik yalnızca doldurulmuş değerlerin% 10'una sahipse, hariç tutmak daha ilginç olmaz)

Geleneksel paketlerde veya eksik yöntemlere karşı sağlam diğer yöntemlerde herhangi bir uygulama var mı?


3
Aradığınız sanat terimi, birden fazla itirafın popüler ve modern bir seçim olduğu "empoze" dir. Eksik gözlemleri olan gözlemleri hariç tutmanın veya eksik gözlemleri ortalamanın yerine koymanın verileri kötü yönde saptayabileceğini unutmayın. Başlamak için bir yer Gelman ve arkadaşları, Bayesian Veri Analizi 3. Baskı, "Bölüm 18: Eksik Veri Modelleri" dir.
Sycorax, Reinstate Monica'ya

Bahşiş için teşekkürler, bu terimi arayacağım ve s18'e bakacağım. Çizgileri silmek, modeli çok önyargılar (eksikler rastgele değilse, bu çok olasıdır) ve ortalamanın yerleştirilmesi, veri eksiklerinin eksojenitesine bağlı olarak ortalamaya güçlü bir 'atalet yükü' koyabilir. Benim büyük sorum bunu ele almak için en iyi yaklaşım ve benim önerim ana gerilemeden önce verileri tamamlamak için ön gerileme çalıştırmak olacaktır (bunu yapan herhangi bir paket var mı veya bir tane oluşturmak gerekir?)
sn3fru

Modern çoklu gösterim, eksik ve eksik veriler için yan yana bir model tahmin eder. Eksik verilerin Bayes alması, gözlemlenen verilere ve eksiklik modeline bağlı olarak eksik veriler üzerindeki dağılımı tahmin etmektir. Python'daki istatistiksel yazılım arzulanan çok şey bırakıyor. TSCS verileri için, Amelia IIR cinsinden sağlam bir seçimdir. Veya kendi kullanarak rulo olabilir stan.
Sycorax, Reinstate Monica'nın

Yanıtlar:


9

Açıkladığınız tekniğe sıralı regresyonlarla çarpma veya zincirlenmiş denklemlerle çoklu çarpma denir. Tekniğe Raghunathan (2001) öncülük etti ve iyi çalışan bir R paketinde uygulandı mice(van Buuren, 2012).

Schafer ve Graham'ın (2002) yazdığı bir makale, ortalama ima ve nedenlerden dolayı silme işleminin (satır dışlama olarak adlandırdığınız) genellikle yukarıda belirtilen tekniklere iyi bir alternatif olmadığını açıklamaktadır. Prensip olarak ortalama impütasyon şartlı değildir ve bu nedenle impüte edilen dağılımları gözlenen ortalamaya doğru yönlendirebilir. Ayrıca, çarpık dağılım üzerindeki istenmeyen diğer etkilerin yanı sıra varyansı daraltacaktır. Ayrıca, listwise silme gerçekten de sadece bir bozuk parayı çevirmek gibi, veriler tamamen rastgele eksikse işe yarayacaktır. Ayrıca numune boyutu küçüldükçe örnekleme hatasını artıracaktır.

Yukarıda alıntı yapılan yazarlar genellikle en az eksik değerleri içeren değişkenle başlamayı önerir. Ayrıca, teknik genellikle Bayesci bir şekilde uygulanır (yani önerinizin bir uzantısı). Değişkenler, yalnızca bir kez değil, isnat prosedüründe daha sık ziyaret edilir. Özellikle, her değişken, en az eksik değerlere sahip değişkenle başlayarak, koşullu posterior öngörücü dağılımından çekimlerle tamamlanır. Bir veri kümesindeki tüm değişkenler tamamlandıktan sonra, algoritma tekrar ilk değişkente başlar ve sonra yakınsamaya kadar tekrarlanır. Yazarlar bu algoritmanın Gibbs olduğunu göstermiştir, bu nedenle genellikle değişkenlerin doğru çok değişkenli dağılımına yakınsarlar.

Genellikle, söz konusu test edilemeyen varsayımlar olduğu için, özellikle rastgele verilerde eksik olduğu için (yani verilerin gözlemlenip gözlemlenmediği gözlemlenmeyen verilere değil, yalnızca gözlemlenen verilere bağlıdır). Ayrıca prosedürler kısmen uyumsuz olabilir, bu yüzden PIGS (kısmen uyumsuz Gibbs örnekleyici) olarak adlandırılmıştır.

Uygulamada Bayes çoklu çarpma, çok değişkenli monoton olmayan eksik veri sorunları ile başa çıkmak için hala iyi bir yoldur. Ayrıca, tahmini ortalama eşleştirme gibi parametrik olmayan uzantılar, regresyon modelleme varsayımlarını gevşetmeye yardımcı olur.


Raghunathan, TE, Lepkowski, J., van Hoewyk, J. ve Solenberger, P. (2001). Bir dizi regresyon modeli kullanarak eksik değerleri çarpma amaçlı çok değişkenli bir teknik. Anket Metodolojisi, 27 (1), 85-95.

Schafer, JL ve Graham, JW (2002). Eksik veriler: Tekniğin bilinen durumu hakkındaki görüşümüz. Psikolojik Yöntemler, 7 (2), 147-177. https://doi.org/10.1037/1082-989X.7.2.147

van Buuren, S. (2012). Eksik Verilerin Esnek Birleşimi. Boca Raton: CRC Press.


1
mükemmel yanıt, bir yandan en azından takip etmem gereken yönü ileri sürdüğüne sevindim, öte yandan düşünmediğim bir cinsel yaklaşıma sahip olmadığım için üzgünüm. Bayes yöntemiyle eksik verilerin etkileşimli tahmininde, python'da böyle bir şeyi nasıl çoğaltabilirim? Bu da bir gerileme mi? ve tüm olası eksik verileri tahmin ettikten sonra, yeni verilerin de bu tahmine katılması için öngörücüyü aşmalıyım? Yardımınız için çok teşekkürler, birçok kişiye fayda sağlayacağına inanıyorum.
sn3fru

1
@ sn3fru Peki, bu sorular diğer yerlerin yanı sıra referanslarda da cevaplanmıştır. Bir Python uygulaması olup olmadığını bilmiyorum, ancak çoğaltmak çok zor olmamalı. Sanırım algoritmanın detaylarını biraz incelemek gerekir. Genel olarak, herhangi bir Bayesci model birden çok impute oluşturmak için kullanılabilir, ancak micealgoritma regresyon veya tahmini ortalama eşleşmesini kullanır. Başlangıçta, eksik verileri gözlemlenen dağılımdan çekerek tamamlar ve ardından sırayla yükler. Bitirdiğinizde tekrar edersiniz, ancak yeni yüklenen değerleri kullanırsınız. Yeni veriler katılıyor, evet
tomka

4

Sorunumu çözen bir şey bulamadım, bu yüzden bazı sayısal değerleri eksik olan (fantezi) ile ve rasgele bir ormanla kategorik olan Pandas veri çerçevesine bazı çözümleri karıştıran bir işlev yazdım.

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)

Güzel, bu başkalarına yardımcı olabilir (kontrol etmedim) - ayrıca Rişlevin yaratıcısı miceStef van Buuren ile iletişime geçmeniz de ilginç olabilir . Python kodunuzla ilgilenebilir ve / veya sizi bu konuda başkalarının çalışmalarına yönlendirebilir. stefvanbuuren.nl
tomka

Bu kadar basit bir şeyle ilgilenip ilgilenmeyeceklerini bilmiyorum, sadece burada paylaşıyorum çünkü bir Pandas veri çerçevesinde eksik çözülmesi gereken diğer insanlara yardımcı olabilir.
sn3fru

Genel olarak Python'da uygulamakla ilgilenebilirler ve birisinin zaten yapılıp yapılmadığını bilebilirler. Daha önce Stef ile iletişime geçtim ve çok duyarlı ve yardımsever. Bir Python uygulaması varsa, burada bu iş parçacığı altında paylaşmak da yararlı olabilir. Örneğin, bkz. Pypi.python.org/pypi/fancyimpute/0.0.4
tomka

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.