ML | DL/혼자공부하는머신러닝딥러닝

9강. 로지스틱 회귀 알아보기

묘걍 2023. 12. 14. 21:11

👉🏻 복습

  • 선형 회귀에 특성을 많이 추가하면 과대적합될 수 있다
  • 과대적합된 모델을 억제하기 위해 규제라는 기법을 사용한다
  • pandas를 사용해 CSV파일을 pandas의 dataframe으로 읽어들이고 넘파이 배열로 변환했다
  • sklearn의 PolynomialFeatures를 활용해 다항특성을 여러개 만들었다
    • 제곱, 특성끼리 곱하기 ...
  • 변환기
    • fit(), transform() 메서드를 제공한다
    • fit()은 학습해서 통계 데이터를 얻는 경우도 있지만 그렇지 않은 경우도 있다. 하지만 API일관성을 위해서 항상 사용한다
    • fit_transform() 도 제공을 한다
  • 주의할 점은 훈련 세트에 사용한 변환기를 테스트세트에서도 활용해야 한다
    • 매개변수 옵션 등을 똑같이 적용하기 위해
    • 훈련세트에 있는 특성값 통계치를 얻어와야할 수 있음
  • 어떤 특성이 만들어졌는지 보려면 get_feature_names()
  • 특성을 많이 만들면 성능이 너무 좋아져서 훈련세트에서는 높은 점수가 나오지만 테스트세트에서는 형편없는 점수가 나온다
  • 선형 회귀 모델일 경우에는 규제를 해야한다
  • 선형 회귀에서는 특성에 곱해지는 계수/가중치 값을 작게 하는 것이 규제의 한 방법
  • 릿지모델(L2)
  • 라쏘모델(L1)
  • 과대적합이 억제되고 테스트세트가 꽤 좋은 점수가 나왔다
  • 얼마만큼 규제할 것인가는 alpha로 조정한다.
    • 기본 값은 1
    • 커질수록 규제가 강해지고
    • 작아질수록 규제가 약해진다
    • 훈련세트, 상황마다 다르니 값을 바꿔가면서 최적의 값을 찾아내야 한다
    • 골드박스 지점을 찾아야 한다

👉🏻 로지스틱 회귀

✏️ 럭키백

출처: 혼공머딥 유튜브

- 어떤 생선인지는 모르고 구매하는 것

- 럭키백 종류마다 럭키백에 포함된 생선의 확률을 알려줌 (이야기 설정 상 이게 이벤트 내용 수정 결과라고 함)

- 이전까지 했던 모델들은 이것이 도미일 확률이 몇%인지는 나오지 않았음

- 숫자가 나오니까 '회귀인가?' 싶을 수도 있음. 하지만 분류 문제

     - 도미인지 빙어인지 분류하면서

     - 이 샘플이 도미(혹은 빙어)임을 얼마나 확신하는지(확률)를 제공한다

👉🏻 확률 계산하기

출처: 혼공머딥 유튜브

✅ K-최근접 이웃 알고리즘으로 먼저 알아보기

- 길이, 대각선 길이, 높이, 두께, 무게 (5가지)

- 다수인 클래스를 예측 클래스로 삼는다

- X는 ■ 3개, ● 2개, ▲ 5개

- 5개인 세모가 예측 클래스가 된다

- 이웃한 샘플 10개

     - 10개 중 5개니까 50%의 확률로 ▲

     - 10개 중 3개니까 30%의 확률로 ■

     - 10개 중 2개니까 20%의 확률로 ●

🙋🏻‍♀️ K - 최근접 이웃이 KNN인가요?

👩🏻‍🏫 맞다. K-Nearest Neighbors이다

- 이웃한 샘플의 클래스 비율을 확률로 출력 가능

 

👉🏻 데이터 준비

- Pandas로 데이터 준비

- DataFrame 객체로 만듦

     - DataFrame에는 다양한 기능이 있다

- head()메서드는 처음 몇 개의 행을 테이블로 출력해준다

- 헤더는 CSV의 첫 번째 줄

