Я использовал функцию panda get_dummies для генерации фиктивных столбцов для категориальных переменных для использования с scikit-learn, но заметил, что иногда это работает не так, как я ожидаю.
Предпосылки
|
1
2
3
|
import pandas as pdimport numpy as npfrom sklearn import linear_model |
импортировать панд как pd импортировать numpy как np из sklearn import linear_model
Допустим, у нас есть следующие обучающие и тестовые наборы:
Обучающий набор
|
1
2
3
4
|
train = pd.DataFrame({"letter":["A", "B", "C", "D"], "value": [1, 2, 3, 4]})X_train = train.drop(["value"], axis=1)X_train = pd.get_dummies(X_train)y_train = train["value"] |
train = pd.DataFrame ({«letter»: [«A», «B», «C», «D»], «value»: [1, 2, 3, 4]}) X_train = train.drop ( [«Значение»], ось = 1) X_train = pd.get_dummies (X_train) y_train = train [«значение»]
Тестовый набор
|
1
2
3
4
|
test = pd.DataFrame({"letter":["D", "D", "B", "E"], "value": [4, 5, 7, 19]})X_test = test.drop(["value"], axis=1)X_test = pd.get_dummies(X_test)y_test = test["value"] |
test = pd.DataFrame ({«letter»: [«D», «D», «B», «E»], «value»: [4, 5, 7, 19]})) X_test = test.drop ( [«Значение»], ось = 1) X_test = pd.get_dummies (X_test) y_test = test [«value»]
Теперь предположим, что мы хотим обучить линейную модель на нашем обучающем наборе, а затем использовать ее для прогнозирования значений в нашем наборе испытаний:
Тренируй модель
|
1
2
|
lr = linear_model.LinearRegression()model = lr.fit(X_train, y_train) |
Протестируйте модель
|
1
|
model.score(X_test, y_test) |
|
1
|
ValueError: shapes (4,3) and (4,) not aligned: 3 (dim 1) != 4 (dim 0) |
Хм, это не пошло в план. Если мы напечатаем X_train и X_test, это может помочь пролить некоторый свет:
Проверка поездных / тестовых наборов данных
|
1
|
print(X_train) |
|
1
2
3
4
5
|
letter_A letter_B letter_C letter_D0 1 0 0 01 0 1 0 02 0 0 1 03 0 0 0 1 |
|
1
|
print(X_test) |
|
1
2
3
4
5
|
letter_B letter_D letter_E0 0 1 01 0 1 02 1 0 03 0 0 1 |
Они действительно имеют разные формы и несколько разных имен столбцов, потому что тестовый набор содержал некоторые значения, которых не было в обучающем наборе.
Мы можем исправить это, сделав поле ‘letter’ категориальным, прежде чем запустить метод get_dummies над фреймом данных. На данный момент поле имеет тип «объект»:
Типы столбцов
|
1
|
print(train.info) |
|
1
2
3
4
5
6
7
|
<class 'pandas.core.frame.DataFrame'>RangeIndex: 4 entries, 0 to 3Data columns (total 2 columns):letter 4 non-null objectvalue 4 non-null int64dtypes: int64(1), object(1)memory usage: 144.0+ bytes |
Мы можем исправить это, преобразовав поле ‘letter’ в тип ‘category’ и установив список допустимых значений в качестве уникального набора значений в наборах Train / Test.
Все допустимые значения
|
1
2
3
|
all_data = pd.concat((train,test))for column in all_data.select_dtypes(include=[np.object]).columns: print(column, all_data[column].unique()) |
|
1
|
letter ['A' 'B' 'C' 'D' 'E'] |
Теперь давайте обновим тип нашего поля «письмо» в поезде и протестируем данные.
Тип: «категория»
|
1
2
3
4
5
|
all_data = pd.concat((train,test)) for column in all_data.select_dtypes(include=[np.object]).columns: train[column] = train[column].astype('category', categories = all_data[column].unique()) test[column] = test[column].astype('category', categories = all_data[column].unique()) |
И теперь, если мы вызовем get_dummies для любого фрейма данных, мы получим одинаковый набор столбцов:
get_dummies: взять 2
|
1
2
3
|
X_train = train.drop(["value"], axis=1)X_train = pd.get_dummies(X_train)print(X_train) |
|
1
2
3
4
5
|
letter_A letter_B letter_C letter_D letter_E0 1 0 0 0 01 0 1 0 0 02 0 0 1 0 03 0 0 0 1 0 |
|
1
2
3
|
X_test = test.drop(["value"], axis=1)X_test = pd.get_dummies(X_test)print(X_train) |
|
1
2
3
4
5
|
letter_A letter_B letter_C letter_D letter_E0 0 0 0 1 01 0 0 0 1 02 0 1 0 0 03 0 0 0 0 1 |
Большой! Теперь мы должны быть в состоянии обучить нашу модель и использовать ее в тестовом наборе:
Тренируй модель: возьми 2
|
1
2
|
lr = linear_model.LinearRegression()model = lr.fit(X_train, y_train) |
Протестируйте модель: возьмите 2
|
1
|
model.score(X_test, y_test) |
|
1
|
-1.0604490500863557 |
И мы сделали!
| Ссылка: | Pandas / scikit-learn: get_dummies test / train sets — ValueError: фигуры, не выровненные от нашего партнера по JCG Марка Нидхэма в блоге Марка Нидхэма . |