파이썬/ai

[Ai,Python] K-nearest neighbor-1(데이터 전처리 및 모델 학습)

hojung 2022. 4. 5.
728x90
반응형

우리가 흔히 아는 딥러닝이라고 하는 것은 많은 데이터를 컴퓨터에게 집어 넣어 미래의 예측 값을 보다 정확하게 추론해내는 일종의 통계학이다. 그러러면 우리는 일단 컴퓨터를 학습시킬 많은 데이터들을 필요로 하는데 우리의 생활 속에서 발생하는 데이터들은 일정한 형식의 format을 가지고 있지도 않고 매우 불규칙하게 생기고 발생한다. 

그래서 우리는 엑셀, DBMS와 같이 데이터들을 관리하는 툴에서 데이터들을 추출해 컴퓨터에게 학습시키기 쉬운 형태의 데이터 형태로 바꿔주는 파이썬의 라이브러리들을 이용할 것이다. 

 

다음과 같은 데이터 셋이 존재한다고 하자 우리는 두 가지 물고기의 길이와 무게 정보를 이용해서 새로운 물고기의 길이와 무게 정보가 들어왔을 때 이 물고기가 두 물고기 중 어떤 물고기인지 판별하는 프로그램을 만들 것이다. 

 

우선 

1. column_Stack()

지금 현재 데이터의 생김새를 보면 길이와 무게가 따로 떨어져있다. 하지만 한 물고기의 길이와 무게는 한 쌍의 데이터로 취급되어질 필요가 있다. 

이 때 사용하는 파이썬의 numpy라이브러리의 함수가 바로 column_Stack()함수이다. 이 함수는 서로 다른 두 가지의 배열을 매칭 시켜주는 역할을 한다. 

다음과 같이 numpy라이브러리를 np라는 이름으로 import를 하고 np에 존재하는 column_stack함수를 이용해서 두 데이터 셋을 합쳐주면 다음과 같은 결과가 나온다. '

 

 

2. 데이터를 trainning set과 test set으로 나누기

어떠한 데이터들로 한 모델을 학습시키다보면 이 모델이 정말 잘 학습되었는지 확인을 해야한다. 따라서 우리는 데이터들에 해당하는 정답을 알고 있는 상태에서 데이터를 일정한 비율로 학습데이터와 시험 데이터로 나누게 된다. 이 비율은 임의의 비율로써 학습이 잘되었다면 test data에서도 정답을 잘 맞출 것이다. 나는 총 49개의 데이터로 학습을 시키는데 이 중 도미의 개수는 35, 빙어의 개수는 14이다. 36개는 trainning data, 13개는 test data로 나누도록 하겠다. 모든 데이터를 두 가지 종류로 거기다 36와 13라는 집합으로 나누는 데에는 고려할 사항이 좀 있다.

  • 첫 번째는 이 데이터들이 랜덤하게 선정되어야 한다는 것이다. 
  • 두 번째는 랜덤하게 선정된 와중에도 총 데이터의 비율대로 유지를 해야한다는 것이다. 즉 test data set의 집합의 데이터가 어느 한 쪽으로 치우치면 안된다는 것이다. 

첫 번째 문제를 해결하기 위해선 numpy 배열의 random함수를 사용해야한다. np.random(seed값)

을 넣어주면 seed에 따라 데이터들이 랜덤하게 배분된다.  코드를 살펴보겠다. 

이 작업의 첫 번째 줄은 현재 1의 값을 35개 가진 배열과 0의 값을 14개 가진 배열을 concatenate함수를 사용해서 두 배열을 합쳐주는 과정을 진행하고 있다. 35개와 14개라 어디서 많이 들어본 느낌이 난다.

아까 우리가 도미의 개수가 35개 빙어의 개수가 14개였다. 따라서 fish_target이라는 배열과 아까 column_Stack()이라는 함수를 사용하여 만든 fish_data라는 배열을 매칭 시켰을 때 target값이 1이면 도미 0이면 빙어라고 즉 정답을 제공해주는 것이다.  

그 후 input_arr은 fish_data를 넣은 numpy ndarray를 넣어주고 

target_arr에는 fish_target을 넣은 numpy ndarray를 넣어준다. 그 후 첫 번째 문제를 해결하기 위해 49개의 인덱스를 np.random함수를 사용해서 무작위로 섞어준다. 이 떄 seed값을 어떤 값이 들어가던 상관없다. 

 

그렇게 섞인 인덱스를 이제는 적용을 할 것이다. 

아래 코드를 살펴보면 무작위로 섞인 인덱스의 35까지는 train_input과 train_target에 들어가고 36부터 49는 test_input과 test_target에 들어가는 것을 확인할 수 있다.

하지만 위의 방법은 너무 복잡하다! 그래서 더 쉽게 해결할 수 있는 방법이 있는 데 바로 

scikit-learn라이브러리의 train_test_split함수를 이용하는 것이다. 이 함수는 우리가 앞서 했던 인덱스를 만들고 섞고 이런 과정 하나 없이 train_input, test_input, train_target, test_target 총 네 개의 배열에 알아서 값들을 랜덤하게 할당해준다. 물론 train_test_split함수의 파라미터로 우리가 생성했던 fish_data와 fish_target배열을 넣어주어야 한다.

 

그 후 나눠진 결과 배열들의 모습을 살펴보면 다음과 같다. 

 

하지만 이제 우리는 두 번쨰 문제를 해결해야 한다. test_target_split함수에 stratify라는 매개변수를 주지 않으면 우리가 앞서 생성했던 target의 비율대로 섞이지 않는 문제가 발생한다. 따라서 stratify라는 매개변수를 준 후 수행하면 다음과 같다. 

두 개의 test_target을 살펴보면 하나는

1 0 0 0 1 1 1 1 1 1 1 1 1 로 1이 10개 0이 3개이다. 

다른 하나는 

0 0 1 0 1 0 1 1 1 1 1 1 1 로 1이 9개 0이 4개이다. 

아까 비율을 살펴보면 

아까 도미와 빙어의 개수가 35와 14였으므로 2.5대 1의 비율을 유지한다. 

stratify매개변수를 준 후가 이 비율에 근접하게 나눠진 것을 확인할 수 있다. 

2.  knn 모델 학습

이제 모델을 학습시켜 볼 것이다. 

scikit-learn라이브러리의 KNeighborsClassifier함수를 import를 해주고 이 함수를 통해 knn 모델을 만든다. 

함수를 통해 knn모델을 만들고 fit 함수를 통해 knn모델에 데이터를 넣어줘서 훈련을 시킨다. 

그 후 score함수를 통해 test_input과 test_target을 넣어주면 test data에서 몇 개의 결과를 맞췄는 지 나오게 된다. 

matplotlib라이브러리를 사용해서 25, 150의 데이터를 하나 넣어서 그래프를 그리면 다음과 같은 그래프가 나온다. 

728x90
반응형

댓글