머신러닝

[머신러닝] 혼자 공부하는 머신러닝 + 딥러닝 Chap.1

sa_woll 2023. 10. 4. 18:02

인공지능 머신러닝 딥러닝

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

인공지능이란

  • 인공지능: 사람처럼 학습하고 추론할 수 있는 지능을 가진 컴퓨터 시스템을 만드는 기술.
  • 역사
    • 워런 매컬러와 월터 피츠의 뇌의 뉴런 개념, 앨런 튜링의 튜링 테스트
    • 인공지능 태동기: 1956년 다트머스 AI 컨퍼런스
    • 인공지능 황금기 도래: 1957년 퍼셉트론
    • AI 겨울: 컴퓨터 성능의 한계
    • 두 번째 AI 붐: 전문가 시스템 등장
    • 두 번째 AI 겨울: 다시 한계 봉착
    • 이후 1998년 LeNet-5를 시작으로 다시 인공지능이 각광받기 시작
  • 강인공지능(인공일반지능): 영화 속의 인공지능. 사람과 구분하기 어려운 지능을 가진 컴퓨터 시스템
  • 약인공지능: 현실에서 우리가 마주하고 있는 인공지능. 특정 분야에서 사람의 일을 도와주는 보조 역할만 가능하다. ex) 알파고, 빅스비, 시리, 자율주행자동차, 기계 번역

🔍 언제 강인공지능에 도달할 수 있을까?: 가능성에 대해서는 긍정적. 그러나 성급한 장밋빛 청사진은 이르다.

머신러닝이란

  • 머신러닝: 규칙을 일일이 프로그래밍하지 않아도 자동으로 데이터에서 규칙을 학습하는 알고리즘을 연구하는 분야로 인공지능의 하위 분야 중에서 지능을 구현하기 위한 소프트웨어를 담당하는 핵심 분야이다.
  • 통계학과의 관련성: 통계학에서 유래된 머신러닝 알고리즘이 많으며 통계학과 컴퓨터사이언스가 상호작용하며 발전 중
  • 사이킷런: 대표적인 머신러닝 라이브러리
    • 파이썬 API를 사용
    • 매우 편리하게 사용 가능, 인증된 알고리즘들
  • 오픈소스 라이브러리와 함께 머신러닝 분야가 폭발적으로 성장하였다.

딥러닝이란

  • 딥러닝: 머신러닝 알고리즘 중에 인공 신경망을 기반으로 한 방법들을 통칭하는 명칭(인공 신경망과 딥러닝이라는 용어는 거의 구분 없이 사용된다.)
  • LeNet-5: 1998년 발표된 손글씨 숫자를 인식하는 인공 신경망 모델.(최초의 합성곱 신경망)
  • AlexNet: 2012년 발표된 이미지 분류에서 압도적인 성능을 보인 인공 신경망 모델.
  • 국내에서는 2016년 알파고 이세돌 대국 이후 관심 증대
  • AI 겨울 이후 인공신경망이 이전과 다른 놀라운 성능을 달성하게 된 원동력
    • 복잡한 알고리즘을 훈련할 수 있는 풍부한 데이터
    • 컴퓨터 성능의 향상
    • 혁신적인 알고리즘의 개발
  • 텐서플로: 2015년 구글이 공개한 오픈소스 딥러닝 라이브러리
  • 파이토치: 2018년 페이스북이 공개한 오픈소스 딥러닝 라이브러리
    • 두 라이브러리 모두 인공 신경망 알고리즘을 전문적으로 다루고 파이썬 API를 사용한다.

코랩과 주피터 노트북

구글 코랩

  • 클라우드 기반의 주피터 노트북 환경
  • 구글이 대화식 프로그래밍 환경인 주피터를 커스터마이징한 것
  • 주피터: 대화식 프로그래밍 환경
  • 코랩 노트북: 주피터 프로젝트의 대표 제품인 노트북을 구글 클라우드의 가상 서버를 통해 사용할 수 있도록 함.

이하 구글코랩 사용법은 생략

마켓과 머신러닝

생선 이름을 자동으로 알려주는 머신러닝을 만들어 보자.

