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

5강. 정교한 결과 도출을 위한 데이터 전처리 알아보기

묘걍 2023. 11. 13. 21:06

👉🏻 복습..

✅ 양성 클래스 (Positive Calss)

- 이진 분류 (0 or 1)에서 찾고자 하는 클래스 (1)

- 찾고자 하는 클래스가 아닌 것은 음성 클래스 (0)

- 대부분의 알고리즘이 이렇게 데이터를 주입해주기를 기대하고 있다

- 좋고 나쁘고의 문제가 아님

 

*샘플링편향

* 주로 샘플을 행에 특성을 열에 넣은 이차원 배열을 훈련 데이터로 사용

* 배열 자체를 섞으면 쌍을 이루지 못하기 때문에 배열의 인덱스를 섞음

    + 배열 슬라이싱: 섞인 배열을 쉽게 만들 수 있다, 인덱스 배열만 만들어 섞으면 되기 때문에 공간 차지가 크지 않다

 

👉🏻 이전 머신러닝 프로그램의 문제점

출처: 혼공머딥 유튜브

- 위 생선을 빙어로 예측한다고 함

- 하지만 도미에 가까워보임

 

👉🏻 넘파이로 데이터 준비

- 이전 시간까지는 fish_length와 fish_weight를 파이썬 리스트로 만들고, 파이썬 리스트 내포를 사용해서 zip() 함수로 for문을 돌려가며 두 리스트를 하나로 합침

- 리스트의 리스트를 만들었다

- 이제는 넘파이를 통해 더 나은 방법으로 두 리스트를 합칠 것이다

- 합치는 모양은 이전과 같이 샘플을 행에, 특성을 열에 둔 이차원 배열

🧩 column_stack

  • 주어진 두 배열을 나란히 세운 뒤 열로 붙여준다

출처: 혼공머딥 유튜브

  • column_stack()과 비슷한 기능을 하는 row_stack()이라는 것도 있다
    • 열 방향으로 쌓아주는 것

출처: 혼공머딥 유튜브

더보기

가정:

  • 우리에게는 두 개의 1차원 배열, array1과 array2가 있습니다.
  • 각 배열은 간단하게 [1, 2, 3]와 [4, 5, 6]으로 가정합니다.

이 배열들을 column_stack을 사용하여 합치면 다음과 같습니다.

1. 원래 배열:

array1 = [1, 2, 3]
array2 = [4, 5, 6]

2. column_stack을 사용하여 합친 결과:

result = np.column_stack((array1, array2))
[[1, 4],
 [2, 5],
 [3, 6]]
array1     array2        column_stack
[1, 2, 3]  [4, 5, 6]  ->  [[1, 4],
                           [2, 5],
                           [3, 6]]

이렇게 column_stack은 각 배열을 열로 쌓아서 새로운 2차원 배열을 만듭니다.

출력해보면

이런식으로 나온다

🧩 concatenate()

  • 입력된 두 배열을 옆으로 길게 붙여주기만 함

✅ np.ones()

  • 이전에는 연산자 오버로딩을 이용하여 [1]*35와 같은 방법으로 1이 35개 있는 리스트를 만들어줬지만 효율적인 방법은 아니었다
  • np.ones()를 통해 1로만 채워진 특정 크기의 배열을 만들 수 있다
  • 크기를 튜플로 지정해주면 n×m 크기의 1이 채워진 2차원 배열을 만들 수도 있다

✅ np.zeros()

  • np.zeros()를 통해 0으로만 채워진 특정 크기의 배열을 만들 수 있다
  • 크기를 튜플로 지정해주면 n×m 크기의 0이 채워진 2차원 배열을 만들 수도 있다

✅ np.full()

  • 특정 값으로만 채워진 특정 크기의 배열을 만들 수 있다
  • np.full(배열 크기, 특정 값)
  • 배열 크기 부분에 튜플을 사용하여 2차원 배열을 만들 수도 있다