- 각 열은 CSV에서 콤마(,)로 나뉘어 있었을 것

- 맨 왼쪽 숫자는 인덱스값

     - 실제 CSV파일에는 없었고 판다스가 붙여준 것

- Species: 7개의 생선에 대한 종류가 들어 있다

     - 이것이 타겟이 된다

- 무게, 길이, 대각선, 높이, 두께: 특성 데이터, 입력 데이터로 사용

Species 열만 따로 뽑아 타깃으로 만들고 나머지는 특성 데이터/입력 데이터로 활용

- 몇 개의 열을 뽑아내는 간단한 방법은 리스트로 열 이름을 전달해주는 것

- 5개의 열만 뽑아서 fish_input에 넣어준다

     - fish_input은 열만 늘어났을 뿐 기본적 포멧은 2차원 배열, 각 샘플이 행으로 늘어져 있는 것은 이전과 동일

- to_numpy를 통해 넘파이 배열로 만들어줌

- 타깃 데이터는 하나의 열(species)만 필요, 리스트로 만들 필요 없음

👉🏻 전처리

- 훈련세트와 테스트세트 나누기

- 표준점수로 전처리

🤔표준점수로 전처리하는 이유?
머신러닝에서 k-최근접 이웃(K-Nearest Neighbors, k-NN)은 주어진 데이터 포인트의 근접 이웃들을 기반으로 예측을 수행하는 알고리즘 중 하나입니다. 표준 점수(표준화)로 전처리하는 이유는 데이터의 스케일이나 단위가 서로 다를 때, 각 특성(feature)이 모델에 동일한 영향을 미치도록 만들기 위함입니다.
다양한 특성 간의 스케일이나 범위가 다르면, 머신러닝 알고리즘이 데이터의 패턴을 학습하기 어려워집니다. 예를 들어, 한 특성의 값이 0에서 1 사이에 있고 다른 특성의 값이 0에서 1000 사이에 있을 때, 두 번째 특성이 더 큰 영향을 미칠 수 있습니다. 이런 경우 모델이 특정 특성에만 의존하여 훈련될 수 있습니다.
표준 점수는 각 특성의 평균을 빼고 표준 편차로 나누어, 각 특성을 평균이 0이고 표준 편차가 1인 분포로 변환합니다. 이렇게 하면 각 특성이 상대적으로 동일한 척도로 표현되며, 이는 k-최근접 이웃 알고리즘이 데이터 간의 거리를 올바르게 계산하는 데 도움이 됩니다. 따라서 표준화를 통해 모델의 성능을 향상시키고 일반화 능력을 높일 수 있습니다.

-  StandardScaler 객체에 fit 메서드를 호출하여 훈련 데이터(train_input)를 사용하여 평균과 표준 편차를 계산

-  transform 메서드를 사용하여 훈련 데이터(train_input)를 표준화

- 이 과정에서는 훈련 데이터의 각 특성에 대해 앞서 학습한 평균과 표준 편차를 사용하여 표준화를 수행

- 훈련 데이터를 표준화한 매개변수(평균과 표준 편차)를 사용하여 테스트 데이터(test_input)도 표준화

- 훈련 데이터와 동일한 변환 매개변수를 사용하여 일관된 스케일을 보장

👉🏻 k-최근접 이웃의 다중 분류

- KNeighborsClassifier를 import

- 객체를 만든다

- n_neighbors가 기본 값이 5인데 3으로 설정한다

- 전처리한 훈련 데이터를 집어 넣고, 타깃 데이터는 전처리가 필요하지 않으니 원래대로 넣어준다

- 타깃데이터인 species가 문자열로 되어 있다

✅ 타깃값 레이블링

  • 이진 분류를 다룰 때는 정수로 타깃 값을 레이블링했다
    • 맞추고자 하는 것을 1로, 아닌 것을 0으로
    • 도미를 1로 빙어를 0으로 뒀던 것 처럼
  • 싸이킷런은 숫자 뿐만 아니라 문자열도 타깃값으로 받아들일 수 있다
    • 안에서 자체적으로 정수로 바꿔서 훈련함
    • 우리가 굳이 정수로 바꿔주지 않아도 됨

