Phương pháp giải quyết vấn đề thiếu dữ liệu trong học máy


15

Hầu như bất kỳ cơ sở dữ liệu nào chúng tôi muốn đưa ra dự đoán bằng thuật toán học máy sẽ tìm thấy các giá trị còn thiếu cho một số đặc điểm.

Có một số cách tiếp cận để giải quyết vấn đề này, để loại trừ các dòng bị thiếu giá trị cho đến khi chúng điền vào các giá trị trung bình của các đặc tính.

Tôi muốn sử dụng cho một cách tiếp cận mạnh mẽ hơn, về cơ bản sẽ chạy hồi quy (hoặc phương thức khác) trong đó biến phụ thuộc (Y) sẽ là mỗi cột bị thiếu giá trị nhưng chỉ với các hàng của bảng chứa tất cả dữ liệu và dự đoán các giá trị còn thiếu với phương thức này, hoàn thành bảng theo bảng và di chuyển đến 'cột' tiếp theo với các giá trị bị thiếu và lặp lại phương thức cho đến khi mọi thứ được lấp đầy.

Nhưng điều đó cho tôi một số nghi ngờ.

Tại sao bất kỳ cột bắt đầu? Tôi tin rằng cái có giá trị thiếu nhỏ nhất cho đến cái có giá trị lớn nhất

Có bất kỳ ngưỡng của các giá trị bị thiếu không đáng để cố gắng hoàn thành nó không? (ví dụ: nếu đặc tính này chỉ có 10% giá trị được điền thì sẽ không thú vị hơn nếu loại trừ nó)

Có bất kỳ loại thực hiện trong các gói truyền thống hoặc các phương pháp khác mạnh mẽ để bỏ lỡ?


3
Thuật ngữ nghệ thuật mà bạn đang tìm kiếm là "sự cắt bỏ", trong đó nhiều thuật ngữ là một lựa chọn phổ biến, hiện đại. Lưu ý rằng việc loại trừ các quan sát bằng các quan sát bị thiếu hoặc thay thế các quan sát bị thiếu bằng giá trị trung bình có thể làm sai lệch dữ liệu. Một nơi để bắt đầu là Gelman et al, Bayesian Phân tích dữ liệu Phiên bản thứ 3, "Chương 18: Mô hình cho dữ liệu bị mất."
Sycorax nói Phục hồi lại

Cảm ơn vì tiền boa, tôi sẽ tìm kiếm với cụm từ đó và nhìn vào cap18. Việc xóa các dòng có thể làm sai lệch mô hình rất nhiều (nếu các sai sót không phải là ngẫu nhiên, rất có thể) và việc đặt trung bình có thể đặt một 'tải quán tính' mạnh xung quanh giá trị trung bình, cũng tùy thuộc vào mức độ sai lệch của dữ liệu. Câu hỏi lớn của tôi là cách tiếp cận tốt nhất để xử lý vấn đề này và đề xuất của tôi là chạy hồi quy trước để hoàn thành dữ liệu trước hồi quy chính (có gói nào thực hiện việc này hay tôi nên tạo một gói?)
sn3fru

Đa phương tiện hiện đại ước tính một mô hình cho dữ liệu bị thiếu và không bị thiếu cạnh nhau. Bayesian đảm nhận dữ liệu bị thiếu là ước tính phân phối dữ liệu bị thiếu, có điều kiện trên dữ liệu được quan sát và mô hình cho sự mất tích. Phần mềm thống kê trong python để lại nhiều mong muốn. Đối với dữ liệu TSCS, Amelia IItrong R là một lựa chọn chắc chắn. Hoặc bạn có thể tự cuộn bằng cách sử dụng stan.
Sycorax nói Phục hồi lại

Câu trả lời:


9

Kỹ thuật mà bạn mô tả được gọi là cắt bỏ bằng các hồi quy tuần tự hoặc nhiều lần cắt ngang bằng các phương trình xích. Kỹ thuật này được Raghunathan (2001) tiên phong và thực hiện trong gói R hoạt động tốt có tên là mice(van Buuren, 2012).

Một bài báo của Schafer và Graham (2002) giải thích rõ lý do tại sao có nghĩa là cắt bỏ và xóa theo cách nghe (cái mà bạn gọi là loại trừ dòng) thường không phải là lựa chọn thay thế tốt cho các kỹ thuật được đề cập ở trên. Nguyên tắc trung bình có nghĩa là không có điều kiện và do đó có thể sai lệch các phân phối bị hạn chế đối với giá trị trung bình quan sát được. Nó cũng sẽ thu hẹp phương sai, trong số các tác động không mong muốn khác đối với phân phối bị tranh chấp. Hơn nữa, việc xóa listwise thực sự sẽ chỉ hoạt động nếu dữ liệu bị mất hoàn toàn ngẫu nhiên, giống như việc lật một đồng xu. Ngoài ra, nó sẽ làm tăng lỗi lấy mẫu, vì kích thước mẫu giảm.

