클라이언트/ 서버/ 엔지니어 " 게임 개발자"를 향한 매일의 공부일지

나의 첫 머신러닝 3 - 마켓과 머신러닝 1 : k-최근접 이웃 모델로 생선 분류해보기 본문

인공지능/머신러닝

나의 첫 머신러닝 3 - 마켓과 머신러닝 1 : k-최근접 이웃 모델로 생선 분류해보기

huenuri 2024. 9. 27. 15:45

점심을 먹고 오후 공부를 시작해본다. 1-3장부터는 본격적으로 머신러닝 프로젝트를 다루게 된다. 하지만 오늘은 왜 이렇게 공부하는 게 더디고 생각도 행동도 느리며 하기가 싫은지 모르겠다.

1주일에 한두 번은 이렇게 열정이 낮아지는 시기가 있다. 특히 금요일은 더욱 그런 것 같다. 월요일과 금요일은 내게 열정이 가장 낮아지는 시기같다. 오늘의 이 위기를 잘 극복해보자. 무조건 빨리 하는 건 도움이 되지 않고 천천히 묵묵히 내가 해야 할 일을 하고 적당히 보상을 주는 것.. 그것이 슬럼프를 빨리 극복하는 길이다.


 

 

 

학습 목표

가장 간단한 머신러닝 알고리즘 중 하나인 k-최근접 이웃을 사용하여 2개의 종류를 분류하는 머신러닝 모델을 훈련한다.

 

 

이번 단원의 미션

 

한빛마켓은 살아있는 생선을 팔기 시작했는데, 머신러닝 엔지니어를 고용하며 다음과 같은 첫번째 임무를 내주었다. 생선 이름을 자동으로 알려주는 머신러닝을 만들고 싶어한다. 이제 이 문제를 머신러닝 초보 엔지니어 혼공머신과 함께 해결해보기로 하자.


 

 

 

생선 분류 문제

한빛 마켓에서 팔기 시작한 생선은 도미, 곤들메기, 농어, 강꼬치고기, 로치, 빙어, 송어이다. 이 생성들을 프로그램으로 분류한다고 가정하자. 어떻게 프로그램을 만들어야 할까?

김팀장은 혼공머신에게 생선 길이가 30cm 이상이면 도미라고 알려주었다. 그 이야기를 듣고 혼공머신은 이와 같은 파이썬 프로그램을 만들었다.

하지만 30cm보다 큰 생선이 무조건 도미라고 말할 수 없다. 또 도미의 크기가 모두 같을 리도 없다. 보통 프로그램은 누군가 정해준 기준대로 일을 한다. 반대로 머신러닝은 누구도 알려주지 않는 기준을 찾아서 일을 한다.


 

 

 

도미 데이터 준비하기

머신러닝은 어떻게 이런 기준을 스스로 찾을 수 있을까? 머신러닝은 여러 개의 도미 생선을 보면 스스로 어떤 생선이 도무인지 구분할 기준을 찾는다. 그렇다면 도미 생선을 많이 준비해야 할 것이다.

 

먼저 혼공머신은 머신러닝을 사용해 도미와 빙어를 구분하기로 했다. 

먼저 2개의 클래스를 준비해야 한다. 머신러닝에서 여러 개의 종류를 클래스라고 부른다. 그중 하나를 구별해 내는 문제를 분류, 2개의 클래스 중 하나를 고르는 문제를 이진 분류라고 한다.

 

 

 

도미 데이터를 이렇게 준비했다. 머신러닝에서는 데이터를 샘플이라고 표현하기도 한다. 리스트에서 첫번째 데이터는 생선의 길이를, 두번째 데이터는 생선의 무게를 나타내고 있다. 각 도미의 특징을 길이와 무게로 표현한 것인데 이러한 특징을 특성이라고 부른다.

 

이 도미 데이터를 보기 쉽도록 그래프로 그려보기로 하자.


 

 

 

 

길이를 x, 무게를 y축으로 정한 후 이 그래프에 점으로 표시했다. 이러한 그래프를 산점도라고 한다. 파이썬에서 과학 계산용 그래프를 그리는 대표적인 패키지는 맷플롯립(matplotlib)이다. 이 패키지를 임포트하고 산점도를 그리는 scatter() 함수를 사용했다.

길이가 커지면 무게가 올라감을 볼 수 있다. 이렇게 산점도 그래프가 일직선에 가까운 형태로 나타나는 경우를 선형적이라고 말한다.


 

 

 

빙어 데이터 준비하기

 

맷플로립에서 scatter() 함수를 연달아 사용하면 2개의 산점도를 한 그래프에 그릴 수 있다. 빙어 데이터와 도미 데이터를 한 공간 안에서 볼 수 있게 되었다. 빙어는 도미에 비해 길이도 무게도 매우 작다.

이 그래프를 통해 알 수 있는 건 빙어는 길이가 늘어나더라도 무게가 많이 늘지 않는다는 것이다. 그에 반해 도미는 길이에 따라 무게의 변화가 크다.


 

 

 

 

