본문 바로가기
인공지능/혼자 공부하는 머신러닝 + 딥러닝

01-03 마켓과 머신러닝

by 녤 2023. 1. 31.

~ 시작하기 전에.. ~

 

알아두면 좋은 사이트: 캐글(https://www.kaggle.com/)

https://easy-study-note.tistory.com/4

 

캐글(Kaggle) 시작하기

캐글은 이미 데이터 엔지니어, 데이터 사이언티스트들에게는 유명한 플랫폼이다. 나는 이제 막 머신러닝을 입문하는 입장에서 좋은 학습 플랫폼을 찾다가 캐글을 발견하게 되었다. 기본적으로

easy-study-note.tistory.com

 

책 44p. ~ 62p.

 

1. 기존 프로그램 vs 머신러닝 프로그램

 

1) 전통적인 프로그램

: 어떤 식으로 만들어 달라~는 규칙 등을 기반으로 프로그래머가 작업 → 규칙을 바탕으로 작업

 

ex) 30cm 보다 큰 생선은 도미이다. (=규칙)

 

↓ 

프로그래밍(전통적인 프로그램)

if fish_data >= 30:
	print("도미")

 

2) 머신러닝 프로그램

: 규칙을 미리 정하기 어려운 경우에 사용

 

ex) 머신러닝은 생선을 보고 어떤 생선인지를 판단하는 규칙을 스스로 찾게 함 

 

*이때, 머신러닝이 데이터에서 규칙을 찾는 일을 "학습/훈련" 이라고 부른다.

 

 

=> 즉 머신러닝과 기존 프로그램의 가장 큰 차이는 "판단 규칙(기준)을 스스로 찾는지 혹은 프로그래머가 지정해주는지" 이다.

 


2. 이진 분류

 

1) 종류 = 클래스

ex) 도미, 빙어 등과 같은 데이터들

 

2) 분류: 머신러닝에서 여러 개의 종류(=클래스) 중 하나를 구별하는 문제

 

3) 이진 분류: 2개의 종류(클래스) 중 하나를 고르는 문제

 


 

3. 데이터 준비

 

1) 데이터 = 샘플

ex) 각각의 생선 = 데이터 = 샘플

 

2) 데이터의 특징= 특성(feature)

ex) 각 생선의 무게 or 길이 = 샘플(생선)의 특징 = 특성

 


 

4. 산점도(Scatter plot)

 

1) 산점도: x와 y축으로 이루어진 좌표계에 두 변수(x, y)의 관계를 표현하는 방법

= x와 y축에 두 개의 특성을 넣고 각 샘플을 하나의 점으로 표시함 

 

- 산점도를 사용하여 두 특성을 그래프로 표현하면 데이터를 잘 이해할 수 있고, 작업에 대한 힌트를 얻을 수 있음

 

2) 맷플롯립(matplotlib): 파이썬에서 과학계산용 그래프를 그릴 수 있는 대표적인 패키지

 

~사용법 예시~

import matplotlib.pyplot as plt #matplotlib의 pypylot 함수를 plt로 줄여서 사용

plt.scatter(bream_length, bream_weight) 
#scatter() 함수를 사용하여 산점도를 그림; scatter(X축의 데이터, Y축의 데이터)
#scatter() 함수를 두 번 이상 연속하여 호출할 경우, 산점도가 따로 그려지는 것이 아닌 하나의 산점도에 그려짐

plt.xlabel('length')
#X축의 이름 표시

plt.ylabel('weight')
#Y축의 이름 표시

plt.show
#그래프 출력

 

 

<빙어 + 도미 데이터 준비 및 산점도 그리기>

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]


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 #matplotlib의 pypylot 함수를 plt로 줄여서 사용

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

-위와 같이 산점도가 일직선에 가까운 형태로 나타나는 경우를 선형(linear)적이라고 말함 

 

+) 빙어가 도미에 비해 길이도 무게도 매우 작은 것을 확인 가능 → 데이터 구분이 어렵지 않는 것을 충분히 예상 가능

 


 

5. 데이터 합치기

 

K-최근접 이웃 알고리즘을 사용하기 위해서는 도미와 빙어 데이터를 하나의 데이터로 합쳐줘야 함 

= ML 프로그램이 두 생선을 구분하는 방법을 해결하기 위함

 

→ 만약 도미나 빙어 둘 중 하나의 데이터만 전달하면 두 데이터를 구분하는 방법을 구할 수 없을 것 

 

~파이썬에서 리스트를 합치는 방법~

# 리스트에 덧셈 연산자를 사용 → 하나의 리스트가 됨(=리스트가 합쳐지는 것을 의미)
# =연산자 오버로딩
length = bream_length + smelt_length
weight = bream_weight + smelt_weight

 


 

6. 사이킷런(Scikit-learn)

 

1) 사이킷런: 머신러닝 패키지 중 하나. 2차원 리스트 형태의 데이터를 필요로 함

 

-사이킷런을 사용하기 위해서는 각 특성의 리스트를 세로 방향으로 늘어뜨린 2차원 리스트를 만들어야 함

ex) 생선의 길이와 무게로 2차원 리스트를 만들어야 함 (= 사이킷런이 2차원 리스트 형태의 데이터를 요구하기 때문)

 

 

~2차원 리스트를 만드는 가장 쉬운 방법~

