2016-12-26 38 views
8

Buduję model predykcji w python z dwoma oddzielnymi zestawami treningowymi i testowymi. Dane treningowe zawierają zmienną kategoryczną typu liczbowego, np. Kod pocztowy, [91521,23151,12355, ...], a także zmienne kategoryczne ciągów, np. Miasto ["Chicago", "Nowy Jork", "Los Angeles", ...].Zachowaj tę samą zmienną dummy w danych treningowych i testowych

Aby wyedukować dane, najpierw używam "pd.get_dummies", aby pobrać zmienną atrybutu tych zmiennych, a następnie dopasować model do transformowanych danych treningowych.

Wykonuję tę samą transformację danych testowych i przewiduję wynik przy użyciu wyszkolonego modelu. Jednak wystąpił błąd "ValueError: Liczba funkcji modelu musi być zgodna z danymi wejściowymi. Model n_features ma wartość 1487, a parametr wejściowy n_features to 1345 '. Powodem jest to, że w danych testowych jest mniej zmiennych "obojętnych", ponieważ ma mniej "miasta" i "kodu pocztowego".

Jak mogę rozwiązać ten problem? Na przykład "OneHotEncoder" koduje tylko wszystkie zmienne kategoryczne typu liczbowego. "DictVectorizer()" będzie kodował tylko wszystkie zmienne kategoryczne typu string. Przeszukuję online i widzę kilka podobnych pytań, ale żadna z nich naprawdę nie odpowiada na moje pytanie.

Handling categorical features using scikit-learn

https://www.quora.com/If-the-training-dataset-has-more-variables-than-the-test-dataset-what-does-one-do

https://www.quora.com/What-is-the-best-way-to-do-a-binary-one-hot-one-of-K-coding-in-Python

Odpowiedz

10

Załóżmy masz nazwy identyczne cecha w pociągu i zbiorze testowym. Można wygenerować połączony zestaw danych z pociągu i przetestować, pobrać atrapy ze zsumowanego zestawu danych i podzielić go na szkolenie i testowanie.

Można zrobić to w ten sposób:

import pandas as pd 
train = pd.DataFrame(data = [['a', 123, 'ab'], ['b', 234, 'bc']], 
        columns=['col1', 'col2', 'col3']) 
test = pd.DataFrame(data = [['c', 345, 'ab'], ['b', 456, 'ab']], 
        columns=['col1', 'col2', 'col3']) 
train_objs_num = len(train) 
dataset = pd.concat(objs=[train, test], axis=0) 
dataset_preprocessed = pd.get_dummies(dataset) 
train_preprocessed = dataset_preprocessed[:train_objs_num] 
test_preprocessed = dataset_preprocessed[train_objs_num:] 

W rezultacie, masz taką samą liczbę funkcji dla pociągu i zbiorze testowym.

11

Można też po prostu brakujące kolumny i dodać je do zbiorze testowym:

# Get missing columns in the training test 
missing_cols = set(train.columns) - set(test.columns) 
# Add a missing column in test set with default value equal to 0 
for c in missing_cols: 
    test[c] = 0 
# Ensure the order of column in the test set is in the same order than in train set 
test = test[train.columns] 

Ten kod zapewnić również, że kolumny wynikającego z kategorii w zbiorze testowym, ale nie występuje w zbiorze treningowym zostanie usunięty

1
train2,test2 = train.align(test, join='outer', axis=1, fill_value=0) 

Pociąg2 i test2 mają te same kolumny. Wartość_pełnienia wskazuje wartość używaną w przypadku brakujących kolumn.