- 훈련된 후 타깃 값이 클래스가 어떤식으로 되어 있는지 확인하기 위해 classes_속성을 사용

✅ 속성 이름의 언더바(_)

  • 모델 클래스를 만들 때 지정한 값이 아니라
  • 모델이 데이터로부터 학습한 값 (train_target으로부터 추출한)

✅ 레이블 순서

  • 싸이킷 런은 알파벳 순서대로 레이블을 준다
  • 레이블은 0부터 달린다
    • Bream이 0, Prkki가 1, Perch가 2, ...
  • 내가 직접 정하고 싶으면 수동으로 지정해주면 된다
  • 여기서는 레이블 순서가 중요하지 않기 때문에 싸이킷런에서 정한 대로 함

- predict() 메서드로 예측해보기

- 테스트 샘플 중 5개의 샘플을 뽑아서

- 친절하게 이름으로 바뀌어 나온다

- 확률을 출력하려면 predict_proba()메서드를 호출함

- 싸이킷런의 분류 모델들은 대부분 predict_proba()메서드를 제공한다

     - 제공하지 않는 경우는 확률을 계산하기 위해 자원이 너무 많이 필요할 경우.

        확률을 꼭 구해야할 경우에는 매개변수로 명시해줘야함

- 여기서도 5개의 샘플에 대해서 확률을 뽑아봄

 

- 5개의 샘플이 행으로 나와있음

- 7개의 생선에 대해서 확률이 출력된다

- 첫 번째 쌤플은 3번째 생선(Perch)일 확률이 100%다 → Perch로 예측

- 다섯 번째 샘플은 3번째 생선(Perch)일 확률이 66%, 다섯 번째 생선(Roach)일 확률이 33% → Perch로 예측

 

출처: 혼공머딥 유튜브

- 샘플이 행으로 놓여있고

- 각 요소는 클래스에대한 확률을 나타낸다

🧩 문제점

- 이웃이 3개 밖에 없으니 확률이 1/3, 2/3, 3/3 세 가지로 밖에 나오지 않는다.

- 확률이라고 말하기 어색하다

더보기

K-최근접 이웃(K-Nearest Neighbors, k-NN) 알고리즘은 다수결 투표를 기반으로 예측을 수행합니다. 다중 분류에서는 각 클래스에 대한 확률을 추정하기 위해 이웃 중 해당 클래스에 속한 이웃의 비율을 계산합니다. 하지만 이웃의 수가 적으면 클래스별 확률이 제한적으로 나타날 수 있습니다.

n_neighbors 매개변수가 3으로 설정되었다면, 각 예측에 대해 가장 가까운 3개의 이웃을 찾아 다수결 투표를 진행합니다. 이때, 다수결 투표를 통해 선택된 클래스의 확률은 해당 클래스에 속한 이웃의 비율로 나타낼 수 있습니다.

예를 들어, 이웃이 3개 중 2개가 클래스 A에 속하고 1개가 클래스 B에 속한다면, 클래스 A에 대한 확률은 2/3이 됩니다. 그러나 이웃의 수가 적을 경우, 확률은 1/3, 2/3, 3/3 등과 같이 제한된 수의 값만을 가질 수 있습니다. 이는 이웃의 수가 늘어날수록 더 부드러운(continuous) 확률 분포를 얻을 수 있게 됩니다.

따라서, 이웃의 수가 매우 적을 경우 다수결 투표로 인해 각 클래스의 확률이 제한적으로 나타날 수 있으며, 이는 모델이 해당 데이터에 대한 불확실성을 덜 반영하게 됨을 의미합니다. 이를 해결하기 위해서는 더 많은 이웃을 고려하거나 다른 확률 추정 방법을 사용하는 등의 조치를 취할 수 있습니다.

 

👉🏻 로지스틱 회귀

  • 대표적 분류 알고리즘
  • 인공신경망의 기본
    • 은닉층이 없는 기본적 인공신경망
  • 선형회귀와 특징이 비슷하다
    • 선형 함수를 학습한다