👉🏻 사이킷 런으로 데이터 나누기

- 머신러닝에서 필요한 도구들은 사이킷 런에서 많이 제공하고 있다

  • 사이킷런의 model_selection 밑의 train_test_split
  • fish_data와 fish_target을 한꺼번에 전달해서 훈련 세트와 테스트 세트로 나눌 수 있다
  • 여러 개의 배열을 더 넣을 수도 있다

✅ train_test_split

  • 훈련 세트와 테스트 세트를 나눠준다
더보기

`from sklearn.model_selection import train_test_split`에서 `train_test_split`은 scikit-learn 라이브러리에서 제공하는 함수로, 기계 학습 모델을 훈련하기 위한 데이터와 모델의 성능을 평가하기 위한 데이터를 나누는 데 사용됩니다.

여기에 대한 간단한 설명은 다음과 같습니다:

1. 목적:
   - 기계 학습에서는 데이터를 훈련에 사용하고, 모델의 성능을 평가하기 위한 데이터를 따로 빼두어야 합니다. `train_test_split` 함수는 주어진 데이터를 훈련 세트(Training Set)와 테스트 세트(Test Set)로 나누어주는 역할을 합니다.

2. 사용 방법:
   - `train_test_split` 함수는 여러 인자를 받지만, 주로 사용되는 인자는 피처(Feature) 데이터와 타겟(Target) 데이터입니다. 다른 인자로는 테스트 세트의 크기, 난수 발생기의 시드 등이 있습니다.

  from sklearn.model_selection import train_test_split

   X, y = ...  # 피처 데이터와 타겟 데이터를 준비

   X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)



   여기서 `X`는 피처 데이터, `y`는 타겟 데이터입니다. `test_size`는 테스트 세트의 비율을 나타내며, `random_state`는 난수 발생기의 시드값입니다.

3. 반환 값:
   - 함수는 훈련 세트와 테스트 세트로 나눠진 피처 데이터와 타겟 데이터를 반환합니다. 위의 코드에서는 `X_train`, `X_test`, `y_train`, `y_test`에 각각 할당되었습니다.

이렇게 나눠진 훈련 세트와 테스트 세트를 사용하여 모델을 훈련하고 성능을 평가하는 데 활용할 수 있습니다. 이 과정은 모델이 새로운 데이터에 대해 얼마나 잘 일반화되는지 확인하는 데 도움이 됩니다.

✅ stratify

  • 매개변수
  • 분류일 경우 샘플링 편향이 생기지 않도록 골고루 섞이게 해야한다
  • 훈련데이터가 굉장히 크고 클래스가 비교적 균등하게 있으면 적당히 랜덤으로 섞어도 되지만
  • 그렇지 않은 경우 편향이 생길 수 있어
  • stratify 매개변수에 fish_target배열을 전달
    • 그 배열을 보고 target값이 골고루 섞이도록 훈련 세트와 테스트 세트를 나눠준다
  • 분류 문제일 경우 필수로 사용
더보기

`stratify`는 `train_test_split` 함수에서 사용되는 매개변수 중 하나로, 클래스 불균형이 있는 경우에 훈련 세트와 테스트 세트에 각 클래스의 비율을 유지하기 위해 사용됩니다.

간단한 예제를 통해 설명하겠습니다. 가정하자면, 어떤 분류 문제에서 클래스 A와 클래스 B가 있고, 전체 데이터셋에서 클래스 A가 상대적으로 많고 클래스 B가 적다고 가정해봅시다.

from sklearn.model_selection import train_test_split

X, y = ...  # 피처 데이터와 타겟 데이터를 준비
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)



여기서 `stratify=y`는 클래스 레이블 `y`를 기반으로 데이터를 나누라는 것을 의미합니다. 이렇게 사용하면 훈련 세트와 테스트 세트에 각 클래스의 비율이 전체 데이터셋의 비율과 동일하게 유지됩니다.

