[ML] 사이킷런(scikit-learn)으로 와인 분류하기 - 로지스틱회귀(Logistic Regression)
사이킷런의 와인 분류 데이터셋을 사용하여 로지스틱 회귀 분석을 한다.
1. 라이브러리 및 데이터 로드
# 필요한 라이브러리
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import pandas as pd
# 필요한 데이터
wine_data = load_wine()
2. 데이터 정보 확인하기
# 데이터 셋 정보 확인
print(wine_data.DESCR)
📍 위 코드에 대한 출력 결과(일부만 가져옴)
3. 입력변수, 출력변수 지정
# 입력 변수를 dataframe으로 변환하여 저장
x = pd.DataFrame(wine_data.data, columns=wine_data.feature_names)
# 출력 변수를 dataframe으로 변환하여 저장
y = pd.DataFrame(wine_data.target, columns=['class'])
📍 입력변수와 출력변수의 head 출력 결과
4. 학습, 테스트 데이터 나누기
# 학습, 테스트용 데이터셋 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
학습 데이터셋은 80%, 테스트 데이터셋은 20%로 데이터를 나누고 random_state
를 42로 설정하여 데이터 분배 결과를 고정할 수 있도록 한다.
# 잘 나누어졌는지 shape로 확인
print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)
출력 결과
(142, 13) (36, 13) (142, 1) (36, 1)
3. 모델링 및 평가
# 로지스틱 회귀 함수 사용
model = LogisticRegression(solver='saga', max_iter=1000)
# 학습 데이터로 모델 학습
model.fit(x_train, y_train)
# 학습이 완료된 모델에 테스트 데이터를 입력하여 y값을 예측
y_predict = model.predict(x_test)
# 분류가 잘 이루어졌는지 평가
model.score(x_test, y_test)
max_iter를 1000으로 설정했을 때의 성능
0.8611111111111112
출력할 클래스가 3개라는 점에서 다항 로지스틱 회귀에 맞는 솔버인 ‘saga’를 선택하고 최적화를 찾기 위해 과정을 몇번을 반복할 것인가(max_iter)는 1000으로 설정하여 모델을 만들어보았다. 모델 결과 성능이 약 86% 정도가 나왔는데, 이는 10개 중 8.6개가 정답으로 맞춘다는 뜻이다.
4. 반복 횟수 조정
max_iter 값을 조정하였을 때 성능을 높일 수 있는지 확인하기 위해 max_iter 값을 이전의 2배로 설정하여 모델을 만들어보았다.
# max_iter 를 2000으로 설정한 모델
model2 = LogisticRegression(solver='saga', max_iter=2000)
# 학습 데이터로 모델 학습
model2.fit(x_train, y_train)
# 학습이 완료된 모델에 테스트 데이터를 입력하여 y값을 예측
y_predict = model2.predict(x_test)
# 분류가 잘 이루어졌는지 평가
model2.score(x_test, y_test)
max_iter를 2000으로 설정했을 때의 성능
0.8888888888888888
max_iter를 2배로 설정(1000 -> 2000)하니 성능이 약 89%로 이전 대비 성능이 3%가 올랐다. max_iter 값을 5000으로 설정한 결과도 확인해보니 성능이 100%가 나왔다. 사이킷런에서 로지스틱 회귀 모델을 만들 때, max_iter 값을 높게 설정해도 그 전에 최적화가 이루어지면 과정을 stop 하도록 설계했다고 한다.
5. 결과 해석
(1) 클래스별 확률
.predict()
를 사용하면 입력변수에 대한 결과를 예측한 값을 확인할 수 있고 .predict_proba()
를 사용하면 입력변수에 대한 결과를 클래스별 확률값으로 확인할 수 있다.
첫 번째 입력변수에 대해 예측된 결과를 보면, predict
결과 0으로 예측하였다. predict_proba
결과를 보면서 해석해 보면 리스트 내의 세가지 값(class 0일 확률, class 1일 확률, class 2일 확률)들 중 0번째 요소가 제일 큰 값을 가진다. 즉 다른 클래스들일 확률들과 비교했을 때 0일 확률이 가장 크기 때문에 0으로 예측하는 것이다.
(2) 피처들의 계수
.coef_
를 사용하면 모델로부터 어떤 feature가 결과에 큰 영향을 주는지 확인할 수 있다. class 별로 어떤 피처에 크게 영향을 받았는지 결과는 아래와 같다.
model.coef_
출력 결과
array([[-0.01878431, -0.00677701, -0.00294959, -0.06715177, -0.04582759,
0.00248559, 0.00965551, -0.00169579, 0.00160013, -0.01425674,
-0.00055358, 0.00368465, 0.00816883],
[ 0.00966877, -0.01763132, 0.0004303 , 0.03637297, 0.03785306,
0.0104504 , 0.01808975, -0.00023449, 0.00866373, -0.05555264,
0.00738715, 0.0199435 , -0.00607386],
[ 0.00911553, 0.02440833, 0.00251929, 0.0307788 , 0.00797453,
-0.01293599, -0.02774526, 0.00193028, -0.01026386, 0.06980938,
-0.00683356, -0.02362815, -0.00209496]])
- 첫 번째 클래스는
-0.06715177472030232
값을 가지는alcalinity_of_ash
변수에 가장 영향을 많이 받았다는 것을 알 수 있다.- 음수가 나왔기 때문에 해당 값이 클수록 해당 클래스가 나올 확률이 낮아진다는 의미로 해석 가능
- 두 번째 클래스는 계수로
-0.055552643460647214
값이 나온color_intensity
변수에 가장 영향을 많이 받았다는 것을 알 수 있다.- 음의 관계를 가지기 때문에 해당 값이 클수록 클래스가 나올 확률이 낮아진다는 의미로 해석 가능
- 세 번째 클래스는 계수로
0.06980938213920487
값이 나온color_intensity
변수에 가장 영향을 많이 받았다는 것을 알 수 있다.- 양의 관계를 가지기 때문에 해당 값이 클수록 클래스가 나올 확률이 높아진다는 의미로 해석 가능
6. Reference
👩🏻💻개인 공부 기록용 블로그입니다
오류나 틀린 부분이 있을 경우 댓글 혹은 메일로 따끔하게 지적해주시면 감사하겠습니다.
댓글남기기