Я использовал функцию panda get_dummies для генерации фиктивных столбцов для категориальных переменных для использования с scikit-learn, но заметил, что иногда это работает не так, как я ожидаю.
Предпосылки
1
2
3
|
import pandas as pd import numpy as np from 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_D 0 1 0 0 0 1 0 1 0 0 2 0 0 1 0 3 0 0 0 1 |
1
|
print(X_test) |
1
2
3
4
5
|
letter_B letter_D letter_E 0 0 1 0 1 0 1 0 2 1 0 0 3 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 3 Data columns (total 2 columns): letter 4 non- null object value 4 non- null int64 dtypes: 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_E 0 1 0 0 0 0 1 0 1 0 0 0 2 0 0 1 0 0 3 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_E 0 0 0 0 1 0 1 0 0 0 1 0 2 0 1 0 0 0 3 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 Марка Нидхэма в блоге Марка Нидхэма . |