Chapter 01. 나의 첫 머신러닝¶
- 학습목표
- 인공지능, 머신러닝, 딥러닝 차이점을 이해한다.
- 구글 코랩 사용법을 배운다.
- 첫 번째 머신러닝 프로그램을 만들고 머신러닝의 기본 작동 원리를 이해한다.
01-1 인공지능과 머신러닝, 딥러닝¶
이번 절에서는 인공지능, 머신러닝, 딥러닝이 무엇인지 알아보고 그 차이를 살펴본다.
- 인공지능이란
인공지능(artificial intelligence)은 사람처럼 학습하고 추론할 수 있는 지능을 가진 컴퓨터 시스템을 만드는 기술이다. 인공지능의 역사는 약 80년 남짓 되었지만 인류는 훨씬 더 오래전부터 지능적인 시스템을 생각했다. 많은 과학자가 참여한 1956년 다트머스 AI 컨퍼런스에서는 인공지능에 대한 장밋빛 전망이 최고조에 도달했다. 이 시기를 인공지능 태동기라고 한다. 그 이후 인공지능 황금기가 도래했다. 흔히 영화 속의 인공지능은 인공일반지능 artificial general intelligence 혹은 강인공지능 strong AI 이라고 부르는 인공지능이다. 영화<터미네이터>의 스카이넷처럼 사람과 구분하기 어려운 지능을 가진 컴퓨터 시스템이 인공일반지능이다. 반면 현실에서 우리가 마주하고 있는 인공지능은 약인공지능 Week AI 이다. 약인공지능은 아직까지는 특정 분야에서 사람의 일을 도와주는 보조 역할만 가능하다. 예를 들면 음성비서, 자율주행 자동차, 음악 추천, 기계 번역 등이다. 또 이세돌과 바둑 시합을 한 알파고가 좋은 예이다. 그럼 언제 인공일반지능에 도달할 수 있을까? 아직은 아무도 그 시기를 정확히 알 수 없지만 가능성에 대해서는 대체로 긍정적이다. 그렇지만 가까운 미래에 이런 기술이 도래하리라 낙관하지는 않았으면 좋겠다. 여기에는 거품이 끼어 있을 수 있다. 앞서 언급했듯이 과거에도 이 분야에서는 성급하게 장밋빛 청사진을 제시하다가 실패한 경우가 있기 때문이다.
- 머신러닝이란
머신러닝(machine learning)은 규칙을 일일이 프로그래밍하지 않아도 자동으로 데이터에서 규칙을 학습하는 알고리즘을 연구하는 분야이다. 인공지능의 하위 분야 중에서 지능을 구현하기 위한 소프트웨어를 담당하는 핵심 분야이다. 머신러닝은 통계학과 깊은 관련이 있다. 통계학에서 유래된 머신러닝 알고리즘이 많으며 통계학과 컴퓨터 과학 분야가 상호 작용하면서 발전하고 있다. 대표적인 오픈소스 통계 소프트웨어인 R에는 다양한 머신러닝 알고리즘이 구현되어 있다. 하지만 최근 머신러닝의 발전은 통계나 수학 이론보다 경험을 바탕으로 발전하는 경우도 많다. 컴퓨터 과학 분야가 이런 발전을 주도하고 있다. 컴퓨터 과학 분야의 대표적인 머신러닝 라이브러리는 사이킷런 scikit-learn 이다. 사이킷런 라이브러리는 파이썬 API를 사용하는데 파이썬 언어는 배우기 쉽고 컴파일하지 않아도 되기 때문에 사용하기 편리하다. 머신러닝 분야에 관심이 높아지면서 파이썬과 함께 사이킷런 라이브러리가 큰 인기를 얻고 있다. 이제는 사이킷런 외에 대표적인 다른 머신러닝 라이브러리를 찾아보기 힘들다.
파이썬으로 print('Hello world')명령을 출력할 수 있다면 누구나 조금만 배워 머신러닝 프로그램을 만들 수 있다. 사이킷런 라이브러리에서 제공하는 클래스와 함수를 사용하여 필요한 작업을 수행할 수 있다. 당연하지만 사이킷런에 모든 머신러닝 알고리즘이 포함되어 있지는 않다. 연구자들은 새로운 알고리즘을 끊임없이 개발하여 발표한다. 많은 사람이 이를 검증하고 사용해 본 다음 장단점을 파악하게 된다. 어느 정도 시간이 지나서 이런 알고리즘이 유익하다고 증명되어 널리 사용하게 되면 사이킷런 라이브러리 개발자들이 이 알고리즘을 라이브러리에 추가한다. 그러므로 머신러닝 라이브러리에 포함된 알고리즘들은 안정적이며 성능이 검증되어 있다. 비교적 안심하고 사용할 수 있는 이유이다. 프로그래머가 직접 알고리즘을 구현하느라 힘들게 프로그램을 짤 필요가 없다. 사이킷런이 있기 전까지 머신러닝 기술은 대부분 폐쇄적인 코드와 라이브러리로 토용ㅇ되었다. 해당 분야에 대해 전문교육을 이수하거나 비싼 비용을 지불하고 구매를 해야 했다. 하지만 사이킷런과 같은 오픈소스 라이브러리의 발전 덕분에 머신러닝 분야는 말 그대로 폭발적으로 성장했다. 파이썬 코드를 다룰 수 있다면 누구나 머신러닝 알고리즘을 무료로 손쉽게 제품에 활용할 수 있다. 덕분에 현대의 개발자는 머신러닝 알고리즘을 이해하고 사용할 수 있어야 한다. 이런 현상으로 인해 새로운 이론과 기술은 직접 코드로 구현되고 통용되어야 그 가치를 입증할 수 있게 되었다. 코드로 구현되어 성능을 입증하지 못하면 탁상공론에 지나지 않고 사람들의 주목을 끌기 어렵다. 이런 기조는 딥러닝 분야에서 더욱 증폭되었다.
- 딥러닝이란
많은 머신러닝 알고리즘 중에 인공 신경망 artificial neural network을 기반으로 한 방법들을 통칭하여 딥러닝 deep learning이라고 부른다. 종종 사람들은 인공 신경망과 딥러닝을 크게 구분하지 않고 사용한다. 국내에서는 2016년 이세돌과 알파고의 대국으로 인해 딥러닝에 대한 관심이 크게 높아졌다. 하지만 앞에서 소개했듯이 딥러닝은 2010년 초반부터 이렇게 새로운 혁명을 준비하고 있었다. LeNet-5 나 AlexNet과 같이 인공 신경망이 이전과 다르게 놀라운 성능을 달성하게 된 원동력으로 크게 세 가지를 꼽을 수 있다. 복잡한 알고리즘을 훈련할 수 있는 풍부한 데이터와 컴퓨터 성능의 향상, 그리고 혁신적인 알고리즘 개발이다. 인공지능에 대한 과거의 시도와 달리 최근의 딥러닝 발전은 매우 긍정적이고 지속 가능해 보인다. 이런 오픈소스 머신러닝 라이브러리의 영향력을 눈치챘던 것일까? 2015년 구글은 딥러닝 라이브러리인 텐서플로 TensorFlow를 오픈소르로 공개했다. 텐서플로는 공개와 동시에 큰 인기를 얻었으며 아직까지 가장 널리 사용되는 딥러닝 라이브러리이다. 텐서플로는 공개와 동시에 큰 인기를 얻었으며 아직까지 가장 널리 사용되는 딥러닝 라이브러리이다. 페이스북도 2018년 파이토치PyTorch딥러닝 라이브러리를 오픈소스로 발표했다. 이 라이브러리들의 공통점은 인공 신경망 알고리즘을 전문으로 다루고 있다는 것과 모두 사용하기 쉬운 파이썬 API를 제공한다는점이다.
마무리¶
- 키워드로 끝내는 핵심 포인트
- 인공지능은 사람처럼 학습하고 추론할 수 있는 지능을 가진 시스템을 만드는 기술이다. 인공지능은 강인공지능과 약인공지능으로 나눌 수 있다.
- 머신러닝은 규칙을 프로그래밍하지 않아도 자동으로 데이터에서 규칙을 학습하는 알고리즘을 연구하는 분야이다. 사이킷런이 대표적인 라이브러리 이다.
- 딥러닝은 인경 신경망이라고도 하며, 텐서플로와 파이토치가 대표적인 라이브러리이다.
01-3 마켓과 머신러닝¶
생선 분류 문제¶
한빛 마켓에서 팔기 시작한 생선은 '도미','곤들매기','농어','강꼬치고기','로치','빙어','송어'이다. 이 생선들은 물류 센터에 많이 준비되어 있다. 이 생선들을 프로그램으로 분류한다고 가정해보자. 어떻게 프로그램을 만들어야 할까?
- 생선 데이터 [캐글에 공개된 데이터셋] 캐글은 2010년에 설립된 전 세계에서 가장 큰 머신러닝 경연 대회 사이트이다. 대회 정보뿐만 아니라 많은 데이터와 참고 자료를 제공한다.
아무래도 생선을 분류하는 일이니 생선의 특징을 알면 쉽게 구분 할 수 있다.
- 생선 길이가 30cm 이상이면 도미 이다. 이것으로 파이썬 프로그램을 만들어보자.
# if fish_length >= 30:
# print("도미")
하지만 30cm보다 큰 생선이 무조건 도미라고 말할 수 없다. 또 도미의 크기가 모두 같을 리도 없다. 물론 고래와 새우처럼 현격히 차이가 있다면 길이만으로 둘 중 하나를 고르는 프로그램을 만들 수 있을 것이다. 하지만 판매하는 생선은 이렇게 절대 바뀌지 않을 기준을 정하기 어렵다. 그럼 이 문제를 머신러닝으로 어떻게 해결 할수 있을까? 보통 프로그램은 '누군가 정해준 기준대로 일'을 한다. 반대로 머신러닝은 누구도 알려주지않는 기준을 찾아서 일을 한다. 다시 말해 누가 말해주지 않아도 머신러닝은 "30~40cm 길이의 생선은 도미이다"라는 기준을 찾는것이다. 머신러닝은 기준을 찾을 뿐만 아니라 이 기준을 이용해 생선이 도미인지 아닌지 판별할 수도 있다.
도미 데이터 준비하기
- 도미와 빙어를 구분하기
- http://bit.ly/bream_list (35마리의 도미를 준비, 저울로 잰 도미의 길이 cm 와 무게 g 을 파이썬 리스트로 만들면 아래와 같다.
bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0,
31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0,
35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0]
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0,
500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0,
700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]
리스트에서 첫 번째 도미의 길이는 25.4 cm, 무게는 242.0g이고 두 번째 도미의 길이는 26.3cm, 무게는 290.0g과 같은 식이다. 각 도미의 특징을 길이와 무게로 표현한 것이다. 이런 특징을 특성 feature 이라고 부른다. 두 특성을 숫자로 보는 것보다 그래프로 표현하면 데이터를 잘 이해할 수 있고 앞으로 할 작업에 대한 힌트를 얻을 수도 있다. 길이를 x축으로 하고 무게를 y축으로 정하자. 그 다음 각 도미를 이 그래프에 점으로 표시해 보자. 이런 그래프를 산점도 scatter plot 라고 부른다. 파이썬에서 과학계산용 그래프를 그리는 대표적인 패키지는 맷플롯립 matplotlib이다. 이 패키지를 임포트하고 산점도를 그리는 scatter()함수를 사용해 보자. 임포트 import란 따로 만들어둔 파이썬 패키지(함수 묶음)를 사용하기 위해 불러오는 명령이다.
import matplotlib.pyplot as plt # matplotlib의 pylot 함수를 plt로 줄여서 사용
plt.scatter(bream_length, bream_weight)
plt.xlabel('length') # x축은 길이
plt.ylabel('weight') # y축은 무게
plt.show()
- xlabel()과 ylabel()은 각각 x축과 y축의 이름을 화면에 표시한다. show()함수는 준비된 그래프를 화면에 출력한다.
도미 35마리를 2차원 그래프에 점으로 나타냈다. x축은 길이, y축은 무게이다. 2개의 특성을 사용해 그린 그래프이기 때문에 2차원 그래프라고 말한다. 생선의 길이가 길수록 무게가 많이나간다고 생각하면 이 그래프 모습은 매우 자연스럽다. 이렇게 산점도 그래프가 일직선에 가까운 형태로 나타나는 경우를 선형 linear적이라고 말한다. 머신러닝에서는 선형이란 단어가 종종 등장한다. 도미 데이터가 준비되었으니 다음으로 빙어 데이터를 준비해보자.
빙어 데이터 준비하기
- http://bit.ly/smelt_list (빙어데이터 출처)
smelt_length = [9.8, 10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]
smelt_weight = [6.7, 7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]
숫자를 보고 금방 눈치챌 수 있듯이 빙어는 크기도 작고 무게도 가볍다. 빙어 그래프도 그려보자. 맷플롯립에서 2개의 산점도를 한 그래프로 그리는 것은 아주 간단하다. 다음처럼 scatter()함수를 연달아 사용한다.
plt.scatter(bream_length, bream_weight)
plt.scatter(smelt_length, smelt_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
맷플롯립은 친절하게 2개의 산점도를 색깔로 구분해서 나타낸다. 주황색 점이 빙어의 산점도이다. 빙어는 도미에 비해 길이도 무게도 매우 작은것을 확인 했다. 빙어도 도미와 비슷하게 길이와 무게가 비례하지만 늘어나는 정도가 조금 다르다. 빙어는 길이가 늘어나더라도 무게가 많이 늘지 않는다. 따라서 빙어의 산점도도 선형적이지만 무게가 길이에 영향을 덜 받는다고 볼 수 있다. 이런 특성 간의 관계에 대해서는 2장에서 자세히 알아본다. 도미와 빙어 데이터를 모두 준비했고 산점도도 그려 보았다. 이제 이 두 데이터를 스스로 구분하기 위한 첫 번째 머신러닝 프로그램을 만들어 보자.
첫 번째 머신러닝 프로그램¶
여기에서는 가장 간단하고 이해하기 쉬운 k-최근접 이웃 k-Nearest Neighbors 알고리즘을 사용해 도미와 빙어 데이터를 구분해 보겠다. k-최근접 이웃 알고리즘을 사용하기 전에 앞에서 준비했던 도미와 빙어 데이터를 하나의 데이터로 합친다. 파이썬에서는 다음처럼 두 리스트를 더하면 하나의 리스트로 만들어 준다.
length = bream_length + smelt_length
weight = bream_weight + smelt_weight
아준 간단하게 두 리스트를 하나로 합쳤다. 이제 length와 weight 리스트는 다음과 같다. 이 책에서 사용하는 머신러닝 패키지는 사이킷 런 scikit-learn이다. 이 패키지를 사용하려면 다음처럼 각 특성의 리스트를 세로 방향으로 늘어뜨린 2차원 리스트를 만들어야 한다. 이렇게 만드는 가장 쉬운 방법은 파이썬의 zip() 함수와 리스트 내포 list comprehension 구문을 사용하는 것이다. zip()함수는 나열된 리스트 각각에서 하나씩 원소를 꺼내 반환한다. zip()함수와 리스트 내포 구문을 사용해 length와 weight 리스트를 2차원 리스트로 만들어 본다.
fish_data = [[l, w] for l, w in zip(length, weight)]
for문은 zip()함수로 length와 weight 리스트에서 원소를 하나씩 꺼내어 l과 w에 할당한다. 그러면 [l, w]가 하나의 원소로 구성된 리스트가 만들어진다. 예상대로 fish_data가 만들어졌는지 출력해서 확인해 보자.
print(fish_data)
[[25.4, 242.0], [26.3, 290.0], [26.5, 340.0], [29.0, 363.0], [29.0, 430.0], [29.7, 450.0], [29.7, 500.0], [30.0, 390.0], [30.0, 450.0], [30.7, 500.0], [31.0, 475.0], [31.0, 500.0], [31.5, 500.0], [32.0, 340.0], [32.0, 600.0], [32.0, 600.0], [33.0, 700.0], [33.0, 700.0], [33.5, 610.0], [33.5, 650.0], [34.0, 575.0], [34.0, 685.0], [34.5, 620.0], [35.0, 680.0], [35.0, 700.0], [35.0, 725.0], [35.0, 720.0], [36.0, 714.0], [36.0, 850.0], [37.0, 1000.0], [38.5, 920.0], [38.5, 955.0], [39.5, 925.0], [41.0, 975.0], [41.0, 950.0], [9.8, 6.7], [10.5, 7.5], [10.6, 7.0], [11.0, 9.7], [11.2, 9.8], [11.3, 8.7], [11.8, 10.0], [11.8, 9.9], [12.0, 9.8], [12.2, 12.2], [12.4, 13.4], [13.0, 12.2], [14.3, 19.7], [15.0, 19.9]]
첫 번쨋 생선의 길이 25.4cm와 무게 240.0g이 하나의 리스트를 구성하고 이런 리스트가 모여 전체 리스트를 만들었다. 이런 리스트를 2차원 리스트 혹은 리스트의 리스트라고 부른다. 생선 49개의 길이와 무게를 모두 준비했다. 마지막으로 준비할 데이터는 정답 데이터이다. 즉 첫 번째 생선은 도미이고, 두 번째 생선도 도미라는 식으로 각각 어떤 생선인지 답을 만드는 것이다. 왜 이런 작업이 필요할까? 머신러닝 알고리즘이 생선의 길이와 무게를 보고 도미와 빙어를 구분하는 규칙을 찾기를 원한다. 그렇게 하려면 적어도 어떤 생선이 도미인지 빙어인지를 알려주어야 한다. 만약 스무고개를 하는데 고개마다 답을 알려주지 않는 다면 정답을 맞힐 수 없는 것과 비슷하다. 머신러닝은 물론이고 컴퓨터 프로그램은 문자를 직접 이해하지 못한다. 대신 도미와 빙어를 숫자 1과 0으로 표현해 보겠다. 예를 들어 첫 번째 생선은 도미이므로 1이고 마지막 생선은 빙어이므로 0이 된다. 앞서 도미와 빙어를 순서대로 나열했디 때문에 정답 리스트는 1이 35번 등장하고 0이 14번 등장하면 된다. 곱셈 연산자를 사용하면 파이썬 리스트를 간단하게 반복시킬 수 있다.
fish_target = [1] * 35 + [0] * 14
print(fish_target)
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
- 머신러닝에서 2개를 구분하는 경우 찾으려는 대상을 1로 놓고 그 외에는 0으로 놓는다. 위의 예는 도미를 찾는 대상으로 정의했기 때문에 도미를 1로 놓고 빙어를 0으로 놓았다. 반대로 빙어를 찾는 대상으로 놓고 빙어를 1로 놓아도 된다.
이제 사이킷런 패키지에서 k-최근접 ㅣ웃 알고리즘을 구현한 클래식인 KNeighborsClassifier를 임포트 한다.
# !pip3 install KNeigborsClassifier
from sklearn.neighbors import KNeighborsClassifier
- (파이썬에서 패키지나 모듈 전체를 임포트하지 않고 특정 클래스만 임포트하려면 import ~ import 구문을 사용한다.)
임포트한 KNeighborsClassifier 클래스의 객체를 먼저 만든다.
kn = KNeighborsClassifier()
이 객체에 fish_data와 fish_target을 전달하여 도미를 찾이 위한 기준을 학습시킨다. 이런 과정을 머신러닝에서는 훈련 training이라고 부른다. 사이킷런에서 fit()메서드가 이런 역할을 한다. 이 메서드에 fish_data 와 fish_target을 순서대로 전달해 보자.
kn.fit(fish_data, fish_target)
KNeighborsClassifier()
fit() 메서드는 주어진 데이터로 알고리즘을 훈련시킨 뒤 훈련한다. 이제 객체(또는 모델)kn이 얼마나 잘 훈련되었는지 평가해 보겠다. 사이킷런에서 모델을 평가하는 메서드는 score()메서드이다. 이 메서드에서 0에서 1사이의 값을 반환한다. 1은 모든 데이터를 정확히 맞혔다는 것을 나타낸다. 예를 들어 0.5라면 절반만 맞혔다는 의미이다.
kn.score(fish_data, fish_target)
1.0
모든 fish_data의 답을 정확히 맞혔다. 이 값을 정확도 accuracy라고 부른다. 즉 이 모델은 정확도가 100%이며 도미와 빙어를 완벽하게 분류했다.
k-최근접 이웃 알고리즘
앞에서 첫 번째 머신러닝 프로그램을 성공적으로 만들었다. 여기에서 사용한 알고리즘은 k-최근접 이웃이다. 이 알고리즘에 대해 조금 더 자세히 알아보도록 하겠다. k-최근접 이웃 알고리즘은 매우 간단하다. 어떤 데이터에 대한 답을 구할 때 주위의 다른 데이터를 보고 다수를 차지하는 것을 정답으로 사용한다. 마치 근묵자흑과 같이 주위의 데이터로 현재 데이터를 판단하는 것이다.
kn.predict([[30, 600]])
array([1])
predict() 메서드는 새로운 데이터의 정답을 예측한다. 이 메서드도 앞서 fit() 메서드와 마찬가지로 리스트의 리스트를 전달해야 한다. 이렇게 생각하면 k-최근접 이웃 알고리즘을 위해 준비해야 할 일은 데이터를 모두 가지고 있는 게 전부이다. 새로운 데이터에 대해 예측할 때는 가장 가까운 직선거리에 어떤 데이터가 있는지를 살피기만 하면 된다. 단점은 k-최근접 이웃 알고리즘의 이런 특징 때문에 데이터가 아주 많은 경우 사용하기 어렵다. 데이터가 크기 때문에 메모리가 많이 필요하고 직선거리를 계산하는 데도 많은 시간이 필요하다. 사이킷런의 KNeighborsClassifier 클래스도 마찬가지이다. 이 클래스는 _fit_X 속성에 우리가 전달한 fish_data를 모두 가지고 있다. 또 _y 속성에 fish_target을 가지고 있다.
print(kn._fit_X)
[[ 25.4 242. ] [ 26.3 290. ] [ 26.5 340. ] [ 29. 363. ] [ 29. 430. ] [ 29.7 450. ] [ 29.7 500. ] [ 30. 390. ] [ 30. 450. ] [ 30.7 500. ] [ 31. 475. ] [ 31. 500. ] [ 31.5 500. ] [ 32. 340. ] [ 32. 600. ] [ 32. 600. ] [ 33. 700. ] [ 33. 700. ] [ 33.5 610. ] [ 33.5 650. ] [ 34. 575. ] [ 34. 685. ] [ 34.5 620. ] [ 35. 680. ] [ 35. 700. ] [ 35. 725. ] [ 35. 720. ] [ 36. 714. ] [ 36. 850. ] [ 37. 1000. ] [ 38.5 920. ] [ 38.5 955. ] [ 39.5 925. ] [ 41. 975. ] [ 41. 950. ] [ 9.8 6.7] [ 10.5 7.5] [ 10.6 7. ] [ 11. 9.7] [ 11.2 9.8] [ 11.3 8.7] [ 11.8 10. ] [ 11.8 9.9] [ 12. 9.8] [ 12.2 12.2] [ 12.4 13.4] [ 13. 12.2] [ 14.3 19.7] [ 15. 19.9]]
print(kn._y)
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
실제로 k-최근접 이웃 알고리즘은 무언가 훈련되는 게 없는 셈이다. fit() 메서드에 전달한 데이터를 모두 저장하고 있다가 새로운 데이터가 등장하면 가장 가까운 데이터를 참고하여 도미인지 빙어인지를 구분한다. 그럼 가까운 몇개의 데이터를 참고할까? 이는 정하기 나름이다. KNeighborsClassifier 클래스의 기본값은 5이다. 이 기준은 n_neighbors 매개변수로 바꿀 수 있다. 예를 들어 다음과 같이 해보자.
kn49 = KNeighborsClassifier(n_neighbors=49) # 참고 데이터를 49개로 한 kn49 모델
가장 가까운 데이터 49개를 사용하는 k-최근접 이웃 모델에 fish_data를 적용하면 fish_data에 있는 모든 생선을 사용하여 예측하게 된다. 다시 말하면 fish_data의 데이터 49개 중에 도미가 35개로 다수를 차지하므로 어떤 데이터를 넣어도 무조건 도미로 예측할 것이다.
kn49.fit(fish_data, fish_target)
kn49.score(fish_data, fish_target)
0.7142857142857143
fish_data에 있는 생선 중에 도미가 35개이고 빙어가 14개 이다. kn49모델은 도미만 올바르게 맞히기 때문에 다음과 같이 정확도를 계산하면 score() 메서드와 같은 값을 얻을 수 있다.
print(35/49)
0.7142857142857143
확실히 n_neighbors 매개변수를 49로 두는 것은 좋지 않다. 기본값을 5로 하여 도미를 완벽하게 분류한 모델을 사용한다.
도미와 빙어 분류 [문제해결 과정]¶
도미와 빙어를 구분하기 위해 첫 번째 머신러닝 프로그램을 만들었다. 먼저 도미 35마리와 빙어 14마리의 길이와 무게를 측정해서 파이썬 리스트로 만든다. 그 다음 도미와 빙어 데이터를 합쳐 리스트의 리스트로 데이터를 준비했다. 사용한 첫 번째 머신러닝 알고리즘은 k-최근접 이웃 알고리즘이다. 사이킷런의 k-최근접 이웃 알고리즘은 주변에서 가장 가까운 5개의 데이터를 보고 다수결의 원칙에 따라 데이터를 예측한다. 도미와 빙어를 분류하는 문제를 풀면서 KNeighborsClassifier 클래스의 fit(), score(), precidt() 메서드를 사용해 보았다. 끝으로 k-최근접 이웃 알고리즘의 특징을 알아보았다.
전체 소스 코드 (https://bit.ly/hg-01-3) 이 절의 코드를 바로 열어 볼 수 있음.
# 마켓과 머신러닝
# 생선 분류 문제
# 도미 데이터 준비하기
bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0,
31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0,
35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0]
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0,
500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0,
700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]
import matplotlib.pyplot as plt # matplotlib의 pylot 함수를 plt로 줄여서 사용
plt.scatter(bream_length, bream_weight)
plt.xlabel('length') # x축은 길이
plt.ylabel('weight') # y축은 무게
plt.show()
# 빙어 데이터 준비하기
smelt_length = [9.8, 10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]
smelt_weight = [6.7, 7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]
# 첫 번째 머신 러닝 프로그램
length = bream_length + smelt_length
weight = bream_weight + smelt_weight
fish_data = [[l, w] for l, w in zip(length, weight)]
print(fish_data)
fish_target = [1] * 35 + [0] * 14
print(fish_target)
from sklearn.neighbors import KNeighborsClassifier
kn = KNeighborsClassifier()
kn.fit(fish_data, fish_target)
kn.score(fish_data, fish_target)
# k-최근접 이웃 알고리즘
plt.scatter(bream_length, bream_weight)
plt.scatter(smelt_length, smelt_weight)
plt.scatter(30, 600, marker= '^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
kn.predict([[30, 600]])
print(kn._fit_X)
print(kn._y)
kn49 = KNeighborsClassifier(n_neighbors=49)
kn49.fit(fish_data, fish_target)
kn49.score(fish_data, fish_target)
print(35/49)
[[25.4, 242.0], [26.3, 290.0], [26.5, 340.0], [29.0, 363.0], [29.0, 430.0], [29.7, 450.0], [29.7, 500.0], [30.0, 390.0], [30.0, 450.0], [30.7, 500.0], [31.0, 475.0], [31.0, 500.0], [31.5, 500.0], [32.0, 340.0], [32.0, 600.0], [32.0, 600.0], [33.0, 700.0], [33.0, 700.0], [33.5, 610.0], [33.5, 650.0], [34.0, 575.0], [34.0, 685.0], [34.5, 620.0], [35.0, 680.0], [35.0, 700.0], [35.0, 725.0], [35.0, 720.0], [36.0, 714.0], [36.0, 850.0], [37.0, 1000.0], [38.5, 920.0], [38.5, 955.0], [39.5, 925.0], [41.0, 975.0], [41.0, 950.0], [9.8, 6.7], [10.5, 7.5], [10.6, 7.0], [11.0, 9.7], [11.2, 9.8], [11.3, 8.7], [11.8, 10.0], [11.8, 9.9], [12.0, 9.8], [12.2, 12.2], [12.4, 13.4], [13.0, 12.2], [14.3, 19.7], [15.0, 19.9]] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[[ 25.4 242. ] [ 26.3 290. ] [ 26.5 340. ] [ 29. 363. ] [ 29. 430. ] [ 29.7 450. ] [ 29.7 500. ] [ 30. 390. ] [ 30. 450. ] [ 30.7 500. ] [ 31. 475. ] [ 31. 500. ] [ 31.5 500. ] [ 32. 340. ] [ 32. 600. ] [ 32. 600. ] [ 33. 700. ] [ 33. 700. ] [ 33.5 610. ] [ 33.5 650. ] [ 34. 575. ] [ 34. 685. ] [ 34.5 620. ] [ 35. 680. ] [ 35. 700. ] [ 35. 725. ] [ 35. 720. ] [ 36. 714. ] [ 36. 850. ] [ 37. 1000. ] [ 38.5 920. ] [ 38.5 955. ] [ 39.5 925. ] [ 41. 975. ] [ 41. 950. ] [ 9.8 6.7] [ 10.5 7.5] [ 10.6 7. ] [ 11. 9.7] [ 11.2 9.8] [ 11.3 8.7] [ 11.8 10. ] [ 11.8 9.9] [ 12. 9.8] [ 12.2 12.2] [ 12.4 13.4] [ 13. 12.2] [ 14.3 19.7] [ 15. 19.9]] [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0.7142857142857143
마무리
키워드로 끝내는 핵심 포인트
- 특성은 데이터를 표현하는 하나의 성질이다. 이 절에서는 생선 데이터의 각각을 길이와 무게 특성으로 나타냈다.
- 머신러닝 알고리즘이 데이터에서 규칙을 찾는 과정을 훈련 이라고 한다. 사이킷런에서는 fit()메서드가 하는 역할이다.
- k-최근접 이웃 알고리즘은 가장 간단한 머신러닝 알고리즘 중 하나이다. 사실 어떤 규칙을 찾기보다는 전체 데이터를 메모리에 가지고 있는 것이 전부이다.
- 정확도는 정확한 답을 몇개 맞혔는지를 백분율로 나타낸 값이다. 사이킷런에서는 0~1사이의 값으로 출력된다.
- 정확도 = (정확힌 맞힌 개수) / (전체 데이터 개수)
핵심 패키지와 함수
- matplotlib
- scatter()는 산점도를 그리는 맷플롯립 함수이다. 처음 2개의 매개변수로 x축 값과 y축 값을 전달한다. 이 값은 파이썬 리스트 또는 넘파이 배열이다. c 매개변수로 색깔을 지정한다. 색을 지정하지 않은 결우 10개의 기본 색깔을 사용해 그래프를 그린다. b=파랑, g=초록, r=빨강, c=시안, m=마젠타, y=노랑, k=검정, w=흰색..
- matplotlib
- 출처: 혼자공부하는 머신러닝 + 딥러닝
'혼자공부하는 머신러닝 + 딥러닝' 카테고리의 다른 글
Chapter06. 비지도 학습 (군집알고리즘, k-평균) (0) | 2021.05.29 |
---|---|
Chapter05.트리의 앙상블 (0) | 2021.05.28 |
Chapter04. 다양한 분류 알고리즘 (0) | 2021.05.27 |
Chapter03.회귀 알고리즘과 모델 규제 (0) | 2021.05.25 |
Chapter 02 데이터 다루기 (훈련세트와 테스트 세트 / 데이터 전처리) (0) | 2021.05.17 |