작성자 없음
작성자 정보가 삭제된 글입니다.
작성
·
155
0
인프런님, 말씀해주신 코딩대로 전체 문자열에 대해 라벨인코딩 했는데 오류가 뜹니다,,
# 필요한 라이브러리를 불러옵니다.
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.model_selection import train_test_split
# 시험환경 세팅 함수 (변경하지 않습니다.)
def exam_data_load(df, target, id_name="", null_name=""):
if id_name == "":
df = df.reset_index().rename(columns={"index": "id"})
id_name = 'id'
else:
id_name = id_name
if null_name != "":
df[df == null_name] = np.nan
X_train, X_test = train_test_split(df, test_size=0.2, shuffle=True, random_state=2021)
y_train = X_train[[id_name, target]]
X_train = X_train.drop(columns=[id_name, target])
y_test = X_test[[id_name, target]]
X_test = X_test.drop(columns=[id_name, target])
return X_train, X_test, y_train, y_test
# 데이터를 불러옵니다.
df = pd.read_csv("../input/house-prices-advanced-regression-techniques/train.csv")
# 데이터를 분리합니다.
X_train, X_test, y_train, y_test = exam_data_load(df, target='SalePrice', id_name='Id')
# 레이블 인코딩을 수행합니다.
# 모든 문자열 특성에 대해 레이블 인코딩을 적용합니다.
for col in X_train.columns:
if X_train[col].dtype == 'object':
encoder = LabelEncoder()
X_train[col] = encoder.fit_transform(X_train[col].astype(str))
X_test[col] = encoder.transform(X_test[col].astype(str))
# 랜덤 포레스트 모델을 생성하고 훈련합니다.
model = RandomForestRegressor(n_estimators=100, random_state=2021)
model.fit(X_train, y_train['SalePrice'])
# 예측을 수행합니다.
y_pred = model.predict(X_test)
# RMSE와 R2 값을 계산합니다.
rmse = np.sqrt(mean_squared_error(y_test['SalePrice'], y_pred))
r2 = r2_score(y_test['SalePrice'], y_pred)
print(f'RMSE: {rmse:.4f}')
print(f'R2 Score: {r2:.4f}')
오류내용은 아래와 같습니다
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
/opt/conda/lib/python3.7/site-packages/sklearn/preprocessing/_label.py in _encode_python(values, uniques, encode)
65 try:
---> 66 encoded = np.array([table[v] for v in values])
67 except KeyError as e:
/opt/conda/lib/python3.7/site-packages/sklearn/preprocessing/_label.py in <listcomp>(.0)
65 try:
---> 66 encoded = np.array([table[v] for v in values])
67 except KeyError as e:
KeyError: 'Membran'
During handling of the above exception, another exception occurred:
ValueError Traceback (most recent call last)
/tmp/ipykernel_20/2316063552.py in <module>
38 encoder = LabelEncoder()
39 X_train[col] = encoder.fit_transform(X_train[col].astype(str))
---> 40 X_test[col] = encoder.transform(X_test[col].astype(str))
41
42 # 랜덤 포레스트 모델을 생성하고 훈련합니다.
/opt/conda/lib/python3.7/site-packages/sklearn/preprocessing/_label.py in transform(self, y)
275 return np.array([])
276
--> 277 _, y = _encode(y, uniques=self.classes_, encode=True)
278 return y
279
/opt/conda/lib/python3.7/site-packages/sklearn/preprocessing/_label.py in _encode(values, uniques, encode, check_unknown)
111 if values.dtype == object:
112 try:
--> 113 res = _encode_python(values, uniques, encode)
114 except TypeError:
115 types = sorted(t.__qualname__
/opt/conda/lib/python3.7/site-packages/sklearn/preprocessing/_label.py in _encode_python(values, uniques, encode)
67 except KeyError as e:
68 raise ValueError("y contains previously unseen labels: %s"
---> 69 % str(e))
70 return uniques, encoded
71 else:
ValueError: y contains previously unseen labels: 'Membran'
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
chandnd37님, 라벨 인코딩 과정에서 발생한 오류는 훈련 데이터셋(X_train
)에는 없고 테스트 데이터셋(X_test
)에 있는 새로운 범주에 대해 인코딩을 시도했기 때문에 발생합니다. LabelEncoder
는 fit
메서드를 사용하여 훈련 데이터셋의 범주를 학습하고, 이 범주에 대해 정수 라벨을 부여합니다. 만약 테스트 데이터셋에 훈련 데이터셋에 없던 새로운 범주가 있다면 transform
메서드를 사용할 때 KeyError
가 발생합니다.
이 문제를 해결하기 위해서는 훈련 데이터셋과 테스트 데이터셋에 모두 등장하는 범주만을 고려하여 인코딩을 해야 합니다. 또한, 훈련 데이터에만 있는 범주는 무시하거나 다르게 처리해야 합니다. 테스트 데이터의 새로운 범주를 ‘unknown’이라는 공통 범주로 통일하여 인코딩하는 방법도 있습니다. ‘unknown’ 범주를 추가하여 fit
시켜주거나, 아니면 새로운 범주에 대해서는 무시하고 처리하는 방법을 사용할 수 있습니다. 먼저, fit_transform
을 적용하기 전에 데이터셋을 분석하여 어떤 문자열 값들이 시험 데이터셋에만 존재하는지 확인해보는 것이 좋겠습니다.
아래의 코드는 ‘unknown’ 범주를 추가하여 처리하는 예제를 보여줍니다:
# ...
for col in X_train.columns:
if X_train[col].dtype == 'object':
# Train에만 있는 레이블을 'unknown'으로 바꾸고 인코딩
train_unique_labels = set(X_train[col].unique())
test_unique_labels = set(X_test[col].unique())
# `X_test`에만 존재하는 레이블을 'unknown'으로 변경
X_test[col] = X_test[col].apply(
lambda x: 'unknown' if x not in train_unique_labels else x
)
# 인코딩
encoder = LabelEncoder()
encoder.fit(list(train_unique_labels) + ['unknown']) # 'unknown' 포함하여 학습
X_train[col] = encoder.transform(X_train[col].astype(str))
X_test[col] = encoder.transform(X_test[col].astype(str))
# ...
만약 ‘unknown’ 범주 없이 무시하고 처리하고 싶다면, 이에 대한 예외 처리를 하여 처리하면 됩니다.
추가적인 도움이 필요하시면 언제든 문의해주시기 바랍니다.