<jupyter_start><jupyter_text>5장. 범주형 데이터 다루기 이 노트북을 주피터 노트북 뷰어(nbviewer.jupyter.org)로 보거나 구글 코랩(colab.research.google.com)에서 실행할 수 있습니다.      주피터 노트북 뷰어로 보기        구글 코랩(Colab)에서 실행하기    5.1 순서가 없는 범주 특성 인코딩하기<jupyter_code># 라이브러리를 임포트합니다.
import numpy as np
from sklearn.preprocessing import LabelBinarizer, MultiLabelBinarizer

# 특성을 만듭니다.
feature = np.array([["Texas"],
                    ["California"],
                    ["Texas"],
                    ["Delaware"],
                    ["Texas"]])

# 원-핫 인코더를 만듭니다.
one_hot = LabelBinarizer()

# 특성을 원-핫 인코딩합니다.
one_hot.fit_transform(feature)
# 특성의 클래스를 확인합니다.
one_hot.classes_
# 원-핫 인코딩을 되돌립니다.
one_hot.inverse_transform(one_hot.transform(feature))
# 라이브러리를 임포트합니다.
import pandas as pd

# 특성으로 더미(dummy) 변수를 만듭니다.
pd.get_dummies(feature[:,0])
# 다중 클래스 특성을 만듭니다.
multiclass_feature = [("Texas", "Florida"),
                      ("California", "Alabama"),
                      ("Texas", "Florida"),
                      ("Delware", "Florida"),
                      ("Texas", "Alabama")]

# 다중 클래스 원-핫 인코더를 만듭니다.
one_hot_multiclass = MultiLabelBinarizer()

# 다중 클래스 특성을 원-핫 인코딩합니다.
one_hot_multiclass.fit_transform(multiclass_feature)
# 클래스를 확인합니다.
one_hot_multiclass.classes_<jupyter_output><empty_output><jupyter_text>붙임<jupyter_code>from sklearn.preprocessing import OneHotEncoder

# 여러 개의 열이 있는 특성 배열을 만듭니다.
feature = np.array([["Texas", 1],
                    ["California", 1],
                    ["Texas", 3],
                    ["Delaware", 1],
                    ["Texas", 1]])

one_hot_encoder = OneHotEncoder(sparse=False)
one_hot_encoder.fit_transform(feature)
one_hot_encoder.categories_<jupyter_output><empty_output><jupyter_text>5.2 순서가 있는 범주형 특성 인코딩하기<jupyter_code># 라이브러리를 임포트합니다.
import pandas as pd

# 특성을 만듭니다.
dataframe = pd.DataFrame({"Score": ["Low", "Low", "Medium", "Medium", "High"]})

# 매핑 딕셔너리를 만듭니다.
scale_mapper = {"Low":1,
                "Medium":2,
                "High":3}

# 특성을 정수로 변환합니다.
dataframe["Score"].replace(scale_mapper)
dataframe = pd.DataFrame({"Score": ["Low",
                                    "Low",
                                    "Medium",
                                    "Medium",
                                    "High",
                                    "Barely More Than Medium"]})

scale_mapper = {"Low":1,
                "Medium":2,
                "Barely More Than Medium": 3,
                "High":4}

dataframe["Score"].replace(scale_mapper)
scale_mapper = {"Low":1,
                "Medium":2,
                "Barely More Than Medium": 2.1,
                "High":3}
dataframe["Score"].replace(scale_mapper)<jupyter_output><empty_output><jupyter_text>붙임<jupyter_code>from sklearn.preprocessing import OrdinalEncoder

features = np.array([["Low", 10],
                     ["High", 50],
                     ["Medium", 3]])

ordinal_encoder = OrdinalEncoder()
ordinal_encoder.fit_transform(features)
ordinal_encoder.categories_<jupyter_output><empty_output><jupyter_text>5.3 특성의 딕셔너리를 인코딩하기<jupyter_code># 라이브러리를 임포트합니다.
from sklearn.feature_extraction import DictVectorizer

# 딕셔너리를 만듭니다.
data_dict = [{"Red": 2, "Blue": 4},
             {"Red": 4, "Blue": 3},
             {"Red": 1, "Yellow": 2},
             {"Red": 2, "Yellow": 2}]

# DictVectorizer 객체를 만듭니다.
dictvectorizer = DictVectorizer(sparse=False)

# 딕셔너리를 특성 행렬로 변환합니다.
features = dictvectorizer.fit_transform(data_dict)

# 특성 행렬을 확인합니다.
features
# 특성 이름을 얻습니다.
feature_names = dictvectorizer.get_feature_names()

# 특성 이름을 확인합니다.
feature_names
# 라이브러리를 임포트합니다.
import pandas as pd

