다음은 펭귄 데이터를 이용하여 빅데이터 분석기사에서 활용할 수 있는 전처리에 대해 설명하고자 합니다.
# 작업 유형2 - 데이터 전처리
# 펭귄 데이터를 이용해서 전처리
import seaborn as sns
df = sns.load_dataset('penguins')
print(df.head())
# 결과
species island bill_length_mm bill_depth_mm flipper_length_mm \
0 Adelie Torgersen 39.1 18.7 181.0
1 Adelie Torgersen 39.5 17.4 186.0
2 Adelie Torgersen 40.3 18.0 195.0
3 Adelie Torgersen NaN NaN NaN
4 Adelie Torgersen 36.7 19.3 193.0
body_mass_g sex
0 3750.0 Male
1 3800.0 Female
2 3250.0 Female
3 NaN NaN
4 3450.0 Female
df.isna().sum() # isna를 통해 데이터셋에 결측치가 있는지 확인하고 sum을 통해 합계를 보여준다
# 결과
species 0
island 0
bill_length_mm 2
bill_depth_mm 2
flipper_length_mm 2
body_mass_g 2
sex 11
dtype: int64
이후 결측치가 존재하는 열을 확인한 후 missing이라는 배열에 담아 결측치를 중앙값으로 채워넣는다.
#1. 결측치 제거
missing = ['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g'] # 결측치 존재 열
for i in missing:
df[i] = df[i].fillna(df[i].median()) # 중앙값으로 다 채워넣음
df['sex'] = df['sex'].fillna('Male') # 성별과 같은 범주형의 경우 비중이 높은 남성으로 입력
df
# 결과
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex
0 Adelie Torgersen 39.10 18.7 181.0 3750.0 Male
1 Adelie Torgersen 39.50 17.4 186.0 3800.0 Female
2 Adelie Torgersen 40.30 18.0 195.0 3250.0 Female
3 Adelie Torgersen 44.45 17.3 197.0 4050.0 Male
4 Adelie Torgersen 36.70 19.3 193.0 3450.0 Female
... ... ... ... ... ... ... ...
339 Gentoo Biscoe 44.45 17.3 197.0 4050.0 Male
340 Gentoo Biscoe 46.80 14.3 215.0 4850.0 Female
341 Gentoo Biscoe 50.40 15.7 222.0 5750.0 Male
342 Gentoo Biscoe 45.20 14.8 212.0 5200.0 Female
343 Gentoo Biscoe 49.90 16.1 213.0 5400.0 Male
344 rows × 7 columns
이후 사이킷런 패키지의 LabelEncoder를 불러와 수치형이 아닌 변수들을 지도학습을 편리하게 하기 위해 수치형으로 다 라벨링을 해준다.
#2. 라벨 인코딩
from sklearn.preprocessing import LabelEncoder
label = ['species', 'island', 'sex'] # 수치형이 아닌 변수들을 수치로 라벨링 해줌
df[label] = df[label].apply(LabelEncoder().fit_transform) # apply 함수로 리스트화 되어 있는 변수들의 라벨인코딩
df
# 결과
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex
0 0 2 39.10 18.7 181.0 3750.0 1
1 0 2 39.50 17.4 186.0 3800.0 0
2 0 2 40.30 18.0 195.0 3250.0 0
3 0 2 44.45 17.3 197.0 4050.0 1
4 0 2 36.70 19.3 193.0 3450.0 0
... ... ... ... ... ... ... ...
339 2 0 44.45 17.3 197.0 4050.0 1
340 2 0 46.80 14.3 215.0 4850.0 0
341 2 0 50.40 15.7 222.0 5750.0 1
342 2 0 45.20 14.8 212.0 5200.0 0
343 2 0 49.90 16.1 213.0 5400.0 1
344 rows × 7 columns
이후 데이터를 변환해주는데 정수형을 카테고리형으로 변경해준다.
#3. 데이터 변환, 더미
import pandas as pd
category = ['island', 'sex']
for i in category:
df[i] = df[i].astype('category') # 정수형을 카테고리형으로 변경
df = pd.get_dummies(df) # 더미변수로 변환
df
# 결과
species bill_length_mm bill_depth_mm flipper_length_mm body_mass_g island_0 island_1 island_2 sex_0 sex_1
0 0 39.10 18.7 181.0 3750.0 0 0 1 0 1
1 0 39.50 17.4 186.0 3800.0 0 0 1 1 0
2 0 40.30 18.0 195.0 3250.0 0 0 1 1 0
3 0 44.45 17.3 197.0 4050.0 0 0 1 0 1
4 0 36.70 19.3 193.0 3450.0 0 0 1 1 0
... ... ... ... ... ... ... ... ... ... ...
339 2 44.45 17.3 197.0 4050.0 1 0 0 0 1
340 2 46.80 14.3 215.0 4850.0 1 0 0 1 0
341 2 50.40 15.7 222.0 5750.0 1 0 0 0 1
342 2 45.20 14.8 212.0 5200.0 1 0 0 1 0
343 2 49.90 16.1 213.0 5400.0 1 0 0 0 1
이후 파생변수를 통해 qcut으로 분위수를 계산한 뒤 이를 기반으로 이산화를 수행해준다. 이 경우 구간은 5개로 설정해주었고 labels를 False로 해주어야 올바르게 값이 열에 들어가게 된다.
#4. 파생변수
# qcut으로 특정변수의 분위수를 계산하여 이를 기반으로 이산화 수행
# 구간은 5개
df['body_mass_g_qcut'] = pd.qcut(df['body_mass_g'],5, labels=False)
df.head()
# 결과
species bill_length_mm bill_depth_mm flipper_length_mm body_mass_g island_0 island_1 island_2 sex_0 sex_1 body_mass_g_qcut
0 0 39.10 18.7 181.0 3750.0 0 0 1 0 1 1
1 0 39.50 17.4 186.0 3800.0 0 0 1 1 0 1
2 0 40.30 18.0 195.0 3250.0 0 0 1 1 0 0
3 0 44.45 17.3 197.0 4050.0 0 0 1 0 1 2
4 0 36.70 19.3 193.0 3450.0 0 0 1 1 0 0
스케일을 통해 fit, transform을 해준다. 이때 사이킷런 패키지의 MinMaxScaler를 통해 fit, transform을 한다. MinMaxScaler외에도 PCA클래스, Feature Vectorization 클래스등 여러가지가 있지만 이 경우 MinMaxScaler를 사용해준다.
#5. 스케일
# 스케일할 변수를 리스트화
# fit하고 transform을 통해 스케일 변환 진행
from sklearn.preprocessing import MinMaxScaler
scaler = ['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g']
min = MinMaxScaler()
min.fit(df[scaler])
df[scaler] = min.transform(df[scaler])
df
# 결과
species bill_length_mm bill_depth_mm flipper_length_mm body_mass_g island_0 island_1 island_2 sex_0 sex_1 body_mass_g_qcut
0 0 0.254545 0.666667 0.152542 0.291667 0 0 1 0 1 1
1 0 0.269091 0.511905 0.237288 0.305556 0 0 1 1 0 1
2 0 0.298182 0.583333 0.389831 0.152778 0 0 1 1 0 0
3 0 0.449091 0.500000 0.423729 0.375000 0 0 1 0 1 2
4 0 0.167273 0.738095 0.355932 0.208333 0 0 1 1 0 0
... ... ... ... ... ... ... ... ... ... ... ...
339 2 0.449091 0.500000 0.423729 0.375000 1 0 0 0 1 2
340 2 0.534545 0.142857 0.728814 0.597222 1 0 0 1 0 3
341 2 0.665455 0.309524 0.847458 0.847222 1 0 0 0 1 4
342 2 0.476364 0.202381 0.677966 0.694444 1 0 0 1 0 4
343 2 0.647273 0.357143 0.694915 0.750000 1 0 0 0 1 4
이후 데이터를 지도학습 시키기 위하여 train셋과 test셋으로 나누어준다. 이때 test_size는 0.2로 20%만 test셋으로 나누고 random_state경우 1을 기준으로 진행하였다.
# 6. 데이터 분리
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df.iloc[:, 1:], df['species'],
test_size=0.2, stratify=df['species'], random_state=1)
print('x_train', X_train.shape)
print('x_test', X_test.shape)
print('y_train', y_train.shape)
print('y_test', y_test.shape)
# 결과
x_train (275, 10)
x_test (69, 10)
y_train (275,)
y_test (69,)
이후 모형학습을 해주는데 여러가지 방법이 있다. 랜덤포레스트, 에이다 부스트, k-최근접 이웃 알고리즘 등이 있다.
#7. 모형학습
# 랜덤포레스트 분류모형
from sklearn.ensemble import RandomForestClassifier
model1 = RandomForestClassifier(max_depth=6, n_estimators=100)
model1.fit(X_train, y_train)
pred1 = model1.predict(X_test)
# 에이다 부스트 분류모형
from sklearn.ensemble import AdaBoostClassifier
model2 = AdaBoostClassifier()
model2.fit(X_train, y_train)
pred2 = model2.predict(X_test)
#8. 앙상블
# 보팅은 hard 투표기반으로 진행, clf에 할당
# 훈련용 데이터를 입력하여 clf 핏
# 테스트 데이터를 입력하여 pred3에 할당
from sklearn.ensemble import VotingClassifier
clf = VotingClassifier(estimators=[('rf', model1), ('ad', model2)],voting='hard')
clf.fit(X_train, y_train)
pred3 = clf.predict(X_test)
모형학습을 다 끝낸 뒤 모형평가를 통해 어떤 모형이 가장 정확도가 높았는지 평가를 해준다.
#9. 모형평가
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
print('랜포 정확도' ,accuracy_score(y_test, pred1))
print('아이다 정확도', accuracy_score(y_test, pred2))
print('보팅 정확도', accuracy_score(y_test, pred3))
# 결과
랜포 정확도 1.0
아이다 정확도 0.9855072463768116
보팅 정확도 1.0
#10. 하이퍼파라미터 튜닝
# 그리드 서치를 위한 파라미터 범위지정, parameters 변수에 할당
# 기본적인 랜덤포레스트 모형 만들고, 그리드서치를 통해 최적의 파라미터 추정
# print함수를 통해 학습된 모형의 최적의 하이퍼파라미터를 best_params_함수로 출력
from sklearn.model_selection import GridSearchCV
parameters = {'n_estimators':[50, 100], 'max_depth':[4,6]}
model4 = RandomForestClassifier()
clf = GridSearchCV(estimator=model4, param_grid=parameters, cv=3)
clf.fit(X_train, y_train)
print('최적의 파라미터', clf.best_params_) # {'max_depth': 6, 'n_estimators': 100}
제출을 위해 파일을 저장한 뒤 read_csv를 통해 제대로 저장이 되었는지 확인해준다.
#11. 파일저장
# y_test의 index를 id로 pred3을 pred열로 하는 데이터프레임 만들고 csv로 저장
# index = False로 함, True시에 인덱스가 추가로 생성
pd.DataFrame({'id': y_test.index, 'pred': pred3}).to_csv('003000000.csv', index=False)
check = pd.read_csv('003000000.csv')
check.head()
# 결과
id pred
0 57 0
1 173 1
2 213 1
3 50 0
4 25 0
'데이터분석' 카테고리의 다른 글
티스토리에 GA연동(구글 애널리틱스) (0) | 2023.01.09 |
---|---|
빅데이터분석기사 작업형 유형 1 문제 모음 (0) | 2022.08.09 |