출처: 혼공머딥 유튜브

- 5개의 특성을 사용하기 때문에 계수가 5개로 늘어났다 (a, b, c, d, e)

     - 계수 / 가중치 / 기울기와 특성을 곱해 나중에 절편을 더해서 값을 만들어내는 것이 선형회귀와 완전히 동일하다

- 절편이 하나 (f)

✅ z

  • z값을 그대로 사용하면 회귀 알고리즘
    • 그대로 사용하면 z가 -∞ ~ ∞
  • 분류를 위해서 확률로 바꿔야함
    • 0 ~ 1로
  • 수학적 트릭이 필요, 이것이 시그모이드 함수 / 로지스틱 함수

🧩 로지스틱 함수

출처: 혼공머딥 유튜브

  • 시그모이드 함수 = 로지스틱 함수
  • 시그모이드 함수는 S자 모양으로 생김
  • cf. 하이퍼볼릭 탄젠트 함수도 S자 모양이기 때문에 시그모이드 함수라고 부르는 경우도 있긴 함. 하지만 경험상 대부분의 경우 시그모이드 함수는 로지스틱 함수를 의미한다
더보기

하이퍼볼릭 탄젠트 함수(tanh 함수)는 수학적인 함수 중 하나로, 실수 값을 입력으로 받아 -1에서 1 사이의 출력 값을 갖는 함수입니다. tanh 함수는 쌍곡선 탄젠트(hyperbolic tangent) 함수로도 불립니다.

하이퍼볼릭 탄젠트 함수는 다음과 같이 정의됩니다:

여기서 는 자연상수(약 2.71828)입니다. 입력 값이 양수일 때는 1에 가까운 값을 출력하며, 음수일 때는 -1에 가까운 값을 출력합니다. 0에서는 함수의 값이 0입니다.

하이퍼볼릭 탄젠트 함수는 신경망과 같은 기계 학습 모델에서 주로 사용되며, 시그모이드 함수와 유사하지만 출력 범위가 -1에서 1로 확장되어 학습의 안정성을 높일 수 있습니다. 특히, tanh 함수는 입력 값이 0 근처에서 시그모이드 함수보다 미분이 더 크기 때문에 그래디언트 소실 문제를 어느 정도 완화할 수 있습니다.

  • z값(x축)이 -∞ ~ ∞
    • 여기서 시그모이드 함수 최대 출력값: 0.1 ~ 최소 출력 값: 0
    • 그래서 0과 1사이, 확률값으로 생각하기 쉽다
  • 0.5를 기준으로
    • 0.5보다 크면 양성 클래스
    • 0.5보다 작으면 음성 클래스
  • 그냥 z값을 보고도 양성/음성을 나눌 수 있다
    • z가 0보다 크면 양성 클래스 (0일 때 0.5가 되기 때문에)
    • z가 0보다 작으면 음성 클래스 (시그모이드 값이 음수가 되기 때문에)
    • 분류만 하고 싶다면 굳이 시그모이드 함수에 넣지 않아도 판단 가능, 하지만 확률을 뽑고 싶으면 시그모이드 함수에 넣어야 함
    • 싸이킷 런의 predict() 함수는 z값만 보고 판단
    • k최근접이웃 알고리즘의 predict_proba() 함수는 파이값( ɸ이거 말하는건가?)을 계산해서 확률 값을 출력한다
    • 계산 편의상 그렇게 하는거고 일반적으로는 확률 값을 바꿔서 양성/음성 클래스를 분류한다
  • 0.5가 애매함
    • 라이브러리 구현마다 다름 (양성이다 vs 음성이다)
    • 선택사항일 뿐
    • 일반적으로는 음성으로 판단
  • 출력 값을 그대로 사용하는 회귀가 아니라
  • 그 값을 시그모이드함수에 넣어서 확률로 바꾼 뒤 0.5보다 크면 양성 클래스 0.5보다 작으면 음성클래스로 판단
  • 양성과 음성으로 분류하니 분류 알고리즘이다

🧩 시그모이드 함수 그려보기