Các tác giả được trích dẫn ở trên thường khuyên nên bắt đầu với biến có các giá trị bị thiếu ít nhất. Ngoài ra, kỹ thuật này thường được áp dụng theo cách Bayes (nghĩa là mở rộng đề xuất của bạn). Các biến được truy cập thường xuyên hơn trong thủ tục cắt bỏ, không chỉ một lần. Cụ thể, mỗi biến được hoàn thành bằng cách rút ra từ phân phối dự báo sau có điều kiện, bắt đầu bằng biến có các giá trị thiếu ít nhất. Khi tất cả các biến trong một tập dữ liệu đã được hoàn thành, thuật toán lại bắt đầu ở biến đầu tiên và sau đó lặp lại cho đến khi hội tụ. Các tác giả đã chỉ ra rằng thuật toán này là Gibbs, do đó nó thường hội tụ đến phân phối đa biến chính xác của các biến.

Thông thường, vì có một số giả định không thể kiểm chứng được liên quan, đặc biệt là thiếu dữ liệu ngẫu nhiên (nghĩa là dữ liệu có được quan sát hay không chỉ phụ thuộc vào dữ liệu được quan sát chứ không phụ thuộc vào các giá trị không quan sát được). Ngoài ra các quy trình có thể không tương thích một phần, đó là lý do tại sao chúng được gọi là PIGS (bộ lấy mẫu Gibbs không tương thích một phần).

Trong thực tế Bayesian nhiều lần cắt bỏ vẫn là một cách tốt để đối phó với các vấn đề thiếu dữ liệu không đơn điệu đa biến. Ngoài ra, các phần mở rộng không tham số như kết hợp trung bình dự đoán giúp thư giãn các giả định mô hình hồi quy.


Raghunathan, TE, Lepkowski, J., van Hoewyk, J., & Solenberger, P. (2001). Một kỹ thuật đa biến để nhân lên các giá trị thiếu bằng cách sử dụng một chuỗi các mô hình hồi quy. Phương pháp khảo sát, 27 (1), 85 nên95.

Schafer, JL, & Graham, JW (2002). Thiếu dữ liệu: Quan điểm của chúng tôi về tình trạng của nghệ thuật. Phương pháp tâm lý, 7 (2), 147 Ảo177. https://doi.org/10.1037/1082-989X.7.2.147

van Buuren, S. (2012). Tính linh hoạt của dữ liệu bị thiếu. Boca Raton: Báo chí CRC.


1
phản ứng tuyệt vời, một mặt tôi rất vui vì đã tiến lên ít nhất là hướng mà tôi phải tuân theo, mặt khác tôi buồn vì không có một cách tiếp cận thể loại mà tôi không nghĩ tới. Theo dự đoán tương tác của dữ liệu bị thiếu theo phương pháp bayes, làm thế nào tôi có thể tái tạo một cái gì đó như thế này trong python? Có phải là một hồi quy quá không? và sau khi dự đoán tất cả các dữ liệu bị thiếu có thể, tôi có nên xem qua dự đoán để dữ liệu mới cũng tham gia vào dự đoán đó không? Rất cám ơn sự giúp đỡ, tôi tin rằng nó sẽ có lợi cho nhiều người khác.
sn3fru

1
@ sn3fru Vâng, những câu hỏi này được trả lời trong tài liệu tham khảo, trong số những nơi khác. Tôi không biết có triển khai Python hay không, nhưng sao chép nó không quá khó. Tôi cho rằng nó sẽ yêu cầu nghiên cứu chi tiết của thuật toán một chút. Nói chung, bất kỳ mô hình Bayes nào cũng có thể được sử dụng để tạo ra nhiều xung đột, nhưng micethuật toán sử dụng phương pháp hồi quy hoặc kết hợp trung bình dự đoán. Ban đầu, bạn hoàn thành dữ liệu còn thiếu bằng cách rút ra từ phân phối được quan sát và sau đó thực hiện tuần tự. Sau khi hoàn thành, bạn lặp lại, nhưng sử dụng các giá trị mới được liệt kê. Dữ liệu mới tham gia, vâng
tomka

4

Tôi không tìm thấy bất cứ điều gì giải quyết vấn đề của mình, vì vậy tôi đã viết một hàm pha trộn một số giải pháp cho khung dữ liệu Pandas với các giá trị số bị thiếu (với hình ảnh lạ mắt) và phân loại (với một khu rừng ngẫu nhiên).

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)

Thật tuyệt, điều này có thể giúp đỡ người khác (tôi đã không kiểm tra nó) - cũng có thể thú vị khi bạn liên hệ với người tạo ra Rchức năng mice, Stef van Buuren. Anh ta có thể quan tâm đến mã Python của bạn và / hoặc hướng bạn đến công việc của người khác về vấn đề này. stefvanbuuren.nl
tomka

Tôi không biết liệu họ có quan tâm đến điều gì đó đơn giản không, tôi chỉ chia sẻ ở đây vì nó có thể giúp những người khác cần giải quyết vấn đề còn thiếu trong khung dữ liệu của Pandas.
sn3fru

Chà, họ có thể quan tâm đến việc triển khai nó trong Python nói chung và họ có thể biết liệu ai đó đã thực hiện nó chưa. Tôi đã liên lạc với Stef trước đây và anh ấy rất nhanh nhạy và hữu ích. Nếu có một triển khai Python, nó cũng có thể hữu ích để chia sẻ nó ở đây theo chủ đề này. Xem ví dụ: pypi.python.org/pypi/fancyimpute/0.0.4
tomka

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.