개발/머신러닝-딥러닝

2023.06.09 ML(머신러닝)의 로지스틱 회귀

상달군 2023. 6. 13. 17:02
728x90

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()

728x90