이 매개변수를 사용하지 않으면, 훈련 세트와 테스트 세트에 각 클래스의 비율이 불균형할 수 있습니다. 특히, 클래스의 크기가 크게 차이 나는 경우에는 `stratify`를 사용하여 각 클래스를 적절히 나누는 것이 모델의 일반화에 도움이 될 수 있습니다.

간단히 말해, `stratify`는 각 클래스의 비율을 고려하여 데이터를 나누어주는 옵션으로, 클래스 불균형이 있는 분류 문제에서 사용됩니다.

✅ random_state

  • random seed 설정
  • 실전에서는 사용하지 않음
  • 숫자는 큰 의미가 없음

출처: 혼공머딥 유튜브

- 2개의 배열을 입력하면 4개의 배열을 반환

     - 3개 입력 → 6개 반환

👉🏻 수상한 도미

- 라이브러리를 불러옴

- 객체를 생성함

- 모델을 훈련함 (학습)

- 모델을 평가함 (테스트)

- 정확도 매우 높음

- 수상한 도미 예측해보기

- 빙어로 예측함

출처: 혼공머딥 유튜브

- 그림을 그려보면 분명 빙어에 가까운데 잘못 예측하고 있음

 

🎮 K-최근접 이웃 알고리즘이 바라보는 이웃의 정보 

✅ kneighbors()메서드

  • 입력 데이터에 대해 가장 가까운 이웃들(5개)의 정보를 반환
  • 반환 값은 두 개
    • 하나는 입력 데이터와 각 이웃 간의 거리를 담은 배열이고,
    • 다른 하나는 각 이웃의 인덱스를 담은 배열

- distances에는 이웃간의 거리 배열이 담기고

- indexes에는 이웃의 인덱스 배열이 담긴다

- train_input의 첫 번째 열을 x축으로, 두 번째 열을 y축으로 하는 그래프 그리기

     - 각각 길이 특성, 무게 특성

- 입력된 데이터 [25, 150]에 대한 산점도를 그린다. 모양은 삼각형

-  indexes에 저장된 이웃 데이터들을 나타내는 산점도를 그린다. 모양은 마름모

     - 0: 길이, 1: 무게 특성

     - 배열 인덱싱을 사용하는 것

- 왼쪽 아래에 몰려있음

- 사람의 눈으로 봐도 오른쪽 위가 더 가까워보임

- 이상

💡 범위

  • x축의 범위는 0 ~ 40
  • y축의 범위는 0 ~ 1000
  • 스케일이 맞지 않아서 눈으로 보는 것과 다른 결과가 나온 것이다.

👉🏻 기준을 맞춰라

출처: 혼공머딥 유튜브

- 바로 위 도미 데이터와는 92, (우리 눈에는 멀어보이지만) 그 다음으로 가까운 빙어 데이터와는 130 차이가 난다

- 눈으로 볼 땐 두 배 이상 차이나보이지만 실제로는 전혀 그렇지 않다

- 모두 x축 스케일과 y축 스케일이 맞지 않아서 일어난 일이다

✅ xlim()

  • 축의 범위를 수동으로 지정할 수 있다
더보기

pyplot의 xlim() 및 ylim() 함수는 그래프의 x축 및 y축의 범위를 지정하는 데 사용됩니다. 이 함수들을 사용하면 그래프의 특정 부분만을 확대하거나 축소할 수 있습니다.

간단한 설명을 제공하겠습니다:

  1. xlim() 함수:
    • xlim() 함수는 x축의 범위를 지정합니다. 즉, 어떤 x값을 보여줄지 결정합니다.
    • 예를 들어, plt.xlim(0, 10)은 x축을 0부터 10까지의 범위로 설정합니다.
  2. ylim() 함수:
    • ylim() 함수는 y축의 범위를 지정합니다. 즉, 어떤 y값을 보여줄지 결정합니다.
    • 예를 들어, plt.ylim(0, 20)은 y축을 0부터 20까지의 범위로 설정합니다.

