인프런 커뮤니티 질문&답변

김민정님의 프로필 이미지
김민정

작성한 질문수

[퇴근후딴짓] 빅데이터 분석기사 실기 (작업형1,2,3)

시험환경 살펴보기 (구 버전)

캐글에 있는 타이타닉 생존률 문제

해결된 질문

작성

·

248

0

https://www.kaggle.com/code/agileteam/t2-1-titanic-simple-baseline/notebook

 

캐글에 있는 타이타닉 생존률 문제입니다.

2-3. 범주형 라벨인코딩에서 이런 오류가 나네요..

ValueError: y contains previously unseen labels: 'SOTON/O.Q. 3101311'

아래는 제가 작성한 코딩입니다.. ㅠㅠ

# 2. 전처리
# 2-1. drop
X_train = X_train.drop(columns = ['PassengerId', 'Name'])
X_test = X_test.drop(columns = ['Name'])
X_test_id = X_test.pop('PassengerId')
y_train = y_train.drop(columns = ['PassengerId'])
# 2-2. 결측치처리
# 캐빈 drop, 에이지 mean
X_train = X_train.drop(columns = ['Cabin'])
X_test = X_test.drop(columns = ['Cabin'])
X_train['Age'] = X_train['Age'].fillna(X_train['Age'].mean())
X_test['Age'] = X_test['Age'].fillna(X_test['Age'].mean())

# 2-3. 범주형 라벨인코딩
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
cols = ['Sex', 'Ticket', 'Embarked']
for col in cols :
    X_train[col] = encoder.fit_transform(X_train[col])
    X_test[col] = encoder.transform(X_test[col])

# 분리
from sklearn.model_selection import train_test_split
X_tr, X_val, y_tr, y_val = train_test_split(X_train, y_train, test_size = 0.2, random_state = 2022)

# 학습
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(X_tr, y_tr)
pred = model.predict(X_val)

답변 1

0

퇴근후딴짓님의 프로필 이미지
퇴근후딴짓
지식공유자

테스트 데이터에 훈련 데이터에 없는 새로운 범주가 있을 경우 이러한 오류가 발생합니다.

cols에 있는 컬럼의 카테고리를 확인해주세요 차이가 있는 것 같습니다.

['Sex', 'Ticket', 'Embarked']

김민정님의 프로필 이미지
김민정
질문자

저도 처음에 오류 메시지를 그렇게 이해하고, 컬럼을 다시 확인했는데

X_train에도 X_test 둘다 동일하게 위 세개 컬럼 모두 있습니다.. ㅠㅠ

퇴근후딴짓님의 프로필 이미지
퇴근후딴짓
지식공유자

컬럼이 아니라

컬럼의 카테고리를 확인해 주세요💪

예를들면 Embarked 컬럼 안에 카테고리(종류)입니다.

df['Embarked'].value_counts() 와 같은 방식으로 확인 가능합니다. 🙂

김민정님의 프로필 이미지
김민정
질문자

선생님께서 말씀해주신 value_counts()를 봤는데.. 그럼 dtype을 봐야 하는걸까요?

저는 지금까지 계속 info로 확인해서 object컬럼 인줄 알았습니다..

 

df['Embarked'].value_counts()

S    644
C    168
Q     77
Name: Embarked, dtype: int64

 

df.info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 712 entries, 90 to 116
Data columns (total 11 columns):
 #   Column       Non-Null Count  Dtype  
---  ------       --------------  -----  
 0   PassengerId  712 non-null    int64  
 1   Pclass       712 non-null    int64  
 2   Name         712 non-null    object 
 3   Sex          712 non-null    object 
 4   Age          575 non-null    float64
 5   SibSp        712 non-null    int64  
 6   Parch        712 non-null    int64  
 7   Ticket       712 non-null    object 
 8   Fare         712 non-null    float64
 9   Cabin        170 non-null    object 
 10  Embarked     711 non-null    object 
dtypes: float64(2), int64(4), object(5)
memory usage: 66.8+ KB
None
퇴근후딴짓님의 프로필 이미지
퇴근후딴짓
지식공유자

다시 정리해드리겠습니다 🙂
위 에러는 인코딩에서 에러가 났어요 test에 train에는 없는 새로운 카테고리(종류)가 있고
인코딩한 컬럼은 cols = ['Sex', 'Ticket', 'Embarked']입니다.

sex와 embarked는 똑같고

print(X_train['Ticket'].value_counts()) 
print(X_test['Ticket'].value_counts())

했을 때 train은 565종류가 있고 test는 165종류가 있어요

차이도 큰데 test에 있는 SOTON/O.Q. 3101311 컬럼은 train에는 없습니다.

 

해결방법

  • 1: 쉽게 해결하는 방법은 일단은 Ticket 컬럼을 제거하는 방법 (입문자에게 추천)

  • 2: 합쳐서 인코딩 하는 방법

df = pd.concat([X_train, X_test])

from sklearn.preprocessing import LabelEncoder
cols = ['Sex', 'Ticket', 'Embarked']

for col in cols:
    le = LabelEncoder()
    df[col] = df[col].astype(str) # 숫자와 문자가 함께 있어 문자로 처리
    df[col] = le.fit_transform(df[col])


# 다시 분리
X_train = df.iloc[:len(X_train)]
X_test = df.iloc[len(X_train):]

 

마지막으로 타입을 확인하는 방법은 여러가지가 있지만 info로 확인하는 것이 편합니다 🙂 화이팅!!

김민정님의 프로필 이미지
김민정

작성한 질문수

질문하기