- numpy의 arange 함수를 사용하여 -5부터 5까지의 범위에서 0.1 간격으로 값을 생성하고 그 결과를 z에 저장

- 시그모이드 함수의 수식을 사용하여 z매열의 각 요소에 대한 시그모이드 값 계산, 그 결과를 phi에 저장

✅ np.exp()

  • np.exp(x)는 주어진 x에  대해 자연 로그의 지수를 반환하는 함수.  e는 자연 상수 (약2.71828)

더보기

🤔 -z를 전달하는 이유?

로지스틱 회귀의 시그모이드 함수는 다음과 같습니다:

여기서 z는 입력 특성에 대한 가중치 합과 편향(bias)의 합입니다.

-z를 사용하는 이유는 지수 함수를 취하면 양수 값이 크게 증가하므로, 이를 이용하여 확률을 0과 1 사이의 값으로 매핑하는 데에 유용합니다. 따라서

의 지수 함수를 사용하여 z가 크면 0에 가까워지고, z가 작으면 1에 가까워집니다.

이렇게 계산된 값은 시그모이드 함수의 출력인 로 사용되어, 입력 데이터에 대한 확률을 나타내게 됩니다.

- plot() 함수를 사용해 z를 x축, phi를 y축으로 하는 선 그래프 생성

👉🏻 로지스틱 회귀 (이진 분류)

🧩 불리언 인덱싱

  • 배열에서 조건을 만족하는 요소들을 선택하는 방법 중하나
  • True, False 값을 전달하여 행을 선택할 수 있다
  • 각 원소의 위치에 True, False값을 전달해 True값만 뽑아내는 것

- A에서 E까지 5개의 원소로 이루어진 배열

- 여기서 A와 C만 골라내려면 첫 번째와 세 번재 원소만 True이고 나머지 원소는 모두 False인 배열을 전달

🧩 도미와 빙어 행만 골라내기

- 불리언 인덱싱 활용

- '도미'와 '빙어'만 True로 만드는 비교 연산자, True로 만든 두 배열을 or연산자로 합침

- bream_smelt_indexes는 도미와 빙어인 원소 부분은 True, 나머지는 False로 되어있는 불리언 인덱스

       - 길이는 train_scaled 행의 길이와 같다

- 만든 불리언 인덱스를 train_scaled에 전달하면 True로 되어 있는 도미와 빙어만 뽑아져 train_bream_smelt로 전달

     - target도 마찬가지

- LogisticRegression도 선형 모델이기 때문에 linear_model모듈 아래 있다

- 객체를 만들고

- fit()메서드에 훈련데이터와 타겟 데이터를 넣어준다

- predict()메서드로 예측

- 5개의 샘플만 출력

- 확률 출력해보기

- 이진 분류이기 때문에 첫 번째 인덱스([0])이 음성 클래스일 확률, 두 번째 인덱스([1])가 양성 클래스일 확률

- 알파벳 순으로 레이블링해서 도미(Bream)이 첫 번째가 된 것

     - 마치 빙어를 찾기 위한 분류처럼 되었음 (빙어가 1이라는 뜻)

👉🏻 로지스틱 회귀 계수 확인

- 선형함수를 학습하기 때문에 당연히 기울기와 절편을 출력할 수 있다

- 5개의 가중치가 나온다 (특성이 5개, 특성마다 곱해지는 가중치(기울기))

- 마지막은 절편

출처: 혼공머딥 유튜브

- z 함수 출력해보기

✅ decision_function()

  • 주어진 입력 데이터에 대한 로지스틱 회귀의 결정 함수 값(z값)을 반환
    • 결정 함수 값은 입력 데이터가 양성 클래스에 속할 확률과 관련 있다
  • 결과로 나오는 배열은 각 훈련 데이터 포인트에 대한 결정 함수 값들
    • 양수일 경우 해당 포인트가 양성 클래스에 속할 확률이 높다는 것
    • 음수일 경우 해당 포인트가 음성 클래스에 속할 확률이 높다는 것
  • 주의: 출력은 확률이 아니라 어떤 결정 함수 값. 이 값의 부호와 크기를 통해 모델이 예측한 클래스와 해당 예측의 신뢰도를 파악할 수 있다