- 무게가 생선을 구분하는 데 큰 영향을 끼친다

- 길이는 미치는 영향이 미미한 것

- 위 그림으로 판단해보면 이상한 도미는 빙어 데이터와 가깝게 나타난다

🧩 k-최근접 이웃의 특징

  • 가장 가까운 거리에 있는 주변 샘플을 찾음
  • 이때문에 특성의 거리가 다르면 문제가 된다
  • 스케일이 큰 특성에 절대적으로 영향을 받는다
    • 위의 경우 무게에 영향을 많이 받았다
  • 두 샘플의 스케일을 맞춰주는 과정이 필요하다!
    • 이렇게 특성의 스케일 영역을 맞춰줘야하는 알고리즘이 많다
    • 트리 기반 알고리즘들은 스케일에 영향을 받지 않는다
    • 딥러닝 알고리즘들은 특성 스케일에 영향을 받는다

👉🏻 표준 점수로 바꾸기

출처: 혼공머딥 유튜브

🧩 z점수

  • (특성 - 평균)/표준편차
더보기

표준점수 또는 Z-점수는 데이터의 분포를 평균이 0이고 표준편차가 1인 표준 정규 분포로 변환하는 데 사용되는 통계적 측도입니다. Z-점수는 각 데이터 포인트가 평균에서 얼마나 떨어져 있는지를 나타냅니다.

Z-점수를 계산하는 공식은 다음과 같습니다:


여기서 각 용어에 대한 설명은 다음과 같습니다:

- 특성 값: 데이터 포인트의 실제 값.
- 평균: 해당 특성의 모든 데이터 포인트의 평균값.
- 표준편차: 해당 특성의 모든 데이터 포인트의 표준편차.

간단한 예제를 통해 설명하겠습니다:

1. 평균과 표준편차 계산:
   - 특정 특성(예: 시험 점수)에 대한 평균과 표준편차를 계산합니다.

2. Z-점수 계산:
   - 개별 데이터 포인트의 값을 가져와서 해당 특성의 평균을 빼고, 그 결과를 해당 특성의 표준편차로 나누어 Z-점수를 계산합니다.

예를 들어, 시험 점수가 평균이 70이고 표준편차가 10인 경우, 점수가 80인 학생의 Z-점수는

이 됩니다. 이는 해당 학생의 시험 점수가 평균보다 1 표준편차만큼 더 높다는 것을 의미합니다.

Z-점수는 데이터를 표준화하여 서로 다른 단위를 가진 변수들을 비교하기 용이하게 만들어줍니다. 또한 표준 정규 분포의 특성을 갖기 때문에 통계적인 분석이나 비교에 용이합니다.

  • 지금은 처음이니까 수동으로 하지만 사이킷런에 해당 도구가 존재

- 길이 특성과 무게 특성의 평균을 따로 구해야 한다

- 전체 특성에 대한 평균

- 넘파이의 mean() 함수가 평균을, std() 함수가 표준편차를 구해준다

- 변환하고자 하는 배열을 넣고

- 축(axis)을 0으로 설정해 행을 따라 쭉 계산한다 (⬇️방향)

     - 1로 설정한다면 각 행마다의 평균을 따로 구해준다 (➡️방향)

- 길이 평균: 약 27, 무게 평균 약 454

- 길이 표준편차: 약 9, 무게 표준편차  약 323

✅ numpy의 broadcasting

- 우리가 구한 mean/std는 (1,2)크기

- train_input은 (36,2) 크기

     - 샘플이 36개, 특성이 2개

출처: 혼공머딥 유튜브

- mean / std를 모든 행에 적용해서 다 빼준다

     - (1,2)크기의 배열을 36번 복사해서 같은 크기의 배열로 만들어준 뒤 연산하지 않아도 된다

