📄 예제에 사용한 파일
1. hr 데이터셋 살펴보기
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from google.colab import drive
hr_df = pd.read_csv('/content/drive/MyDrive/KDT/Python/4.머신러닝 딥러닝/hr.csv')
hr_df.head()
✅ 데이터셋 정보 알아보기
hr_df.info()
✅ 데이터셋의 수치형 데이터 정보 알아보기
hr_df.describe()
✅ 작년의 고과점수와 승진 확률에 대해 시각화하여 알아보기
sns.barplot(x='previous_year_rating', y='is_promoted', data=hr_df)
✅ 평균고과점수와 승진 확률에 대해 시각화하여 알아보기
sns.lineplot(x='avg_training_score', y='is_promoted', data=hr_df)
✅ 채용방법과 승진확률에 대해 시각화하여 알아보기
sns.barplot(x='recruitment_channel', y='is_promoted', data=hr_df)
✅ 중복값을 제외한 채용방법의 종류와 수 알아보기
hr_df['recruitment_channel'].value_counts()
✅ 성별에 따른 승진확률에 대해 알아보기
sns.barplot(x='gender', y='is_promoted', data=hr_df) # 여자인 데이터의 수가 적기 때문에 승진 비율을 더 높아보임(오차 확률이 높음)
✅ 중복값을 제외한 성별의 종류와 개수 알아보기
hr_df['gender'].value_counts()
✅ 부서에 따른 승진 확률 알아보기
sns.barplot(x='department', y='is_promoted', data=hr_df)
plt.xticks(rotation=45)
✅ 중복값을 제외한 부서 종류와 개수 알아보기
hr_df['department'].value_counts()
✅ 지역에 따른 승진 확률 알아보기
plt.figure(figsize=(15,10))
sns.barplot(x='region', y='is_promoted', data=hr_df)
plt.xticks(rotation=45)
✅ 결측지 알아보기
hr_df.isna().sum()
✅ 학력 컬럼에 중복값을 제외한 데이터의 종류와 개수 알아보기
hr_df['education'].value_counts()
✅ 전년도 고과 점수의 중복값 제외 데이터 종류와 개수 알아보기
hr_df['previous_year_rating'].value_counts()
✅ NaN 데이터 삭제하기
hr_df = hr_df.dropna() # NaN인 데이터가 미비하기 때문에 삭제
✅ NaN값 알아보기
hr_df.isna().sum()
✅ object형 컬럼 알아보기
for i in ['department', 'region','education','gender','recruitment_channel']:
print(i, hr_df[i].nunique())
✅ object형 데이터들의 유니크한 값들의 수 알아보기(원핫인코딩을 위해)
for i in ['department', 'region','education','gender','recruitment_channel']:
print(i, hr_df[i].nunique())
✅ 원 핫 인코딩 하기
hr_df = pd.get_dummies(hr_df, columns=['department', 'region','education','gender','recruitment_channel'])
hr_df.head()
✅ 학습 데이터와 검증 데이터 분리하기
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(hr_df.drop('is_promoted', axis=1), hr_df['is_promoted'], test_size=0.2, random_state=10)
X_train.shape, X_test.shape
>>> ((38928, 58), (9732, 58))
y_train.shape, y_test.shape
>>> ((38928,), (9732,))
2. 로지스틱 회귀(Logistic Regression)
- 둘 중 하나를 결정하는 문제(이진 분류)를 풀기 위한 대표적인 알고리즘
- 3개 이상의 클래스에 대한 판별을 하는 경우 OvR(One-vs-Rest), OvO(One-vs-One) 전략으로 판별
- one-vs-rest(OvR): K개의 클래스가 존재할 때, 1개의 클래스를 제외한 다른 클래스를 K개 만들어, 각각의 이진 분류에 대한 확률을 구하고, 총합을 통해 최종 클래스를 판별
- one-vs-one(OvO): 4개의 계정을 구분하는 클래스가 존재한다고 할 때, 0vs1, 0vs2, 0vs3,...,2vs3까지의 NX(N-1)/2개의 분류기를 만들어 가장 많이 양성으로 선택된 클래스를 판별
대부분 OvR전략을 선호, 데이터가 한쪽으로 많이 치우친 경우 OvO을 사용
# 모델 불러오기
from sklearn.linear_model import LogisticRegression
# 모델 객체 생성
lr = LogisticRegression()
# 학습
lr.fit(X_train, y_train)
# 예측
pred = lr.predict(X_test)
2-1. accuracy_score
from sklearn.metrics import accuracy_score, confusion_matrix
accuracy_score(y_test, pred)
>>> 0.9114262227702425
📍 약 91.14%의 정답률, 분류 문제에 있어서 accuracy_score는 신빙성이 떨어짐(데이터가 한쪽으로 치우친 경우 치우친 쪽으로 판단할 가능성이 높음)
hr_df['is_promoted'].value_counts()
📍 이진분류 ➡ 데이터가 한쪽으로 치우쳤기 때문에 평가용 지표를 accuracy_score을 쓰는것 보다 confusion_matrix를 쓰는 것이 좋음
2-2. confusion_matrix
- 정밀도와 재현율(민감도)을 활용하는 평가용 지표
- TN: 승진하지 못했는데 승진하지 못했다고 예측
- FN: 승진하지 못했는데 승진했다고 예측
- FP: 승진했는데 승진하지 못했다고 예측
- TP: 승진했는데 승진했다고 예측
confusion_matrix(y_test, pred)
✅ heatmap으로 연관관계 알아보기
sns.heatmap(confusion_matrix(y_test, pred), annot=True, cmap='Blues')
3-1. 정밀도(precision)
- TP / (TP + FP)
- 무조건 양성으로 판단해서 계산하는 방법
- 실제 1인 것중에 얼마 만큼을 제대로 맞추었는가에 대한 퍼센티지(%)
3-2. 재현율(recall)
- TP / (TP+FN)
- 정확하게 감지한 양성 샘플의 비율
- 1이라고 예측한 것 중, 얼마 만큼을 제대로 맞추었는가에 대한 퍼센티지(%)
- 민감도 또는 TPR(True Positive Rate)라고도 부름
3-3. f1 score
- 정밀도와 재현율의 조화 평균을 나타내는 지표
from sklearn.metrics import precision_score, recall_score, f1_score
# 정밀도
precision_score(y_test, pred)
>>> 1.0
# 재현율
recall_score(y_test, pred)
>>> 0.0011587485515643105
# f1 score
f1_score(y_test, pred)
>>> 0.0023148148148148147
lr.coef_
X_train
# 독립변수 2개, 종속변수 1개
# 임의의 데이터를 만들어 평가지표를 활용하여 보자.
TempX = hr_df[['age', 'length_of_service']]
tempY = hr_df['is_promoted']
# 모델 객체 생성
temp_lr = LogisticRegression()
# 학습
temp_lr.fit(TempX, tempY)
# 데이터프레임으로 보기
temp_df = pd.DataFrame({'age':[20, 27, 35], 'length_of_service':[1, 3, 7]})
temp_df
# 학습에 대한 예측
pred = temp_lr.predict(temp_df)
pred
>>> array([0, 0, 0]) # 승진을 다 못했다고 예측
#age, length_of_service에 대한 기울기값
temp_lr.coef_
# y절편값
temp_lr.intercept_ # y절편값
📍 분류 예측 식
y = -0.01074458x2 + -0.00053409x2 + (-1.96818509)
proba = temp_lr.predict_proba(temp_df)
proba
4. 교차 검증(Cross Validation)
- train_test_split 에서 발생하는 데이터의 섞임에 따라 성능이 좌우되는 문제를 해결하기 위한 기술
- K겹 교차 검증(K-Fold)을 가장 많이 사용
✅ 교차검증 원리
1. 데이터 세트를 k개의 동일한 크기로 나눔. 이때, 각각의 부분 집합을 "fold"라고 함
2. 첫 번째 fold를 검증 세트로 선택하고 나머지 k-1개의 fold를 훈련 세트로 사용하여 모델을 학습
3. 모델을 검증 세트에서 평가하고 성능 지표를 기록
4. 다음 fold를 검증 세트로 선택하고 나머지 fold를 훈련 세트로 사용하여 모델을 다시 학습
5. 위 과정을 k번 반복하고, 각 반복에서 얻은 성능 지표들의 평균을 계산하여 최종 성능 평가를 얻습니다.
from sklearn.model_selection import KFold
# 데이터셋을 5개로 나눔
Kf = KFold(n_splits=5)
Kf
>>> KFold(n_splits=5, random_state=None, shuffle=False)
hr_df
# hr_df의 K-fold 개수(5개)만큼 돌면서 train_index와 test_index를 split하기
for train_index, test_index in Kf.split(range(len(hr_df))):
print(train_index, test_index)
print(len(train_index), len(test_index)) # 차례대로 나눔(shuffle X, random_state X)
✅ 하이퍼 파라미터 튜닝
# 데이터셋을 5개로 나눔, 하이퍼파라미터 튜닝 -> 데이터를 고루 섞어줌
Kf = KFold(n_splits=5, random_state=10, shuffle=True)
# hr_df의 K-fold 개수(5개)만큼 돌면서 train_index와 test_index를 split하기
for train_index, test_index in Kf.split(range(len(hr_df))):
print(train_index, test_index)
print(len(train_index), len(test_index)) # 데이터가 섞여서 나누어짐
✅ 예측 정확도 알아보기
acc_list = []
for train_index, test_index in Kf.split(range(len(hr_df))):
X = hr_df.drop('is_promoted', axis=1)
y = hr_df['is_promoted']
# K겹으로 나눈 데이터셋을 학습데이터와 test 데이터로 나누어줌
X_train = X.iloc[train_index]
X_test = X.iloc[test_index]
y_train = y.iloc[train_index]
y_test = y.iloc[test_index]
# 학습
lr = LogisticRegression()
lr.fit(X_train, y_train)
# 예측
pred = lr.predict(X_test)
# 예측값에 대힌 accuracy_score을 계산하고 acc_list에 담음
acc_list.append(accuracy_score(y_test, pred))
# 한 번 학습시킬때마다의 accuracy_score - 데이터가 어떻게 섞이냐에 따라 성능도 달라짐
acc_list
>>>
[0.9114262227702425,
0.9094739005343198,
0.9173859432799013,
0.914406083025072,
0.9125565145910398]
# 정확도의 평균
np.array(acc_list).mean()
>>> 0.913049732840115
Cross Validation을 사용하는 이유는 결과를 좋게 하기 위함이 아니라 믿을만한 학습 모델인지를 평가하기 위함
(데이터로 인한 모델의 신뢰도)
'Python > ML&DL' 카테고리의 다른 글
[파이썬, Python] 머신러닝 - 5️⃣ 랜덤 포레스트(Random Forest) (0) | 2023.06.18 |
---|---|
[파이썬, Python] 머신러닝 - 4️⃣ 서포트 벡터 머신(Support Vector Machine) (0) | 2023.06.18 |
[파이썬, Python] 머신러닝 - 2️⃣ 의사결정나무(Decision Tree) (2) | 2023.06.14 |
[파이썬, Python] 머신러닝 - 1️⃣ 선형 회귀(Linear Regression) (0) | 2023.06.14 |
[파이썬, Python] 머신러닝을 위한 데이터 전처리 연습하기! (0) | 2023.06.14 |