- 5개의 샘플에 대해서

- 이 값을 시그모이드 함수에 넣어서 확률값 확인

✅ scipy의 expit

  •  로지스틱 함수 또는 시그모이드 함수의 값을 계산

  • 결과로 나오는 값은 입력 배열 각각의 원소에 대한 시그모이드 함수 값
    • 0과 1사이 범위
    • 입력값이 증가함에 따라 시그모이드 값이 0에서 1로 변한다

- 위에서 만든 decisions배열을 전달

- 시그모이드 함수를 거친 평균값이 나옴

- 위에서 확인했던 확률 중 인덱스[1]의 값과 동일함을 볼 수 있다

* 로지스틱 회귀가 이진 분류일 경우 양성 클래스의 z값만 계산을 한다

* 확률을 출력할 때는 음성 클래스의 확률도 출력할 수 있다 (1에서 빼면되니까)

👉🏻 로지스틱 회귀(다중 분류)

- 도미랑 빙어를 따로 뽑아내지 않고 7개의 생선을 모두 쓴다

  • 여러개의 클래스가 있는 경우

- LogisticRegression 클래스를 그대로 사용할 수 있다

✅ max_iter

  • 로지스틱 회귀는 기본적으로 반복적인 알고리즘을 사용한다
  • max_iter가 반복 횟수를 조정한다
  • 기본 값은 100
    • 하지만 100으로 하면 반복 횟수가 모자르다고 나온다 

- 1000으로 늘려서 반복 학습을 많이 할 수 있도록

✅ C

  • 로지스틱 회귀 클래스를 만들 때 아무 매개변수 없이 괄호만 쳐서 객체를 만들었음
  • 로지스틱 회귀는 L2 노름을 사용하는 규제를 기본적으로 적용한다
  • 규제의 강도를 정하기 위해 선형회귀때는 alpha 매개변수, 여기서는 C
  • C값이 올라가면 규제가 약해지고, C값이 내려가면 규제가 강해진다 (alpha와는 반대)
  • 규제의 역수라고 하기도 함
  • 이론의 공식 때문, 그냥 적당히 이해하고 사용하면 됨
  •  기본값 = 1
  • 적절한 값은 여러가지 값을 넣어가며 찾아가야 한다
    • 예전에 for문 돌려서 적절한 alpha값 찾았던 것 처럼

- 규제를 완화하기 위해(복잡한 모델을 만들기 위해) 20으로 늘림

- 분류모델이기 때문에 score는 정확도

- 93% 정확도

- 92% 정확도

- 처음 5개 샘플에 대한 예측

- 처음 5개 샘프에 대한 예측 확률

- 한 행 당 샘플 하나

- 7개의 확률 = 클래스 7개 = 생선 7 종류

- 첫 번째 샘플의 경우 세 번째 클래스가 가장 높은 확률

- 클래스 출력해보기

- 세 번째 클래스가 Perch임. 첫 번째 샘플의 경우 Perch의 확률을 높게 예상함

- coef와 intercept의 크기

🧩 7개의 행 5개의 열

     - 5개는 특성과 곱해지는 계수

     - 7개는 클래스 (클래스가 7개니까)

- 클래스마다 선형 함수가 하나씩 만들어진다

     - z값이 클래스마다 하나씩 만들어지는 것

- 7개의 선형함수를 만들어서 첫 번째 샘플에 대해서 7개의 함수를 통과시켜 나온 값 중 가장 큰 값이 예측클래스

- (예를 들어?)네 번째 선형함수를 학습할 때는 마치 이진분류처럼 한다

     - 4번째 클래스는 양성으로, 나머지 클래스는 음성으로 두고 학습을 하는 것

- 이진 분류를 7번 시행(훈련)하는 것

✅ OvR

  • 이진 분류를 여러번 실행해서 다중 분류를 하는 것
  • One vs Rest
더보기

