특성공학 : 새로운 컬럼을 추가해보자
- Parch, Sibsp 를 더하면 가족의 수가 됨 -> 가족의 수라는 새 컬럼 추가
- train에 추가하면 test도 동일하기 추가해야 함
- 나 자신을 더해줘야 하기 때문에 +1
# train
train['Family_Size'] = train['Parch'] + train['SibSp'] + 1
# test
test['Family_Size'] = test['Parch'] + test['SibSp'] + 1
test.info()
train.info()
Family_Size를 이용해 데이터 시각화
sns.countplot(data = train, x = 'Family_Size', hue = 'Survived')
# 1일때는 사망율이 높고, 2~4명일때는 생존율이 높고, 5~ 사망율이 높아짐
# 사소한 관찰의 오류를줄이기 위해서 범주의 크기를 줄여보자
- 가족의 수가 1이면 Alone, 2-4면 Small, 5~ Large
- train, test 동일하게 변경
bins = [0,1,4,11] #구간
# 0초과 ~1, 2~4, 5~ 11
labels = ['Alone','Small','Large'] # 구간에 대한 이름
train['Family_Size']= pd.cut(train['Family_Size'], bins = bins, labels = labels)
test['Family_Size']= pd.cut(test['Family_Size'], bins = bins, labels = labels)
train
test
구간이 설정된 Family_Size를 이용해 데이터 시각화
sns.countplot(data = train, x = 'Family_Size', hue = 'Survived')
Text 데이터 다뤄보기
- Name 컬럼 사용해보기 : 중간 호칭 추출
1. 사용자 정의 함수 : 문자열 호칭 추출하는 기능 만들어보자
- 성 추출한 후 Title 이라는 컬럼에 담아주기
def split_title(s):
return s.split(',')[1].split('.')[0].strip()
train['Title'] = train['Name'].apply(split_title)
test['Title'] = train['Name'].apply(split_title)
train을 확인 해 보면 Title에 호칭이 잘 들어간 것을 확인할 수 있다.
Title 데이터 시각화 해보기
plt.figure(figsize=(15,5))
sns.countplot(data = train, x = 'Title', hue = 'Survived')
# Mr 미스터 : 남성, 결혼유무 상관없음
# Master : 결혼하지 않은 남성, 주로 청소년 이하
# Ms 미즈 : 여성, 결혼유무 상관없음
# Miss 미스 : 결혼 안한 여성
# Mrs 미스즈 : 결혼한 여성
# Rev 목사님 : 다 돌아가심 !
의미없는 데이터 정리를 위해 호칭 범주 정하기
train['Title'].unique().size
# 호칭의 개수 정리해보기
title = ['Mr', 'Mrs', 'Miss', 'Master','Rev','Don','Dr', 'Mme', 'Ms',
'Major', 'Lady', 'Sir', 'Mlle', 'Col', 'Capt', 'the Countess',
'Jonkheer']
len(title)
# 변환될 호칭 정리
cvt_title = ['Mr', 'Mrs', 'Miss', 'Master','Rev'] + ['Other']*12
cvt_title
# zip 함수 - 같은 위치에 있는 요소끼리 묶어줌
title_dict = dict(zip(title, cvt_title))
train['Title'] = train['Title'].map(title_dict)
test데이터도 동일하게 정리해주자
test['Title'].unique()
train 데이터에는 존재하지 않는 'Dona'라는 호칭이 존재한다.
Dona도 title_dict 내에 'Other로 추가해주자'
title_dict['Dona'] = 'Other'
test['Title'] = test['Title'].map(title_dict)
test['Title']
잘 바뀐것을 확인할 수 있다.
불필요한 컬럼 삭제
train.columns
Name과 Ticket 컬럼은 불필요하므로 삭제한다
axis = 1 열을 기준으로 (Name과 Ticket은 컬럼이므로)
inplace =True : 실제 데이터 변수에 반영(초기화)
train.drop(['Name','Ticket'],axis =1, inplace = True)
test.drop(['Name','Ticket'],axis =1, inplace = True)
train.info()
test.info()
문제, 답으로 분리
x_train = # 훈련용 문제 -> fit 데이터에 맞춰서 학습할 때 사용
y_train = # 훈련용 답 -> fit 데이터에 맞춰서 학습할 때 사용
x_test = # 테스트 용 문제 -> predict 예측할 때 사용
x_train = train.drop('Survived', axis = 1)
y_train = train['Survived']
x_test = test
print('훈련용 문제:',x_train.shape)
print('훈련용 답 :',y_train.shape)
print('테스트용 문제 :' ,x_test.shape)
특성 값 수치화 : 인코딩
- 성별, 호칭 같이 값이 크고 작음에 의미가 없을 때 사용하는 인코딩 : 원핫인코딩
예시
pd.get_dummies(train['Sex'], prefix = 'Sex')
prefix = '앞에 붙일 이름'
범주형 데이터 선택하여 인코딩적용
cat_feature = ['Sex','Embarked','Cabin','Family_Size','Title']
for cat_name in cat_feature :
dummy = pd.get_dummies(train[cat_name], prefix = cat_name)
# 기존 x_train에 병합 / 열기준이므로 axis = 1
x_train = pd.concat([x_train,dummy], axis = 1)
# 기존의 컬럼은 삭제 / 반영시키기
x_train.drop(cat_name, axis = 1, inplace = True)
조회해보면 28개의 컬럼이 추가된 것을 확인할 수 있다.
test도 똑같이 적용해주자
for cat_name in cat_feature :
dummy = pd.get_dummies(test[cat_name], prefix = cat_name)
# 기존 x_train에 병합
x_test = pd.concat([x_test,dummy], axis = 1)
# 기존의 컬럼은 삭제
x_test.drop(cat_name, axis = 1, inplace = True)
x_train 데이터는 28개, x_test는 27개인것이 확인되는데
set 집합을 이용해 빠진 컬럼을 찾아보자
set(x_train.columns) - set(x_test.columns)
Cabin_T가 없는것을 확인할 수 있다.
x_test에 Cabin_T 컬럼을 추가하고 data는 모두 0으로 넣어주자
x_test['Cabin_T'] = 0
머신러닝을 위해서 컬럼의 순서를 맞춰주자
x_test = x_test[x_train.columns]
모델 선택 및 학습
# 분류 예측기와 교차검증 도구 import
- 교차 검증 : tree모델의 성능은 어느정도 될지 확인하는 방법
from sklearn.tree import DecisionTreeClassifier # 분류 예측기
from sklearn.model_selection import cross_val_score # 교차검증 도구
# 일반화 성능 측정
tree_model = DecisionTreeClassifier()
# 범위 : 1.0 ~ 0.0
# 1.0으로 가까워 질수록 정확도가 높아짐
# cv : 교차 검증 횟수 -> 일반적으로 3~5번이 디폴트
result = cross_val_score(tree_model, x_train, y_train, cv = 5)
print("결과 : " , result)
print('평균 : ' , result.mean())
과대적합 : 모델의 깊이가 깊어지면 규칙이 많아짐 -> 모델이 복잡해짐 -> 성능 ↓
- 방지하기 위해 모델의 깊이를 설정할 수 있는 max_depth 존재
# train에 대한 성능은 좋을 수 있지만, test에 대한 성능 떨어질 확률이 높음
# -> 과대적합
# train에 대한 성능도 떨어지고, test에 대한 성능도 현저히 떨어질 확률이 높음
# -> 과소적합
# 머신러닝의 궁극적인 목표
# 과대, 과소가 아닌 일반화 학습이 잘 된 모델을 찾는 것 -> 일반화 모델
방금 전의 tree_model은 max_depth가 none으로 설정 돼 있기 때문에 성능이 떨어졌다고 볼 수 있음
max_depth의 깊이를 5로 설정 해 주자
tree_model = DecisionTreeClassifier(max_depth = 5)
result2 = cross_val_score(tree_model, x_train, y_train, cv = 5)
print("결과 : " , result2)
print('평균 : ' , result2.mean())
전보다 평균이 더 높아진 것을 확인할 수 있다.
학습
# fit() 모델 학습
- 데이터에 맞춰서 모델이 학습함
- 사용방법 : tree_model.fit(훈련용 문제, 훈련용 답)
tree_model.fit(x_train, y_train)
보통
# X 대문자 사용하는 이유 : 컬럼의 개수가 많음
# y 소문자 사용하는 이유 : 컬럼이 1개
모델 예측 및 평가(Kaggle 업로드)
- 답을 가지고 있지 않기 때문에 kaggle에 올려서 정확도를 확인해보자
pre = tree_model.predict(x_test)
pre
답안지 파일 불러오기
result = pd.read_csv('./titanic/gender_submission.csv')
result['Survived'] = pre
result
답안지 파일을 불러온 후 답안지 파일에 방금 예측한 답을 넣어주자
다시 csv 파일로 저장
- 변수명.to_csv('경로 및 파일명')
index없이 저장하기 위해 index = False 사용
result.to_csv('./titanic/submission01_wj.csv',index = False)
답이 있을 때 평가하는 방법!
# 1.
tree_model.score(x_test, y_test) # 분류 성능 평가 지표 - accuracy 정확도
# 2.
from sklearn.metrics import accuracy_score # 정확도 도구
# accuracy_score(pred,y_test) # 분류 성능평가 지표 - accuracy 정확도
'Machine Learning' 카테고리의 다른 글
[Machine Learning] Colab사용 OpenCV 실습 (0) | 2022.07.20 |
---|---|
[Machine Learning] 손글씨데이터 활용 분류 실습 (0) | 2022.07.20 |
[Machine Learning] 타이타닉 데이터 활용하여 생존/사망 분류 실습01 (0) | 2022.07.19 |
[Machine Learning] Pandas와 Matplotlib을 사용해서 카카오톡 대화 전처리 실습 (0) | 2022.07.12 |