# 특성으로 데이터프레임을 만듭니다.
pd.DataFrame(features, columns=feature_names)
# 네 개의 문서에 대한 단어 카운트 딕셔너리를 만듭니다.
doc_1_word_count = {"Red": 2, "Blue": 4}
doc_2_word_count = {"Red": 4, "Blue": 3}
doc_3_word_count = {"Red": 1, "Yellow": 2}
doc_4_word_count = {"Red": 2, "Yellow": 2}

# 리스트를 만듭니다.
doc_word_counts = [doc_1_word_count,
                   doc_2_word_count,
                   doc_3_word_count,
                   doc_4_word_count]

# 단어 카운트 딕셔너리를 특성 행렬로 변환합니다.
dictvectorizer.fit_transform(doc_word_counts)<jupyter_output><empty_output><jupyter_text>5.4 누락된 클래스 값을 대체하기<jupyter_code># 라이브러리를 임포트합니다.
import numpy as np
from sklearn.neighbors import KNeighborsClassifier

# 범주형 특성을 가진 특성 행렬을 만듭니다.
X = np.array([[0, 2.10, 1.45],
              [1, 1.18, 1.33],
              [0, 1.22, 1.27],
              [1, -0.21, -1.19]])

# 범주형 특성에 누락된 값이 있는 특성 행렬을 만듭니다.
X_with_nan = np.array([[np.nan, 0.87, 1.31],
                       [np.nan, -0.67, -0.22]])

# KNN 학습기를 훈련합니다.
clf = KNeighborsClassifier(3, weights='distance')
trained_model = clf.fit(X[:,1:], X[:,0])

# 누락된 값의 클래스를 예측합니다.
imputed_values = trained_model.predict(X_with_nan[:,1:])

# 예측된 클래스와 원본 특성을 열로 합칩니다.
X_with_imputed = np.hstack((imputed_values.reshape(-1,1), X_with_nan[:,1:]))

# 두 특성 행렬을 연결합니다.
np.vstack((X_with_imputed, X))
from sklearn.impute import SimpleImputer

# 두 개의 특성 행렬을 합칩니다.
X_complete = np.vstack((X_with_nan, X))

imputer = SimpleImputer(strategy='most_frequent')
imputer.fit_transform(X_complete)<jupyter_output><empty_output><jupyter_text>5.5 불균형한 클래스 다루기<jupyter_code># 라이브러리를 임포트합니다.
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris

# 붓꽃 데이터를 적재합니다.
iris = load_iris()

# 특성 행렬을 만듭니다.
features = iris.data

# 타깃 벡터를 만듭니다.
target = iris.target

# 처음 40개 샘플을 삭제합니다.
features = features[40:,:]
target = target[40:]

# 클래스 0을 음성 클래스로 하는 이진 타깃 벡터를 만듭니다.
target = np.where((target == 0), 0, 1)

# 불균형한 타깃 벡터를 확인합니다.
target
# 가중치를 만듭니다.
weights = {0: .9, 1: 0.1}

# 가중치를 부여한 랜덤 포레스트 분류기를 만듭니다.
RandomForestClassifier(class_weight=weights)
# 균형잡힌 클래스 가중치로 랜덤 포레스트 모델을 훈련합니다.
RandomForestClassifier(class_weight="balanced")
# 각 클래스의 샘플 인덱스를 추출합니다.
i_class0 = np.where(target == 0)[0]
i_class1 = np.where(target == 1)[0]

# 각 클래스의 샘플 개수
n_class0 = len(i_class0)
n_class1 = len(i_class1)

# 클래스 0의 샘플만큼 클래스 1에서 중복을 허용하지 않고 랜덤하게 샘플을 뽑습니다.
# from class 1 without replacement
i_class1_downsampled = np.random.choice(i_class1, size=n_class0, replace=False)

# 클래스 0의 타깃 벡터와 다운샘플링된 클래스 1의 타깃 벡터를 합칩니다.
np.hstack((target[i_class0], target[i_class1_downsampled]))
np.vstack((features[i_class0,:], features[i_class1_downsampled,:]))[0:5]
# 클래스 1의 샘플 개수만큼 클래스 0에서 중복을 허용하여 랜덤하게 샘플을 선택합니다.
i_class0_upsampled = np.random.choice(i_class0, size=n_class1, replace=True)

# 클래스 0의 업샘플링된 타깃 벡터와 클래스 1의 타깃 벡터를 합칩니다.
np.concatenate((target[i_class0_upsampled], target[i_class1]))
# 클래스 0의 업샘플링된 특성 행렬과 클래스 1의 특성 행렬을 합칩니다.
np.vstack((features[i_class0_upsampled,:], features[i_class1,:]))[0:5]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1309721175584024, 'fraction_numerical': 0.0239638281838734, 'mean_word_length': 3.0587155963302752, 'pattern_counts': {'":': 29, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '57312', 'license': 'MIT', 'n_tokens_mistral': 3530, 'n_tokens_neox': 3887, 'n_words': 578, 'path': '05.ipynb', 'repo_name': 'kwtharalkfnaweeze/https-github.com-rickiepark-machine-learning-with-python-cookbook', 'size': '6635'}