어떤 박스에 들어간 생선의 크기, 무게 등이 주어졌을 때 7개 생선에 대한 확률을 출력하려는 문제를 풀려고 한다. 이에 대해 k-최근접 이웃은 주변 이웃을 찾아주니까 이웃의 클래스 비율을 확률이라고 출력하면 되지않을까?라는 아이디어를 활용할 것이다.
import pandas as pd
fish = pd.read_csv('https://bit.ly/fish_csv_data')
fish.head()
이 데이터 프레임에서 Species열을 타깃(정답값)으로 만들고 나머지 5개 열은 입력 데이터로 사용할 것이다([3]실행). 그리고 [5]실행 부분에서 훈련 세트와 테스트 세트로 나눈다. StandardScaler클래스를 사용해 훈련 세트와 테스트 세트를 표준화 전처리해주고 훈련 세트의 통계 값으로 테스트 세트도 변환해준다.
fish 데이터프레임에서 7개의 생선이 있었다. 이렇게 타깃 데이터에 2개 이상의 클래스가 포함된 문제를 다중 분류라고 부른다. 이진 분류를 사용했을 때는 양성 클래스와 음성 클래스를 각각 1과 0으로 지정하여 타깃데이터를 만들었는데 사이킷런에서의 다중 분류는 편리하게도 문자열로 된 타깃값을 그대로 사용할 수 있다. 타깃값을 그대로 사이킷런 모델에 전달하면 순서가 자동으로 알파벳 순으로 매겨진다는 것만 주의하면 된다.(아래 사진 참고)
predict()는 타깃값으로 예측을 출력한다. 테스트 세트에 있는 처음 5개 샘플의 타깃값을 예측해 보자.
이 5개 샘플에 대한 예측은 어떤 확률로 만들어졌을까? 사이킷런의 분류 모델은 predict_proba() 메서드로 클래스별 확률값을 반환한다.
이제 이 모델이 계산한 확률이 가장 가까운 이웃의 비율이 맞는지 확인해 보자. 네 번째 샘플의 최근접 이웃의 클래스를 확인해 볼 것 이다.
전전의 사진에서 4번째 샘플을 보면 5번째 클래스(Roach)가 하나(0.3333), 3번째 클래스(Perch)가 두개(0.6667)임을 확인 할 수 있다. 방금 출력한 네 번째 샘플의 클래스 확률과 같다. 성공인 것이다.
그런데 3개의 최근접 이웃을 사용하기 때문에 가능한 확률이 0/3, 1/3, 2/3, 3/3이 전부일 것이다. 뭔가 더 좋은 방법을 찾아야 한다.
로지스틱 회귀
로지스틱 회귀는 이름은 회귀이지만 분류 모델이다. 이 알고리즘은 선형 회귀와 동일하게 선형 방정식을 학습한다.
z = a x (Weight) + b x (length) + c x (Diagonal) + d x (Height) + e x (width) + f
여기에서 a, b, c, d, e는 가중치 혹은 계수이다. 특성만 늘어난 것이다. z는 어떤 값도 가능하지만 확률이 되려면 0에서 1사이 값이 되어야 한다. z가 아주 큰 음수일 때 0이되고, z가 아주 큰 양수일 대 1이 되도록 바꾸는 방법으로 시그모이드 함수를 사용하는 것이다. 이는 이진분류에서 자주 사용된다.
이제 로지스틱 회귀 모델로 다중 분류를 수행해보자.
LogisticRegression 클래스를 사용해 7개의 생선을 분류해 보자. 이 클래스는 기본적으로 반복적인 알고리즘을 사용한다. 충분하게 훈련시키기 위해 반복 횟수를 1000으로 늘릴 것이다. 또 LogisticRegression은 기본적으로 릿지 회귀와 같이 계수의 제곱을 규제한다. 이런 규제를 L2규제라고도 부른다. 릿지 회귀에서는 alpha 매개변수로 규제의 양을 조절했는데 LogisticRegression에서 규제를 제어하는 매개변수는 C이다. C는 alpha와 반대로 작을수록 규제가 커진다. C의 기본값은 1이지만 규제를 좀 더 완화하기 위해 20으로 늘리겠다.
훈련이 잘 된 것 같다. 테스트 세트의 처음 5개 샘플에 대한 예측도 해보았다. 밑의 샘플에 대한 예측 확률을 출력한 것과 비교해보자.
5개 샘플에 대한 예측이므로 5행이 출력되었다. 또 7개 생선 클래스에 대한 확률을 계산했으므로 7개의 열이 출력되었다.
첫 번째 샘플을 보면 세번째 열이 확률이 가장 높다. 84.1%나 된다. 세 번째 열이 Perch에 대한 확률일까? classes_속성에서 클래스 정보를 확인해보자.
이 데이터는 5개의 특성을 사용하므로 coef_ 배열의 열은 5개이다. 그런데 행과 intercept가 7개나 있다. 이 말은 z를 7개나 계산한다는 의미이다. 다중 분류는 클래스마다 z값을 하나씩 계산한다. 당연히 가장 높은 z값을 출력하는 클래스가 예측 클래스가 된다. 그럼 확률은 어떻게 계산한 것일까? 이진 분류에서는 시그모이드 함수를 사용해 z를 0과 1사이의 값으로 변환했다. 다중 분류는 이와 달리 소프트맥스 함수를 사용하여 7개의 z값을 확률로 변환한다. 소프트맥스도 어렵지 않다. 각 클래스에 대한 z값을 구한 후 모두 더한 값을 분모로, 각 클래스 z값을 하나씩 분자로 한다면 그것이 소프트맥스를 사용한 값이 되는 것이다.
'AI > 혼공파 머신러닝+딥러닝' 카테고리의 다른 글
[ML 05-1] 결정 트리 (0) | 2024.05.15 |
---|---|
[ML 04-2] 확률적 경사 하강법 (0) | 2024.05.09 |
[ML 03-3] 특성공학과 규제 - 릿지(Ridge), 라쏘(Lasso) (1) | 2024.03.31 |
[KNN, ML 03-2] 선형회귀(Linear Regression) (0) | 2024.03.27 |
[KNN 03-1] k-최근접 이웃 알고리즘 (데이터 전처리) (1) | 2024.03.26 |