첫 번째 머신러닝 프로그램

 

먼저 간단하게 도미와 빙어를 하나를 합쳐보았다.

 

 

덧셈 연산을 사용하면 두 개의 리스트가 합쳐진다. 이 책에서 사용하는 머신러닝 패키지는 사이킷런이다. 이 패키지를 사용하려면 이처럼 각 특성의 리스트를 세로 방향으로 늘어뜨린 2차원 리스트를 만들어야 한다.

 

 

 

파이썬의 zip() 함수와 리스트 내포 구문을 사용하면 이렇게 2차원 리스트가 만들어진다. zip() 함수는 나열된 리스트에서 원소를 하나씩 꺼내주는 일을 한다. 

이렇게 길이와 무게가 함께 묶인 리스트가 만들어졌는데 이 리스트를 2차원 리스트라고 한다. 이제 준비할 것은 정답 데이터이다.


 

 

 

 

정답 데이터가 필요한 이유는 머신러닝은 어떤 것이 도미이고 빙어인지 알려주지 않으면 찾을 수 없기 때문이다. 머신러닝 알고리즘이 생선의 길이와 무게를 보고 도미와 빙어를 구분하는 규칙을 찾으려고 한다. 그러면 적어도 어떤 생선이 도미인지 빙어인지를 알려 주어야 한다.

대신 컴퓨터 프로그램은 문자를 직접 이해하지 못하므로 0과 1의 숫자로 표현한다. 도미와 빙어는 이진 분류로 되어 있기 때문에 덧셈과 곱셈 연산자를 사용해 이처럼 표현할 수 있다.

 

찾으려는 데이터를 1,그 외의 것을 0으로 놓는 것이다. 여기서는 도미를 찾는 것이므로 도미를 1로 놓았다.


 

 

 

 

클래스를 사용할 때는 괄호를 붙여서 클래스의 인스턴스를 만든다. 이 클래스 객체를 kn이라는 이름으로 저장했다. 그리고 앞서 만든 fish_data와 fish_target을 fit 메소드에 전달한다. 이런 과정을 머신러닝에서 훈련이라 하고, kn은 모델이라고 한다.

머신러닝 알고리즘을 구현한 프로그램을 모델이라고 부른다. 또는 프로그램이 아니러라도 알고리즘을 구체화하여 표현한 것을 모델이라고 부른다.

 

그리고 사이킷런에서 모델을 평가하는 메서드는 score()이다. 이 메서드는 0에서 1 사이의 값을 반환한다. 1은 모든 데이터를 정확하게 맞혔다는 것을 나타낸다. 이 값을 정확도라고 부른다.

우리는 알고리즘을 직접 짜지는 않고 이미 구현된 알고리즘을 불러와서 사용하는 일을 했다.


 

 

k-최근접 이웃 알고리즘

이 알고리즘은 어떤 데이터에 대한 답을 구할 때 주위의 다른 데이터를 보고 다수를 차지하는 것을 정답으로 사용한다.

 

 

이 그림에서 삼각형으로 표시된 새로운 데이터가 있다고 가정해보자. 이 삼각형은 도미와 빙어 중 어디에 속할까? 아마도 직관적으로 이 삼각형은 도미라고 판단할 것이다. 왜냐하면 삼각형 주변에 다른 도미 데이터가 많기 때문이다.

predict() 메서드는 새로운 데이터의 정답을 예측한다. fit() 메서드에서 2차원 리스트로 넣었던 것과 마찬가지도 predict() 메서드에서도 2차원 리스트로 넣어주어야 한다.

 

결과값은 1이라고 출력되었는데 이것은 도미이다. array로 출력된 것은 사이킷런이 넘파이라는 array로 반환하기 때문이다. kn 모델의 기본값은 5이다. 이 기준은 n_neighbors 매개변수로 바꿀 수 있다.


 

 

 

 

매개변수를 49로 지정하면 전체 데이터 중에서 판단을 하는데, 이중 도미가 35개를 차지하므로 어떤 데이터를 넣어도 무조건 도미라고 예측할 것이다. 그렇기에 정확도는 71%가 된다.

 


 

 

 

학습을 마치고

1시간 가까이 되는 강의를 들으며 책과 함께 읽고 필기하며 학습일지를 써보았다. 처음에 난 금방 공부가 끝날줄 알았는데 전혀 아니었다. 강의도 듣고 필기도 하고 정리하며 실습도 진행하면 한 소단원당 넉넉잡아 2시간 반은 걸리는 것 같다. 오늘부터 찬찬히 4일 이상 이 책과 함께 열심히 공부해보려고 한다.

책 선정을 정말 잘한 것 같다. 처음 오후 공부를 시작할 무렵에는 정말 하기 싫은 마음이 많았으나 어느새 흥미를 느끼고 재미있어졌다. 앞으로 있을 학습이 기대가 된다.

 

다음 포스트에서는 이제 여기서 배운 것들을 직접 코랩을 사용해 실습해볼 것이다.