"OvR"은 "One-versus-Rest" 또는 "One-versus-All"의 약어로, 다중 클래스 분류(multi-class classification) 문제에서 사용되는 기법 중 하나입니다. OvR은 각 클래스를 나머지 모든 클래스와 구분하여 이진 분류(binary classification) 문제로 변환하는 방식입니다.

일반적인 다중 클래스 분류 문제에서는 여러 개의 클래스가 있습니다. OvR은 각 클래스마다 하나의 이진 분류 문제를 만들어 해당 클래스인지 아닌지를 판별하는 방식입니다. 각 클래스에 대해 하나의 분류기를 훈련시키며, 예측할 때에는 이들 중 가장 높은 확률이 나온 클래스를 선택합니다.

예를 들어, 손글씨 숫자 분류 문제에서 0부터 9까지의 숫자를 분류하는 경우를 생각해봅시다. OvR 방식을 사용하면, 클래스 0에 대한 이진 분류기는 "숫자가 0인가 아닌가?"를 판별하고, 클래스 1에 대한 분류기는 "숫자가 1인가 아닌가?"를 판별하는 식으로 각각의 클래스에 대한 분류기를 훈련시킵니다.

OvR의 장점은 각 클래스에 대한 이진 분류 문제로 단순화되기 때문에 기존의 이진 분류 알고리즘을 활용할 수 있다는 점입니다. 또한, 각 클래스에 대한 분류 문제가 독립적으로 학습되기 때문에 데이터 불균형이나 클래스 간의 상호작용이 적은 경우에 적합합니다.

OvR은 Scikit-Learn과 같은 머신러닝 라이브러리에서 일반적으로 지원되며, OneVsRestClassifier 클래스 등을 통해 구현할 수 있습니다.

🧩 7개의 z를 어떻게 확률로?

  • 7개의 z를 전부 시그모이드로 바꿈
  • 7개의 시그모이드의 총합이 1
    • 한 행에서의 확률은 모두 더했을 때 1이 되어야 한다
  • 7개의 z를 시그모이드에 통과시키면 합이 1이 안됨
  • 7개의 z를(7개의 선형함수의 출력을) 그대로 시그모이드 함수에 넣으면 안된다
  • 다중 분류일 경우 시그모이드 말고 소프트 맥스 함수 사용

👉🏻 소프트맥스 함수

- decision_function 출력해보기

더보기

decision_function은 일반적으로 이진 분류 문제에서 사용되는 메서드 중 하나로, SVM (Support Vector Machine) 및 일부 다른 분류 알고리즘에서 제공됩니다. 이 메서드는 각 샘플에 대한 결정 함수 값을 반환합니다.

결정 함수 값은 해당 샘플이 어떤 클래스에 속하는지를 결정하는 데 사용됩니다. 이 값은 부호를 통해 예측된 클래스를 나타내며, 양수는 양성 클래스(Positive class), 음수는 음성 클래스(Negative class)를 의미합니다. 값의 절댓값이 클수록 해당 샘플이 어떤 클래스에 더 가깝게 위치해 있다고 해석할 수 있습니다.

decision_function은 다중 클래스 분류 문제에서는 각 클래스에 대한 결정 함수 값을 반환합니다. 일반적으로 OvR (One-versus-Rest) 전략을 사용하는 다중 클래스 분류에서는 클래스의 개수만큼 결정 함수가 반환됩니다.

예를 들어, Scikit-Learn의 SVC (Support Vector Classification)에서는 다음과 같이 decision_function을 사용할 수 있습니다:

from sklearn.svm import SVC
from sklearn.datasets import load_iris

# 데이터 로드
iris = load_iris()
X = iris.data
y = iris.target

# SVM 모델 생성
svm_model = SVC(kernel='linear', C=1)
svm_model.fit(X, y)

# decision_function을 통한 결정 함수 값 확인
decision_values = svm_model.decision_function(X)
print("Decision Function Values:\n", decision_values)

이러한 결정 함수 값은 각 클래스에 대한 신뢰도나 확신 정도를 나타내며, 이를 기반으로 최종적으로 어떤 클래스로 분류할지를 결정할 수 있습니다.

