2023.06.09 ML(머신러닝)의 로지스틱 회귀
1.hr 데이터셋 살펴보기
- 데이터 살펴보기
2.로지스틱 회귀(Logistic Regression)
3.혼돈행렬(confusion matrix)
- 3-1.정밀도(precision)
- 3-2.재현율(recall)
- 3-3.f1 score
4.교차검증(Crosss Validation)
7.로지스틱 회귀.ipynb
1.hr 데이터셋 살펴보기
🎈 직원 승진 데이터셋 실습 !!
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
🔻데이터 셋 불러오기
hr_df = pd.read_csv('/content/drive/MyDrive/7.머신러닝 딥러닝/실습데이터/hr.csv')
데이터 살펴보기
- employee_id : 임의의 직원 id
- department : 부서
- region : 지역
- education : 학력
- gender : 성별
- recruitment_channel : 채용 방법
- no_of_trainings : 트레이닝 받은 횟수
- age : 나이
- previous_year_rating : 이전 년도 고과 점수
- length_of_service : 근속년수
- awards_won? : 수상 경력
- avg_training_score : 평균 고과 점수
- is_promoted : 승진여부
🔻 숫치로 확인해보기
hr_df.describe()
🗨 숫치로 보면서 이상치가 존재 하는지 확인 할 수 있다.
🔻 여러 그래프들과 칼럼을 가지고 데이터를 살펴 보겠습니다.
👀 bar그래프를 이용하여 "이전 년도 고과 점수"와 "승진여부" 확인
sns.barplot(x='previous_year_rating', y='is_promoted', data=hr_df)
👀 line그래프를 이용하여 "이전 년도 고과 점수"와 "승진여부" 확인
sns.lineplot(x='previous_year_rating', y='is_promoted', data=hr_df)
👀 line그래프를 이용하여 "평균 고과 점수"와 "승진여부" 확인
sns.lineplot(x='avg_training_score', y='is_promoted', data=hr_df)
🗨 그래프를 보니 당연하게도 점수가 높을수록 승진률이 좋네요. 90점 이상은 되어야 승진할 수 있는거 같습니다.
👀 bar그래프를 이용하여 "채용방법" 과 "승진여부"도 확인해보겠습니다.
sns.barplot(x='recruitment_channel', y='is_promoted', data=hr_df)
👀 referred의 합격이 많은 이유를 한번 보겠습니다.
# recruitment_channel(취업경로) value값을 보게 되면 다른애들보다 referred가 전체 인원 자체가 적은데 합격자가 있어서 높게 측정됨
hr_df['recruitment_channel'].value_counts()
🗨 상대적으로 referred의 인원이 적은데 승진자들이 존재 하기 때문에 높게 측정 된거 같습니다.
👀 성비도 bar그래프를 이용하여 확인해보겠습니다.
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.isna().mean()
# 2부분에 null값이존재함.
# education 0.043953
# previous_year_rating 0.075244
👀 결측값이 존재하는 education 칼럼의 값을 확인 해보겠습니다.
# 널값이 존재하는 education칼럼 확인해보기
hr_df['education'].value_counts()
🗨 이런 값들이 있군요
👀 결측값이 존재하는 previous_year_rating 칼럼의 값을 확인 해보겠습니다.
# 널값이 존재하는 칼럼 확인해보기
hr_df['previous_year_rating'].value_counts()
👀 결측값이 존재하는 모든 칼럼 삭제하기
🗨 education 칼럼과 previous_year_rating 칼럼의 결측값이 1%미만이기도 하고 우리가 가진 데이터량이 많기 때문에
저희는 결측값정도는 아에 삭제해도 된다고 판단 하였습니다.
# 둘다 1%이하 이기 때문에 데이터를 아에 삭제 해주겠습니다.
hr_df = hr_df.dropna()
👀 잘 삭제 되었는지 다시 확인 해보겠습니다.
# null값을 모두 삭제 했기 때문에 널값이 존재 하지 않음
hr_df.info()
👀 5가지의 칼럼의 고유값들의 수를 출력하기
# for문을 이용한 각 칼럼들의 데이터에 고유값들의 수를 뽑아 보겠습니다.
for i in ['department', 'region', 'education', 'gender', 'recruitment_channel']:
print(i, hr_df[i].nunique())
🔻 기계는 수치만 이해할 수 있기 때문에 수치로 변환해주는 전처리 작업을 해주겠습니다.
👀 get_dummies을 이용
hr_df = pd.get_dummies(hr_df, columns = ['department', 'region', 'education', 'gender', 'recruitment_channel'])
hr_df.head(3)
🔻전처리 완료후 이제 수치로 변환된 데이터를 가지고 학습을 위한 자료 분류를 해보겠습니다.
# 학습을 위한 자료 분류
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)
2.로지스틱 회귀(Logistic Regression)
- 둘 중의 하나를 결정하는 문제(이진분류)를 풀기 위한 대표적인 알고리즘
- 3개 이상의 클래스에 대한 판별을 하는 경우 OvR(one-vs-Rest), OvO(one-vs-one)전략으로 판별한다.
- 대부분 OvR 전략을 선호, 데이터가 한쪽으로 치우친 경우 OvO을 사용한다.
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
# 학습시키기
lr.fit(X_train, y_train)
# 모의고사
pred = lr.predict(X_test)
🔻 평가후 accuracy_score (정확도 평가)을 이용하여 정확도를 평가 해보겠습니다.
from sklearn.metrics import accuracy_score
# accuracy_score 정확도 평가
accuracy_score(y_test, pred)
🗨 정확도는 91%정도 나오네요.
👀 0은 승진실패, 1은 승진성공 값 확인
hr_df['is_promoted'].value_counts()
3.혼돈행렬(confusion matrix)
- 한쪽으로 데이터가 쏠려 있을때 기계 학습은 한쪽으로 학습하게 되는데
- 정밀도와 재현율(민감도)을 활용하는 평가용 지수
--------------------------------------------------------------------------
confusion_matrix(y_test, pred)
*결과값*
array([[8869(TN), 0(FP)],
[ 862(FN), 1(TP)]])
--------------------------------------------------------------------------
TN(8869) FP(0)
FN(862) TP(1)
--------------------------------------------------------------------------
- TN: 승진하지 못했는데, 승진하지 못했다고 예측한것
- FP: 승진했는데, 승진하지 못했다고 예측한것
- FN: 승진하지 못했는데, 승진했다고 예측한것(노력했다가 틀린것)
- TP: 승진했는데, 승진했다고 예측한것
어느 한쪽으로 쏠려 학습하지 않았음 !
🔻0과 1의 서로의 연관 관계를 한눈에 볼 수 있음.
👀 참거짓, 합격불합격등 이진분류를 한눈에 보기 편함 .
# 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
- 정밀도와 재현율의 조화평균을 나타내는 지표
👀precision_score, recall_score, f1_score 을 확인해보겠습니다.
from sklearn.metrics import precision_score, recall_score, f1_score
✔3-1.정밀도(precision)
precision_score(y_test, pred)
✔3-2.재현율(recall)
recall_score(y_test, pred)
✔3-3.f1 score
f1_score(y_test, pred)
🔻 coef_를 이용하여 컬럼에 대한 기울기 구하기
# coef_ : 프로퍼티 58개 컬럼에 대한 기울기...
lr.coef_
🔻 58개의 컬럼이 맞는지 확인 해보겠습니다.
🗨 58개의 컬럼이 맞네요
🔻 독립변수 2개와 종속 변수 1개를 가지고 학습 하고 예측 해보겠습니다.
# 독립변수 2개와 종속변수 1개
TempX = hr_df[['age', 'length_of_service']]
tempy = hr_df['is_promoted']
👀 LogisticRegression 객체 생성
temp_lr = LogisticRegression()
👀학습 시키기
temp_lr.fit(TempX, tempy)
👀테스트 할 데이터 만들기
temp_df = pd.DataFrame({'age': [20,27,30], 'length_of_service':[1,3,6]})
🗨 데이터 프레임
👀LogisticRegression 객체에 우리가 만든 테스트 데이터 넣어 예측해보기
pred = temp_lr.predict(temp_df)
👀 coef_ 을 이용하여 기울기 구하기
temp_lr.coef_
👀 intercept_을 이용하여 절편 구하기.
temp_lr.intercept_
proba = temp_lr.predict_proba(temp_df)
proba
4.교차검증(Crosss Validation)
- train_test_split에서 발생하는 데이터의 섞임에 따라 성능이 좌우되는 문제를 해결하기 위한 기술
- K겹(K-Fold) 교차 겸증을 가장 많이 사용한다.
from sklearn.model_selection import KFold
#객체 생성
kf= KFold(n_splits=5)
for train_index, test_index in kf.split(range(len(hr_df))):
print(train_index, test_index)
print(len(train_index), len(test_index))
🗨 객채 생성을 다시 해줍니다.
kf= KFold(n_splits=5, random_state=10, shuffle=True)으로 값변경후 섞어줍니다.
kf= KFold(n_splits=5, random_state=10, shuffle=True)
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 = []
# 5바퀴 돌아서 테스트 한걸 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']
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)# 예측
acc_list.append(accuracy_score(y_test, pred)) # acc_list리스트에 값을 저장
# 정확도의 평균
np.array(acc_list).mean()