럭키백의 확률
- k-최근접 이웃 분류기 : 가장 가까운 이웃 클래스의 비율을 확률이라고 하기(?)
1 데이터 준비하기
3장에서 사용한 pandas를 이용해서 CSV 파일을 읽어들인다.
CSV파일은 read_csv() 함수로 읽어들일 수 있다.
head() 메서드로 어떤 데이터가 있는지 확인하는 절차로 처음 5개의 행을 출력해본다.
head | tail |
- 데이터프레임 내의 처음 n줄의 데이터를 출력 - 객체 안에 제대로 된 데이터 타입이 입력되어 있는지 빠르게 확인할 경우 사용 - n의 기본 값은 5 |
- 데이터프레임 내의 마지막 n줄의 데이터 출력 - 객체 내의 데이터 타입을 확인할 때, 데이터를 정렬하거나 데이터를 추가했을 경우 결과 확인 - n의 기본 값은 5 |
이번에 사용할 수 있는 특성은 총 5개로, 무게, 길이, 대각선, 높이, 넓이가 있다
어떤 종류의 생선이 있는지 알아보기 위해 Species 열에서 고유한 값을 추출해보기 위해 pandas의 unique()함수를 사용한다.
unique() : 데이터에 어떤 종류들이 있는지 알고 싶을 때 사용
타깃 데이터 : Species 열
입력 데이터 : Weight, Length, Diagonal, Height, Width 열
입력 데이터로 사용하기 위해 데이터프레임에서 원하는 열을 리스트로 나열해 선택한다. 여기에서는 5개의 열을 선택해서 to_numpy() 메서드로 넘파이 배열로 바꾸었다. 그리고 이것을 fish_input에 저장했다.
타깃 데이터를 만들기 위해 위와 동일한 방법으로 Species열을 선택하여 넘파이 배열로 바꾸고 이를 fish_target에 저장했다.
데이터를 훈련세트와 테스트세트로 나눈다.
StandardScaler 클래스를 사용해서 훈련세트와 테스트세트를 표준화 전처리한다.
2 k-최근접 이웃 분류기의 확률 예측
KNeighborsClassifier 클래스 객체를 만들고 훈련세트로 모델을 훈련한다.
이진 분류(binary classification) : 2개의 클래스 중 하나를 고르는 문제
- 양성클래스와 음성클래스를 각각 1과 0으로 지정하여 타깃데이터를 만듦
다중 분류(multiclass classification) : 타깃 데이터에 2개 이상의 클래스가 포함된 문제
- 훈련세트와 테스트세트의 타깃 데이터에도 7개의 생선 종류가 들어가 있다.
- 문자열로 된 타깃값을 그대로 사용 가능
타깃값을 그대로 사이킷런 모델에 전달하면 순서가 자동으로 알파벳 순으로 매겨져서 unique()메서드로 출력했던 순서와 다르다.
KNeighborsClassfier에서 정렬된 타깃값은 classes_속성에 저장되어 있다.
Bream이 첫번째 클래스, Parkki가 두번째 클래스가 되는 이런 식
테스트세트에 있는 처음 5개 샘플의 타깃값을 예측하면
사이킷런의 분류 모델은 predict_proba() 메서드로 클래스별 확률값을 반환한다.
테스트세트에 있는 처음 5개의 샘플에 대한 확률을 출력해본다.
round() 함수 : 기본적으로 소수점 첫째 자리에서 반올림을 하는데 decimals 매개변수로 소수점 아래 자릿수를 지정할 수 있다. 여기에서는 소수점 다섯 번째 자리에서 반올림해서 소수점 넷째자리까지 표기했다.
이 모델이 계산한 확률이 가장 가까운 이웃의 비율이 맞는지 확인하기 위해 네 번째 샘플의 최근접 이웃의 클래스를 확인해본다.
이 샘플의 이웃은 다섯 번째 클래스인 'Roach'가 1개이고 세 번째 클래스인 'Perch'가 2개이다. 다섯 번째 클래스에 대한 확률은 1/3=0.3333이고 세 번째 클래스에 대한 확률은 2/3=0.6667이 된다.
3개의 최근접 이웃을 사용하기 때문에 가능한 확률이 0/3, 1/3, 2/3, 3/3 이런 식으로면 안 되서 제대로 확률이라고 말하기 애매하다(?)
로지스틱 회귀(logistic regression) : 선형 방정식을 사용한 분류 알고리즘.
선형 회귀와 달리 시그모이드 함수나 소프트맥스 함수를 사용하여 클래스 확률을 출력할 수 있다.
z = a * (Weight) + b * (Length) + c * (Diagonal) + d * (Height) + e * (Width) + f
a, b, c, d, e는 가중치 혹은 계수이다.
확률로 만들기 위해 0~1(0~100%) 사이 값이 되어야한다. z가 아주 큰 음수일 때 0이 되고, z가 아주 큰 양수일 때 1이 되도록 바꾸려면 시그모이드 함수를 사용하면 된다.
시그모이드 함수(sigmoid function) or 로지스틱 함수(logistic function) : 선형 방정식의 출력을 0과 1 사이의 값으로 압축하며 이진 분류를 위해 사용
z가 무한하게 큰 음수일 경우 : 0에 가까워진다
z가 무한하게 큰 양수일 경우 : 1에 가까워진다.
z가 0이 될 때 : 0.5
즉, z가 어떤 값이 되더라도 S(x)는 0~1 사이의 범위를 벗어날 수 없다. >> 0~100% 사이의 확률로 해석 가능
넘파이를 이용해 -5와 5 사이에 0.1 간격으로 배열 z를 만든 다음 z 위치마다 시그모이드 함수를 계산한다.
이진 분류 -> 시그모이드 함수의 출력이 0.5보다 크면 양성 클래스, 0.5보다 작으면 음성 클래스로 판단한다.
3 로지스틱 회귀로 이진 분류 수행하기
불리언 인덱싱(boolean indexing)
- numpy 배열은 True, False 값을 전달하여 행을 선택할 수 있다.
- 배열 내부에 True와 False만이 존재
- 인덱스 배열의 크기가 원래 데이터프레임의 크기(열과 행)와 같아야한다.
- boolean 값으로 된 배열을 인덱스로 사용하면 True인 값만 결과로 추출할 수 있다.
'A'에서 'E'까지 5개의 원소로 이루어진 배열에서 'A'와 'C'만 골라내려면 첫 번째와 세 번째 원소만 True이고 나머지 원소는 False인 배열로 전달하면 된다.
이 방식을 이용해 훈련세트에서 도미(Bream)와 빙어(Smelt)의 행만 골라내보자!
도미와 빙어에 대한 결과를 비트 OR 연산자(|)를 사용해 합치면 도미와 빙어에 대한 행만 골라낼 수 있다.
bream_smelt_indexes 배열은 도미와 빙어일 경우 True이고 그 외는 모두 False이다. 이 배열을 사용해 train_scaled와 train_target 배열에 불리언 인덱싱을 적용해 도미와 빙어 데이터만 골라냈다.
이제 회귀 모델 훈련을 해보자
훈련한 모델을 사용해 train_bream_smelt에 있는 처음 5개 샘플을 예측해보자
두 번째 샘플을 제외하고 모두 도미로 예측했다. KNeighborsClassifier와 마찬가지로 predict_proba() 메서드를 통해 train_bream_smelt에서 처음 5개 샘플의 예측 확률을 출력해보자
샘플마다 2개의 확률이 출력되어 첫 번째 열이 음성 클래스(0)에 대한 확률이고 두 번째 열이 양성 클래스(1)에 대한 확률이다.
어떤 것이 양성 클래스인지 확인해보니
빙어(Smelt)가 양성 클래스이다. 두 번째 샘플만 양성 클래스인 빙어의 확률이 높다 즉, 두 번째 샘플은 빙어일 확률이 높고, 나머지 4개의 샘플은 도미로 예측할 것이다.
로지스틱 회귀가 학습한 계수를 확인해보면
z = -0.404 * (Weight) - 0.576 * (Length) - 0.663 * (Diagonal) - 1.013 * (Height) - 0.732 * (Width) -2.161
LogisticRegression 클래스의 decision_function() 메서드로 z값을 출력할 수 있다. train_bream_smelt의 처음 5개 샘플의 z값을 출력해보면
이렇게 구한 z값을 시그모이드 함수에 통과시키면 확률을 얻을 수 있다.
파이썬의 사이파이(scipy) 라이브러리에 있는 시그모이드 함수는 expit()이다.
출력된 값을 보면 predict_proba() 메서드 출력의 두 번째 열(양성클래스(1))의 값과 동일하다.
즉, decision_function() 메서드는 양성 클래스에 대한 z 값을 반환한다.
>> 이진 분류를 위해 2개의 생선 샘플(도미와 빙어)를 골라냈고 이를 사용해 로지스틱 회귀 모델을 훈련했다. 이진 분류일 경우 predict_proba() 메서드는 음성 클래스와 양성 클래스에 대한 확률을 출력한다. 또 decision_function() 메서드는 양성 클래스에 대한 z값을 계산한다. 또 coef_, intercept_ 속성에는 로지스틱 모델이 학습한 선형 방정식의 계수가 들어있다.
이제 이진 분류의 경험을 바탕으로 7개의 생선을 분류하는 다중 분류 문제를 해보자
4 로지스틱 회귀로 다중 분류 수행하기
LogisticRegression 클래스는 기본적으로 반복적인 알고리즘을 사용한다. max_iter 매개변수에서 반복횟수를 지정하며 기본값은 100인데 반복횟수가 부족하다는 경고가 발생해서 반복횟수를 1000으로 늘렸다.
LogisticRegression은 기본적으로 릿지 회귀와 같이 계수의 제곱을 규제한다. -> L2규제
릿지 회귀에서는 alpha 매개변수로 규제의 양을 조절해서 alpha가 커지면 규제도 커진다. LogisticRegression에서 규제를 제어하는 매개변수는 C이다.
- C는 작을수록 규제가 강해진다
- C의 기본값이 1이다. 여기에서는 규제를 완화하기 위해 20으로 늘렸다
LogisticRegression 클래스로 다중 분류 모델을 훈련해보자.
훈련세트와 테스트세트에 대한 점수가 높고 과대적합이나 과소적합이 일어나지 않은 것으로 보인다.
테스트 세트의 처음 5개 샘플에 대한 예측을 출력해보면
테스트세트의 처음 5개 샘플에 대한 예측 확률을 출력해보면
5개의 샘플에 대한 예측이므로 5개의 행이 출력되었다. 7개 생선에 대한 확률을 계산했으므로 7개의 열이 출력되었다.
*이진 분류일 경우 2개의 열만 있다 -> 음성클래스, 양성클래스
첫 번째 샘플은 세 번째 열의 확률이 가장 높은데 84.1%나 된다.
세 번째 열의 속성이 무엇인지 확인해보면 Perch를 가장 높은 확률로 예측했음을 알 수 있다.
또, 두 번째 샘플은 여섯 번째 열인 Smelt를 가장 높은 확률인 94.6%로 예측했다.
이진 분류는 샘플마다 2개의 확률을 출력하고 다중 분류는 샘플마다 클래스 개수만큼 확률을 출력한다. 여기에서는 7개이다. 이 중에서 가장 높은 확률이 예측 클래스가 된다.
이 데이터는 5개의 특성을 사용하므로 coef_배열의 열은 5개인데, 행이 7개이다. intercept_도 7개나 있는 것을 보아 이는 이진 분류에서 봤던 z를 7개나 계산한다는 의미이다.
다중 분류는 클래스마다 z값을 하나씩 계산해서 가장 높은 z값을 출력하는 클래스가 예측 클래스가 된다.
이진 분류에서는 시그모이드 함수를 사용해 z를 0과 1 사이의 값으로 변환했고,
다중 분류는 소프트맥스(softmax) 함수를 사용하여 7개의 z값을 확률로 변환한다.
소프트맥스(softmax) 함수 : 여러 개의 선형 방정식의 출력값을 0~1 사이로 압축하고 전체 합이 1이 되도록 만든다. 이를 위해 지수 함수를 사용하기 때문에 정규화된 지수 함수라고도 한다.
- 다중분류에서 사용되는 활성화 함수
- 분류될 클래스가 n개면, n차원의 벡터를 입력받아 각 클래스에 속할 확률을 추정한다.
이진 분류에서처럼 decision_function() 메서드로 z1~z7까지의 값을 구한 다음 소프트맥스 함수를 사용해 확률로 바꾸어본다.
테스트세트의 처음 5개 샘플에 대한 z1~z7의 값을 구해본다.
사이파이가 제공하는 소프트맥스 함수는 scipy.special 아래에 softmax() 함수를 임포트해 사용한다.
앞서 구한 decision 배열을 softmax() 함수에 전달했다. softmax()의 axis 매개변수는 소프트맥스를 계산할 축을 지정한다. 여기에서는 axis=1로 지정하여 각 행, 각 샘플에 대해 소프트맥스를 계산했다. 만약 axis 매개변수를 지정하지 않으면 배열 전체에 대해 소프트맥스를 계산한다.
출력 결과를 앞서 구한 proba 배열과 비교해 보면 정확히 일치하는 것을 알 수 있다
>> 로지스틱 회귀를 사용해 7개의 생선에 대한 확률을 예측하는 모델을 훈련했다.
'머신러닝 + 딥러닝' 카테고리의 다른 글
[혼공머신] CHAPTER 05-1 결정 트리 (0) | 2021.10.02 |
---|---|
[혼공머신] CHAPTER 04-2 확률적 경사 하강법 (0) | 2021.09.29 |
[혼공머신] CHAPTER 03-3 특성공학과 규제 (0) | 2021.09.23 |
[혼공머신] CHAPTER 03-2 선형회귀 (0) | 2021.09.20 |
[혼공머신] CHAPTER 03-1 k-최근접 이웃 회귀 (0) | 2021.09.16 |