[6일째] 분류 변수를 인코딩합니다[2021 추가 달력]
2021년 1인 advent 달력(기계학습), 6일째 보도.
테마는 분류 변수의 인코딩입니다.
대략적으로 말하면, 이것은 수치가 아닌 데이터를 기계 학습으로 처리하는 방법이다.
상세한 상황은 아래와 같다.
분류 변수란 키와 나이처럼 수치로 나타내는 변수가 아니라 조합, 속성(색상, 국가 등)을 분류하는 데 쓰이는 변수를 말한다.또한 분류 변수는 명목 변수와 순서 변수로 나눌 수 있다.
변수 이름
개요
변수 예
디지털 변수
수치로 구성된 변수
신장/나이
명목 변수
정렬하거나 정렬할 수 없는 분류 변수
/색상 (빨간색, 파란색, 녹색)/국가 (일본, 미국, 중국)
정렬 변수
정렬 또는 정렬할 수 있는 분류 변수
・티셔츠 사이즈(S, M, L)
여기서 카테고리 변수의 항목 수에 따른 교부 시퀀스 번호를 처리하는 Ordinal Encoding과 카테고리 변수의 항목 내역을 가상 변수로 변환하는 One Hot Encoding을 다룹니다.
가상 변수는 무엇입니까?
0이나 1의 값을 취하는 변수.
https://plaza.umin.ac.jp/~health-stat/faq/faq17/
Colab의 코드는 여기.입니다.
모든 OrdinalEnceoding
scikit-learn의 Ordinal Enceoding은 결손 값이 있어도 처리할 수 있지만 인코딩이 없기 때문에'missing'이라는 문자열로 결손 값을 대체합니다.
(missing'을 만드는 것은 알기 쉽고 필연성이 없기 때문이다.)
또한 인코딩 처리 후 numby의ary형이 됩니다.
OrdinalEnceoding의 매개 변수인handleunknown에 있어요.encoded_value를 드리겠습니다. unknown value가 설정한 수치로 미지수를 바꿀 수 있습니다.
설정. - 2는 이따가 나올 Category.Encorders의 Ordienal Enceoding은 자동으로 알 수 없는 숫자를 -1로 설정하고 1부터 번호를 매기기 때문에 -2를 지정하여 매칭합니다.
# 数値データとカテゴリーデータに分ける
X_train_number = X_train.select_dtypes(include="number")
X_test_number = X_test.select_dtypes(include="number")
X_train_category = X_train.select_dtypes(include="object")
X_test_category = X_test.select_dtypes(include="object")
# index をリセット
X_train_number = X_train_number.reset_index(drop=True)
X_test_number = X_test_number.reset_index(drop=True)
X_train_category = X_train_category.reset_index(drop=True)
X_test_category = X_test_category.reset_index(drop=True)
# カテゴリーのエンコーディング法則を指定する
ordinal_all_cols_mapping = []
for column in X_train_category.columns:
ordinal_one_cols_mapping = []
for category in natsorted(X_train_category[column].unique()):
ordinal_one_cols_mapping.append(category)
ordinal_all_cols_mapping.append(ordinal_one_cols_mapping)
from sklearn.preprocessing import OrdinalEncoder
# エンコーディング設定
ode = OrdinalEncoder(
handle_unknown = 'use_encoded_value', # 未知数をunknown valueに置き換える設定
unknown_value = -2,
dtype = np.float64,
categories = ordinal_all_cols_mapping
)
# OrdinalEncoderは欠損値があっても処理できるが、エンコーディングしないので欠損値を missing に置き換える
X_train_category = X_train_category.fillna("missing")
X_test_category = X_test_category.fillna("missing")
# エンコーディング
# trainデータは学習と変換、testデータは変換のみを実施。trainの学習パターン通りに変換するため
X_train_labels = ode.fit_transform(X_train_category)
X_test_labels = ode.transform(X_test_category)
# OrdinalEncoder は np.array型に変換してしまうため、DataFrame型で再構築する
X_train_oe = pd.DataFrame(
X_train_labels,
columns=X_train_category.columns
)
X_test_oe = pd.DataFrame(
X_test_labels,
columns=X_test_category.columns
)
# 数値データを結合
X_train_oe = pd.concat([X_train_oe, X_train_number ], axis=1)
X_test_oe = pd.concat([X_test_oe, X_test_number ], axis=1)
분류 변수의 세부 항목이 적은 항목은 OneHotEnceoding이고, 많은 항목은 OrdinalEnceoding이다
분류 변수의 내역수가 많은 변수를 OneHot Encoding 처리할 때 열 수가 너무 많으면 메모리 오류가 발생할 수 있으므로 분류 변수의 세목 수가 많은 경우 Ordinal Enceoding을, 적은 경우 OneHot Enceoding을 수행해야 한다.
(원래 변수의 성질에 따라 OneHot이 좋은지 Ordinal이 좋은지 연구해야 한다)
OrdinalEnceoding과 달리 OnehotEnceoding은 결손 값이 있을 때 인코딩 처리를 하지 않기 때문에 결손 값 처리가 필요하다.
Ordinal Enceoding과 마찬가지로 One Hot Enceoding도 코딩 처리하면 numby의 aray형으로 변한다.
OneHotEncoding 처리 후의 열 이름은 get입니다feature_names_out () 방법을 사용하면 얻을 수 있습니다.
# カテゴリー変数の内訳の数に応じてカラムを分割する
category_unique_num = df.drop(["Global_Sales", "NA_Sales", "PAL_Sales", "JP_Sales", "Other_Sales"], axis=1).select_dtypes(include="object").nunique()
few_kinds_category_columns = category_unique_num[category_unique_num < 10].index
many_kinds_category_columns = category_unique_num[category_unique_num >= 10].index
from sklearn.preprocessing import OneHotEncoder
# エンコーディング設定
ode = OrdinalEncoder(
handle_unknown = 'use_encoded_value', # 未知数をunknown valueに置き換える設定
unknown_value = -2,
dtype = np.float64,
categories = ordinal_all_cols_mapping_en
)
ohe = OneHotEncoder(
handle_unknown = 'ignore',
sparse = False,
dtype = np.int64,
)
# OneHotEncoderは欠損値があっても処理できるが、エンコーディングしないので欠損値を missing に置き換える
X_train_category = X_train_category.fillna("missing")
X_test_category = X_test_category.fillna("missing")
# エンコーディング
# trainデータは学習と変換、testデータは変換のみを実施。trainの学習パターン通りに変換するため
# OneHotEncoder
X_train_ohe_labels = ohe.fit_transform(X_train_category[few_kinds_category_columns])
X_test_ohe_labels = ohe.transform(X_test_category[few_kinds_category_columns ])
# OrdinalEncoder
X_train_ode_labels = ode.fit_transform(X_train_category[many_kinds_category_columns]) + 1
X_test_ode_labels = ode.transform(X_test_category[many_kinds_category_columns ]) + 1
# np.array型になってしまうため、DataFrame型で再構築する
# trainデータ
X_train_ode = pd.DataFrame(
X_train_ode_labels,
columns=X_train_category[many_kinds_category_columns].columns
)
X_train_ohe = pd.DataFrame(
X_train_ohe_labels,
columns=ohe.get_feature_names_out(few_kinds_category_columns)
)
X_train_en = pd.concat([X_train_ohe, X_train_ode], axis=1)
# testデータ
X_test_ode = pd.DataFrame(
X_test_ode_labels,
columns=X_test_category[many_kinds_category_columns].columns
)
X_test_ohe = pd.DataFrame(
X_test_ohe_labels,
columns=ohe.get_feature_names_out(few_kinds_category_columns)
)
X_test_en = pd.concat([X_test_ohe, X_test_ode], axis=1)
# 数値データを結合
X_train_en = pd.concat([X_train_en, X_train_number ], axis=1)
X_test_en = pd.concat([X_test_en, X_test_number ], axis=1)
Category_Encorders 사용
분류 변수 인코딩을 위한 라이브러리, CategoryEncorders를 사용합니다.
인코딩 처리 후 되돌아오는 값은 DataFrame형이 될 수도 있고 인코딩 처리를 할 열을 지정할 수도 있어 매우 쉽다.
# カテゴリーのエンコーディング法則を指定する
ordinal_all_cols_mapping_ce = []
for i, column in enumerate(many_kinds_category_columns):
ordinal_one_cols_mapping = {}
ordinal_one_cols_mapping_breakdown = {}
for j, category in enumerate(natsorted(X_train[column].unique())):
ordinal_one_cols_mapping_breakdown[category] = j
ordinal_one_cols_mapping["col"] = column
ordinal_one_cols_mapping["mapping"] = ordinal_one_cols_mapping_breakdown
ordinal_all_cols_mapping_ce.append(ordinal_one_cols_mapping)
# エンコーディング設定
ode = ce.OrdinalEncoder(
mapping = ordinal_all_cols_mapping_ce,
cols = many_kinds_category_columns
)
ohe = ce.OneHotEncoder(
use_cat_names=True,
cols = few_kinds_category_columns
)
# 元データを壊さないようにコピーする
X_train_ce = X_train.copy()
X_test_ce = X_test.copy()
# 欠損値処理
category_columns = category_unique_num.index
X_train_ce[category_columns] = X_train_ce[category_columns].fillna("missing")
X_test_ce[category_columns] = X_test_ce[category_columns].fillna("missing")
# OneHotEncoder
X_train_ce = ohe.fit_transform(X_train_ce)
X_test_ce = ohe.transform(X_test_ce)
# OrdinalHotEncoder
X_train_ce = ode.fit_transform(X_train_ce)
X_test_ce = ode.transform(X_test_ce)
# 正規化
sc = StandardScaler()
X_train_ce = pd.DataFrame(
sc.fit_transform(X_train_ce),
columns=X_train_ce.columns
)
X_test_ce = pd.DataFrame(
sc.transform(X_test_ce),
columns=X_test_ce.columns
)
OrdinalEnceoding만: 0.235.19774193sklearn에서 OneHot+Ordinal Enceoding: 0.22288307344096592
Category Encorders One Hot + Ordinal Enceoding: 0.222648763368118405
6일째 되는 날 여기까지 읽어주셔서 감사합니다.
Reference
이 문제에 관하여([6일째] 분류 변수를 인코딩합니다[2021 추가 달력]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/megane_otoko/articles/2021ad_06_category_encoding텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)