- 이진분류와 동일하게 z값을 출력해준다

- 7개의 값이 출력됨

- 5개의 샘플에 대해서 7개의 결정함수값(z값)이 출력됨

✅ z값 계산

출처: 혼공머딥 유튜브

  • z값을 지수함수에 적용
  • 첫 번째 샘플로 예를 들면 z0 = -6.5, z1 = 1.03 ... 이를 지수 함수에 적용하는 것
  • 각각을 sum으로 나눔
    • 분자를 다 더한 것
    • 지수함수를 다 적용한 것을 더한 값
  • 다 더하면 1이 된다(?)
  • 일종의 정규화
  • 이렇게 하면 시그모이드값이 나오고 이를 다 더하면 합이 1이 된다
  • 이렇게 나온 것이 predict_proba의 출력값

- 직접 해도 되지만 scipy의 softmax 활용하기

- decision값을 넣고 계산

- 소수점이 너무 길게 나오지 않도록 numpy의 round() 함수 활용

- 앞에서 출력한 확률 값과 동일한 값이 출력되고 있다

 

 

* 인공신경망에서 또 나온다!

* 시그모이드 함수는 이진 분류일 경우 확률을 표현하기 위한 수학적 트릭(?)

* soft_max함수는 다중 분류일 경우 확률처럼 표현하기 위한 수학적 트릭

 


✏️ QnA

🙋🏻‍♀️ OvR 보충 설명해주세요. 예를들면 세 개의 클래스 A, B, C가 있을 때 클래스 A / 클래스 B, C로 한 번 이진 분류, 그 다음은 어떻게 진행하나요?

👩🏻‍🏫 정확히 이해하고 있다. 클래스 A를 양성클래스로, 클래스 B, C를 음성 클래스로 두고 이진분류. 클래스 B를 양성클래스로, 클래스 A, C를 음성클래스로 두고 음성클래스로 두고 이진분류. 클래스 C를 양성클래스, 클래스 A, B를 음성클래스로 두고 이진분류. 세 개의 선형함수가 나옴(= 세 개의 z값이 나옴). 그 값을 soft max 함수를 통과시켜 확률값으로 바꿔 가장 높은 확률 값이 예측클래스가 된다. z값만 보고도 예측가능하다. z값이 가장 높은 것이 예측 클래스가 된다.

 

🙋🏻‍♀️ OvR 설명할 때 여러 클래스의 선형 회귀 계수와 동일하다는 말이 이해가 가지 않아요

👩🏻‍🏫 위 답변과 동일하다. 선형 함수를 여러개 학습하기 때문에 선형함수의 계수는 이진분류 계수와 같은 의미이다. 이진 분류를 여러번 해서 다중 분류를 수행한다고 보면 된다.

 

🙋🏻‍♀️ 핸즈온 머신러닝 1편과 내용이 같나요?

👩🏻‍🏫 다를건 없는 것 같다. 다만 핸즈온 머신러닝은 더 많은 라이브러리와 수학 공식을 다루고 있는 반면 이 책은 입문자용으로 수학 공식은 빼고 가능한 개념으로 이해할 수 있도록 하고 있다

 

🙋🏻‍♀️ 절편, 편향을 쓰는 이유를 알 수 있을까요?

👩🏻‍🏫 데이터셋이 아래와 같이 흩어져 있다고 가정해보자

출처: 혼머딥 유튜브

이 때 절편이 없다면 원점을 지나는 직선만 학습할 수 있다

출처: 혼머딥 유튜브

절편이 있어야 데이터셋에 잘 맞는 직선을 학습할 수 있다

출처: 혼머딥 유튜브

t: 타겟, f: 특성

선형 함수를 학습하려면 절편이 있어야 학습할 수 있다

경우에 따라, 데이터가 원점에 잘 맞춰져 있다면 절편이 필요 없을 수 있긴 하다 (절편이 0)

 

 

 

 

 

 

 

 

 

 

출처: https://youtu.be/pO27UnTsYQU?si=n7ZnccHcctlGsgxQ