[1일차] 첫 머신러닝

Hyun·2023년 2월 19일
0

머신러닝/딥러닝

목록 보기
1/5
post-thumbnail

인공지능과 머신러닝, 딥러닝

  • 인공지능
    사람처럼 학습하고 추론할 수 있는 지능을 가진 컴퓨터 시스템을 만드는 기술

  • 인공일반지능(강인공지능) vs 약인공지능

    인공일반지능(강인공지능)
    사람과 구분하기 어려운 지능을 가진 컴퓨터 시스템

    약인공지능
    현실에서 우리가 마주하고 있는 인공지능, 아직까진 특정 분야에서 사람의 일을 도와주는 보조 역할, ex 알파고, 자율주행 보조 등

  • 머신러닝
    규칙을 일일이 프로그래밍 하지 않아도 자동으로 데이터에서 규칙을 학습하는 알고리즘을 연구하는 분야, 대표적인 머신러닝 라이브러리로 scikit-learn

  • 딥러닝
    많은 머신러닝 알고리즘 중에 인공 신경망(artificial neural network)을 기반으로 한 방법들을 통칭, 대표적인 딥러닝 라이브러리로 TensorFlow, PyTorch

학습 환경: 구글의 colab

k-최근접 이웃을 사용한 2개의 종류를 분류하는 머신러닝 모델 훈련

생선 분류 문제
도미와 빙어를 구분하는 머신러닝 모델을 훈련시킨다.

먼저 도미와 빙어의 데이터를 준비해준다. 데이터의 특징은 길이와 무게가 있다는 점이다.

도미의 데이터부터 살펴보자.

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]
#도미 35마리의 특성을 길이와 무게로 표현한 것

위 데이터를 길이를 x축, 무게를 y축으로 하는 그래프에 점으로 표시해보자. 이런 그래프를 산점도(scatter plot)라고 부른다.

그래프를 그리기 위해 파이썬의 맷플롯립(matplotlib) 패키지를 이용한다. 이 패키지를 import 하고 산점도를 그리는 scatter() 함수를 사용해본다.

import matplotlib.pyplot as plt

plt.scatter(bream_length, bream_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

이렇게 산점도 그래프가 일직선에 가까운 형태로 나타나는 경우를 선형(linear) 적이라고 말한다.

그다음으로 빙어데이터를 준비하고 이번엔 도미와 빙어, 2개의 산점도를 한 그래프로 그려보자. scatter() 함수를 연달아 사용하면 된다.

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]

import matplotlib.pyplot as plt

plt.scatter(bream_length, bream_weight)
plt.scatter(smelt_length, smelt_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

이제 k-최근접 이웃(k-Nearest Neightbors) 알고리즘을 사용하여 도미와 빙어의 데이터를 구분해보자.

먼저 도미와 빙어 데이터의 길이, 무게 데이터를 각각 하나의 길이, 무게 데이터로 합쳐준다.

책에서 사용하는 머신러닝 패캐지가 사이킷런(scikit-learn)이고, 해당 패키지를 사용하기 위해선 2차원 리스트가 필요하다. zip()함수와 for문을 이용해 2차원 리스트를 만들어준다

length = bream_length + smelt_length
weight = bream_weight + smelt_weight

fish_data = [[l,w] for l,w in zip(length, weight)]
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]]

도미와 빙어를 구분하기 위해서는 적어도 어떤 생선이 도미이고 빙어인지 알려주어야 한다. 2진수를 이용한다.

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]

사이킷런 패키지에서 k-최근접 이웃 알고리즘을 구현한 클래스인 KNeighborsClassifier 를 import 하여 객체를 생성한다.

이 객체에 fish_data와 fish_target 을 전달하여 도미를 찾기 위한 기준을 학습시킨다. 이 과정을 머신러닝에서는 훈련이라고 한다. 사이킷런에서는 fit()메서드를 사용한다.

객체(또는 모델) kn이 얼마나 잘 훈련되었는지 평가하기 위해 사이킷런에서는 score()메서드를 사용한다. 이 메서드는 0~1 사이의 값을 반환한다. 예로, 1은 모든 데이터를 정확히 맞췄다는 것을 나타내고 0.5는 절반만 맞췄다는 것을 의미한다.

그러니까 도미와 빙어를 합한 49개의 길이, 무게 쌍의 데이터를 학습시킨 후, 해당 데이터들을 모델에게 다시 대입했을때 얼마나 정확한 예측을 할 수 있는지를 판별하는 값이다. 이 값을 정확도(accuracy)라고 부른다.
아마 score 메서드의 첫번째 매갭변수인 fish_data를 모델에 대입시켰을때 나오는 결과값을 두번째 매개변수인 fish_target과 비교하여 정확도를 산출하는 것 같다.

from sklearn.neighbors import KNeighborsClassifier
kn = KNeighborsClassifier()

kn.fit(fish_data, fish_target)
kn.score(fish_data, fish_target)

출력:
1.0

위 모델은 정확도가 100%이며, fish_data의 데이터들을 100%의 정확도로 도미와 빙어로 정확하게 구분한다는 의미이다.

k-최근접 알고리즘

k-최근접 알고리즘은 어떤 데이터에 대한 답을 구할 때 주위의 가장 가까운 5개의 데이터를 보고 다수결의 원칙에 따라 데이터를 예측한다. 이때 가장 가까운 데이터의 갯수는 기본적으로 5개이고, 변경가능하다.

이렇게 학습된 모델에 어떤 생선의 특징을 주고 예측시켰을때 나오는 결과값을 확인해보자.

kn.predict([[30, 600]])

출력: 
array([1])

예측방법을 생각해보면, 산점도 그래프에서 주위의 데이터(기본값 5개)들 중 더 많은 데이터를 가진 생선의 종류를 따라 갔을 것이다.

생성한 객체(또는 모델) kn이 참고할 데이터의 갯수를 변경시킬 수도 있다.

kn49 = KNeighborsClassifier(n_neighbors=49)
kn49.fit(fish_data, fish_target)
kn49.score(fish_data, fish_target)

출력:
0.7142857142857143 (= 35/49)

참고할 데이터의 갯수가 49개인 경우, 무조건 주위에 도미데이터가 더 많이 존재하게 되므로 fish_data에 대해 정확도를 구했을때 35/49의 정확도를 가지게 된다.

k-최근접 이웃 알고리즘 사용을 위해 준비해야 할 일은 데이터를 모두 가지고 있는것이 전부이다. 새로운 데이터에 대해 예측할 때는 가장 가까운 직선거리에 어떤 데이터들이 존재하는지 살펴보기만 하면 된다.

단점은 데이터가 아주 많은 경우 사용하기 어렵다. 데이터가 크기 때문에 메모리가 많이 필요하고, 직선거리를 계산하는 데도 많은 시간이 필요하기 때문이다.

추가) score() 메서드 관련 질문 결과, 짐작했던게 맞았다.

profile
better than yesterday

0개의 댓글