- 각 행 별로 뺀 값을 배열로 만들어준다

     - 똑같이 (36,2)크기의 배열이 존재

더보기

Numpy의 Broadcasting은 서로 다른 모양(shape)을 가진 배열 간에도 연산이 가능하도록 하는 매우 강력하면서 유연한 기능입니다. 이는 배열의 모양이 맞지 않더라도 자동으로 모양을 맞춰서 연산을 수행할 수 있게 해줍니다.

간단한 예제를 통해 설명하겠습니다:

import numpy as np

# 배열 생성
a = np.array([1, 2, 3])
b = 2

# Broadcasting 적용
result = a + b



여기서 `a`는 shape이 (3,)인 1차원 배열이고, `b`는 스칼라(0차원 배열)입니다. 하지만 Numpy는 자동으로 `b`를 (3,) 모양으로 확장(broadcast)하여 `a`와 같은 모양으로 만들고 각 요소별로 덧셈을 수행합니다. 결과로 `result`는 `[3, 4, 5]`가 됩니다.

다음은 Broadcasting이 동작하는 주요 규칙입니다:

1. 차원 수가 다르면 자동으로 차원을 맞춤: 두 배열의 차원 수가 다를 경우, 차원 수가 맞을 때까지 낮은 차원의 배열에 1을 추가합니다.
   - 예: (3,)과 (1,)의 경우, (3,).

2. 각 차원의 크기가 맞거나 한 배열의 크기가 1인 경우 연산 가능: 모든 차원에서 배열의 크기가 일치하거나 한 배열의 크기가 1이면 연산이 가능합니다.
   - 예: (3, 1)과 (3,)의 경우, (3, 3).

3. 크기가 1인 차원이 여러 개일 때도 가능: 배열의 크기가 1인 차원이 여러 개인 경우에도 Broadcasting이 가능합니다.
   - 예: (1, 3, 1)과 (3, 1)의 경우, (1, 3, 1)과 (1, 1, 3)으로 모양을 맞추어 연산 가능.

이러한 규칙을 활용하면 서로 다른 모양의 배열 간에도 산술 연산이나 함수 적용을 간편하게 수행할 수 있습니다. Broadcasting은 코드를 간결하게 작성하고 실행 속도를 향상시키는 데 도움이 됩니다.

- 메모리를 효율적으로 관리할 수 있다

👉🏻 수상한 도미 다시 표시하기

출처: 혼공머딥 유튜브

- 두 특성의 중심이 0에 맞춰져 있고 1 근처에서 퍼져 있는데이터

- 수상한 도미는 오른쪽 위 끝에 있음

- 훈련데이터를 표준점수로 바꿨기 때문에 여기에 맞추려면 이상한 도미도 표준점수 스럽게 만들어야 한다

- 하지만 수상한 도미는 데이터가 하나라 평균을 낼 수도 없고 표준편차를 낼 수도 없다

- 일반적으로 훈련세트에서 입력 데이터를 변환해서 훈련했으면 그 모델을 사용하기 위해서는 모델을 사용하려는 데이터도 훈련 세트와 똑같은 방식으로 변환해주어야 한다

더보기

모델을 훈련시킬 때 사용한 훈련 데이터와 모델을 평가하거나 예측할 때 사용되는 데이터는 동일한 변환을 거쳐야 한다는 것입니다. 이를 통해 모델이 일관된 방식으로 데이터를 처리하고 일반화할 수 있게 됩니다.

여기서 "변환"은 주로 특성 스케일링이나 정규화와 같은 과정을 의미합니다. 특히 k-최근접 이웃(KNN)과 같은 모델은 입력 데이터의 스케일에 민감할 수 있습니다. 이러한 변환이 필요한 이유와 어떻게 해야 하는지에 대해 쉽게 설명해보겠습니다.