✏️ 생선 분류 문제

  • 생선 길이가 30cm 이상이면 도미라고 해 보자 -> 하지만 30cm보다 큰 생선이 무조건 도미라고 말할 수 없다. -> 머신 러닝 필요
  • 머신러닝은 누구도 알려주지 않는 기준을 찾아서 일을 한다. 누가 말해주지 않아도 머신러닝은 '30cm~40cm 길이의 생선은 도미이다'라는 기준을 찾는 것이다.

📌 도미 데이터 준비하기

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마리의 도미이다. 첫 번째 도미의 길이는 25.4cm, 무게는 242.0g인 것이다. 각 도미의 특징을 길이와 무게로 표현한 것이다. 이런 특징을 특성(feature)라고 부른다.

 

x축을 도미의 길이, y축을 도미의 무게로 하는 산점도를 그린다.

이때 맷플롯립 패키지(파이썬에서 과학계산용 그래프를 그리는 대표적인 패키지)를 사용한다.

  • scatter() 함수: 산점도를 그리는 함수
import matplotlib.pyplot as plt

plt.scatter(bream_length, bream_weight)
plt.xlabel('length')
plt.ylabel('weight')
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]
plt.scatter(bream_length, bream_weight)
plt.scatter(smelt_length, smelt_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

두 개의 산점도를 한 그래프로 그리려면 그냥 scatter()를 두 번 써주면 된다.

첫 번째 머신러닝 프로그램

k-최근접 이웃 알고리즘을 사용하기로 한다.

먼저 도미와 빙어를 하나의 데이터로 만든다. (사이킷런을 사용하기 위해서는 2차원 리스트를 만들어 전달해야 한다.)

 

그 전에,

📌 도미의 길이와 빙어의 길이, 도미의 무게와 빙어의 길이 리스트를 각각 하나로 합친다.

length=bream_length+smelt_length
weight=bream_weight+smelt_weight

이렇게 하면 length 리스트에는 도미 35개의 길이와 빙어 14개의 길이, weight 리스트에는 도미 35개의 무게와 빙어 14개의 무게가 연달아 오게 된다.

 

📌 이제 여기서 각각의 length와 weight을 짝지어 보겠다.

 

파이썬) zip(): 리스트에서 원소를 하나씩 꺼내준다.

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]]

총 49마리의 생선들의 길이와 무게가 짝지어졌다.

 

📌 이제 정답 데이터를 준비한다. 첫 번째 생선은 도미이고, 두 번째 생선도 도미라는 식으로 각각 어떤 생선인지 답을 만드는 것이다. 어떤 생선이 도미인지 빙어인지를 알려 주어야 하기 때문이다.

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를 임포트한다. 

from sklearn.neighbors import KNeighborsClassifier
kn=KNeighborsClassifier()

 

📌 이 객체에 fish_data와 fish_target을 전달하여 도미를 찾기 위한 기준을 학습시킨다. 이를 훈련(training)이라고 부른다. 

fit() 메소드: 알고리즘을 훈련시키는 함수

 

kn객체의 fit함수에 훈련시킬 데이터를 전달한다.

kn.fit(fish_data, fish_target)

score() 메서드: kn이 얼마나 잘 훈련되었는지 평가하는 함수. 1은 모든 데이터를 정확히 맞혔다는 의미

kn.score(fish_data, fish_target)

# 출력 결과
1.0

이 결과값을 정확도라고 한다. 이 모델은 정확도가 100%이다.

 

✏️ k-최근접 이웃 알고리즘

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

 

predict() 메서드: 새로운 데이터의 정답 예측

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

# 출력 결과
array([1])

30, 600인 생선은 도미로 분류된다. 그 점 주위에 도미데이터가 많기 때문이다.

 

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

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

KNeighborsClassifier 클래스는 fit_X 속성에 fish_data를 모두 가지고 있고 _y속성에 fish_target을 가지고 있다.

실제로 k-최근접 이웃 알고리즘은 무언가 훈련되는 게 없는 셈이다. fit() 메서드에 전달한 데이터를 모두 저장하고 있다가 새로운 데이터가 등장하면 가장 가까운 데이터를 참고하여 도미인지 빙어인지를 구분한다.

 

알고리즘의 약점

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

# 실행결과
0.7142857142857143

-> 참고 데이터를 49개로 한 모델에 fish_data를 적용하면 모든 생선을 사용하여 예측하므로 무조건 도미로 예측하게 된다.  도미만 올바르게 맞히기 때문에 정확도는 35/49와 같다.