-파이썬의 zip()함수와 리스트 내포 구문을 사용하는 것

-zip(): 나열된 리스트 각각에서 하나씩 원소를 꺼내 반환

 

fish_data = [[l, w] for l, w in zip(length, weight)]

#zip(length, weight): length리스트와 weight 리스트를 zip으로 묶은 후
#각각 lenght의 각 원소를 l에, weight의 각 원소를 w에 넣는다 → 이 과정을 length와  weight 리스트가 끝날 때 까지 반복
# [] 대괄호로 리스트를 생선한다 
# for문이 []대괄호 안에 있기 때문에 리스트 내포, for문이 완료되면

#[ [l, w] , [l, w] , [l, w] , ... , [l, w]] 형태의 2차원 리스트가 만들어짐
#[l, w]가 하나의 원소로 구성된 리스트임

 

https://devpouch.tistory.com/76

 

[Python] 파이썬 리스트 내포(List comprehension)

리스트 내포(List comprehension) 파이썬에서는 for문과 if문을 한 라인에 작성하여 코드를 직관적으로 만들고 실행속도를 높혀주는 기법인 리스트 내포(List comprehension)기법이 존재합니다. 사용 방법은

devpouch.tistory.com

 

 

 

<학습 데이터 준비>

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]


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)

 


7. 정답 데이터의 필요성 

 

-만약 샘플(데이터)의 답을 알려주지 않는다면 ML 프로그램이 데이터를 구분하는 방법을 찾을 수 없음 

규칙 찾기에서 정답이 없으면 규칙을 찾을 수 없음 

 

= 지도 학습

 

-지도 학습: 프로그램에게 가르치는 것을 의미

ex) 시험 전 문제집을 푸는 것과 비슷

 

-머신 러닝에서 2개를 구분하는 경우, 찾으려는 대상을 1로 놓고 그 외에는 0으로 놓음

 

~정답 데이터 만들기~

#1이 35개 있는 리스트와 0이 14개 있는 리스트를 만들고 그 둘을 합침
fish_taget = [1] * 35 + [0] * 14

 

 

정답 데이터 준비

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]


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)] #학습 데이터
fish_target = [1] * 35 + [0] * 14 #정답 데이터
print(fish_target)

 


8. KNeighborsClassifier  클래스

 

-KNeighborsClassifier  클래스: 사이킷런 모듈에 있는 K-최근접 이웃 알고리즘을 구현하기 위한 클래스 

 

-훈련: 모델에 데이터를 전달하여 규칙을 학습하는 과정

 

 

~사용 방법~

# sklearn아래 neighbors 모듈에 있는 KNeighborsClassifier 클래스를 import함
from sklearn.neighbors import KNeighborsClassifier

#K-최근접 이웃 클래스 생성
kn = KNeighborsClassifier()

#사이킷런에서는 훈련을 위해 fit 메서드를 사용함 
#사용방법: fit(훈련 데이터, 정답데이터)
kn.fit(fish_data, fish_target)

#훈련 데이터로 정답 데이터를 얼마나 맞추는 지 알아보는 메서드
kn.score(fish_data, fish_target)

 

-모델:

① 머신러닝 알고리즘을 구현한 프로그램 = 알고리즘 그 자체

② 알고리즘을 (수식 등으로) 구체화 하여 표현한 것 = 알고리즘이 객체화 된 것

 

 

K최근접 이웃

from sklearn.neighbors import KNeighborsClassifier

kn = KNeighborsClassifier()

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

 


 

9. K-최근접 이웃 알고리즘 정리 

 

-predict() 메서드로 새로운 데이터의 정답을 예측 → 역시 2차원 리스트의 형태로 데이터를 전달함 

kn.predict([[특성1, 특성2]])

 

<K최근접 이웃- 새 샘플 예측>

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

 

1)  K-최근접 이웃 알고리즘 : 새 샘플 주위에 있는 샘플들을 확인하여 주위 샘플들이 어떤 클래스에 속하는 지를 살펴 본 후, 가장 많은 클래스를 새 샘플의 클래스(정답)으로 결정하는 알고리즘

 

* 기본적으로 확인하는 샘플의 개수는 5개이다. 

 

2) 장점: 새로운 데이터 예측 시, 가장 가까운 직선거리에 어떤 데이터가 있는 지를 살피기만 하면 됨(= 간단함)

 

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

 

-K-최근접 이웃 알고리즘은 딱히 훈련되는 것은 없음 

 

- KNeighborsClassifier클래스에서는 n_neighbots 매개변수를 통해 살펴보는 샘플의 개수를 변경할 수 있음

-p 매개변수로 거리를 재는 방법을 지정헐 수 있다. 1일 경우 맨허튼 거리를 사용하고 2일 경우 유클리디안 거리를 사용한다. 

 

*역시 기본으로 확인하는 샘플의 개수는 5개

 

 

<K최근접 이웃- 안 좋은 예(*참고하는 샘플의 개수가 전체 샘플의 개수인 경우)>

kn49 = KNeighborsClassifier(n_neighbors=49)

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

- fish_data의 데이터 49개 중 35개가 도미로 다수를 차지하므로 어떤 데이터를 넣어도 무조건 도미로 예측하게 됨 → 정확도가 떨어지게 됨