1. 스케일에 대한 이해:
   - 일반적으로 특성들은 서로 다른 범위나 단위를 가질 수 있습니다. 예를 들어, 한 특성은 0부터 1까지의 값을 가지고 다른 특성은 0부터 100까지의 값을 가질 수 있습니다.

2. 모델의 민감성:
   - k-최근접 이웃 알고리즘은 데이터 간의 거리를 기반으로 예측을 수행합니다. 만약 한 특성의 값이 다른 특성에 비해 크게 벗어나면, 그 거리에 영향을 많이 받을 수 있습니다.

3. 훈련 데이터 변환:
   - 모델을 훈련할 때는 훈련 데이터를 사용하여 특성 스케일링 등의 변환을 적용합니다. 이는 주로 평균을 빼고 표준편차로 나누는 정규화(standardization)와 같은 방법을 사용합니다.

4. 모델 사용 데이터 변환:
   - 훈련 데이터로 모델을 훈련했다면, 모델을 사용하는 데이터도 같은 변환을 적용해주어야 합니다. 이는 테스트 데이터나 새로운 데이터에 대해서도 동일한 스케일을 적용한다는 것을 의미합니다.

간단히 말해, 모델을 훈련할 때 사용한 훈련 데이터의 특성 스케일링 방법을 알고 있어야 하고, 이와 동일한 방법으로 테스트 데이터나 새로운 데이터를 전처리해주어야 합니다. 이렇게 함으로써 모델이 새로운 데이터에 대해 일관된 예측을 수행할 수 있습니다.

- 훈련세트의 평균과 표준편차를 가지고 테스트세트의 표준 점수를 구해야 한다

더보기
  1. 훈련 세트 변환:
    • 훈련 세트의 특성에 대해 평균과 표준편차를 계산합니다.
    • 이 평균과 표준편차를 사용하여 훈련 세트의 모든 특성을 표준점수로 변환합니다.
  2. 테스트 세트 변환:
    • 테스트 세트의 각 특성에 대해 훈련 세트에서 계산한 평균을 빼고, 훈련 세트에서 계산한 표준편차로 나눠줍니다.
    • 이렇게 함으로써 테스트 세트도 훈련 세트와 동일한 스케일 변환을 적용받게 됩니다.

이렇게 하는 이유는 모델이 학습할 때 사용한 데이터의 특성 스케일을 알아야 하며, 모델이 새로운 데이터에 대해 일관된 예측을 수행하기 위해서는 새로운 데이터도 동일한 스케일링을 받아야 하기 때문입니다. 테스트 세트가 훈련 세트와 동일한 스케일링을 받지 않으면 모델이 테스트 세트에서 부정확한 예측을 할 수 있습니다.

- 모델을 평가하기 위해 준비된 테스트세트나 데이터의 변환은 훈련세트를 기준으로 한다

- 아까랑 비슷하게 그려지긴 했음

     - 데이터 포인트간의 상대적 거리는 유지

- 변한건 x축과 y축의 스케일

- 0을 중심으로 데이터가 고르게 퍼져있다

👉🏻 전처리 데이터에서 모델 훈련

- 변환된 데이터인 train_scaled, train_target을 fit()메서드에 집어 넣어 훈련

- 테스트 데이터의 표준 점수를 test_scaled에 저장

- score 메서드는 정확도를 반환하며, 표준화된 테스트 데이터와 실제 레이블(test_target)을 사용하여 평가를 수행

- input데이터는 스케일을 조정하지만 target데이터는 스케일을 조정하지 않는다

     - target은 정답

- 100% 다 맞았다

- 이상한 도미에 대한 예측 수행

- 도미로 예측

- 스케일 여부에 따라 이렇게 달라진것!

🧩 전처리

  • 입력 데이터를 머신러닝 모델이 사용할 수 있도록 적절히 가공하는 것

 

 

 

 

 

 

 

 

출처: https://youtu.be/kaCJ-knm8KU?si=EjLnY_R6iVOkF1UZ