머신러닝

[혼공머신] 1. ✍🏻 👨🏻‍💻

누코협 2025. 7. 6. 22:09

처음 시도하는 혼공단 심정

 

사진이 저렇지만, 뭐 하기 싫은데 한다는 의미의 느낌은 전혀 아닙니다.

 

혼공단도 처음이고, 블로그도 거의 처음인데, 잘 봐주세요. 🙇🏻

 

정리하면서 많이 듣고 있는 노래를 하나 공유하면서 시작하겠습니다.

 

[혼공머신] 로드맵

혼자 공부하는 머신러닝+딥러닝 로드맵

개정판에서 달라진 점

  • 대규모 언어 모델에 대한 장 추가
    • BART, KoBART, EXAONE, GPT-4
  • 파이토치 코드로 작성된 예제 제공
    • 7-9장
  • 자주 묻는 질문 추가
  • 확인 문제 보강
  • 분량이 약 30% 증가

01-1 인공지능과 머신러닝, 딥러닝

인공지능이란?

인공지능 태동기

  • 인공지능(Artificial Intelligence)은 사람처럼 학습하고 추론할 수 있는 지능을 가진 컴퓨터 시스템을 만드는 기술
  • 1943년, 워런 매컬러와 월터 피츠의 "A Logical Calculus of the Ideas Immanent in Nervous Activity"라는 논문에서 신경계를 단순한 논리 요소들의 네트워크로 보는 수학적 모델
  • 1950년, 앨런 튜링이 인공지능이 사람과 같은 지능을 가졌는지 테스트할 수 있는 "튜링 테스트" 발표
  • 1956년, 다트머신 AI 컨퍼런스에서 인공지능에 대한 전망이 최고조에 달함

인공지능 황금기

  • 1957년 프랑크 로젠블라트가 로지스틱 회귀의 초기 버전이라 볼 수 있는 퍼셉트론 발표
  • 1959년 데이비드 허블과 토르스텐 비셀이 고양이를 사용해 시각 피질에 있는 뉴런 기능 연구

1차 AI 겨울

  • 1974년~1980년

AI 붐

  • 전문가 시스템

2차 AI 겨울

  • 전문가 시스템의 한계로 2차 AI 겨울 도래

LeNet-5

LeNet-5 아키텍처

  • 1998년 얀 르쿤이 LeNet-5라고 하는 최초의 합성곱 신경망을 통해 손글씨 숫자를 인식하는데 성공

AlexNet

  • 이미지 분류 대회인 ImageNet에서 합성곱 신경망 AlexNet 사용

텐서플로

TensorFlow

  • 2015년 구글이 출시
  • 텐서플로는 구글에서 개발한 오픈소스 딥러닝 프레임워크로, 머신러닝 모델을 만들고 훈련시키는 데 사용
  • 데이터를 '텐서'라는 다차원 배열로 처리하며, 인공지능, 자연어 처리, 이미지 인식 등 다양한 분야에 활용

알파고

AlphaGo

  • 2016년 출시
  • 알파고(AlphaGo)는 구글 딥마인드가 개발한 인공지능 바둑 프로그램으로, 2016년 세계적인 바둑 기사 이세돌 9단과의 대결에서 승리하며 인공지능의 뛰어난 능력을 입증

강인공지능과 약인공지능

  • 영화 '그녀'의 사만다나 '터미네이터'의 스카이넷처럼 사람과 구분하기 어려운 지능을 가진 컴퓨터 시스템인공일반지능 혹은 강인공지능이라고 함
  • 현실에서 애플의 '시리'나 자율 주행 자동차 등 특정 분야에서 사람의 일을 도와주는 보조 역할만 가능한 인공지능약인공지능이라고 한다.

인공지능이란

  • 머신러닝, 신경과학, 로봇과학, 최적화 등이 복합적으로 관여하는 것이 인공지능
  • 머신러닝은 인공지능의 하위 개념으로, 데이터를 바탕으로 패턴을 파악해 작업 수행을 자동화하는 알고리즘
    • 대표적 라이브러리: 사이킷런; 선형회귀, 로지스틱 회귀, 결정 트리, 랜덤 포레스트 등
  • 수많은 머신러닝 알고리즘 중에 인공 신경망 알고리즘을 기반으로 한 방법들을 통칭하여 딥러닝
    • 대표적 라이브러리(Keras, Pytorch): CNN(합성곱 신경망), RNN(순환 신경망), 트랜스포머 등

01-2 코랩과 주피터 노트북

구글 코랩

Google Colaboratory

  • 구글이 대화식 프로그래밍 환경인 주피터를 커스터마이징한 웹 브라우저에서 무료로 파이썬 프로그램을 테스트하고 저장할 수 있는 서비스.

텍스트 셀

텍스트 셀의 실행 모습

  • 셀은 코랩에서 실행할 수 있는 최소 단위
  • 텍스트 셀은 코드처럼 실행되는 것이 아니기 때문에 자유롭게 사용 가능.
  • HTML과 마크다운을 혼용해서 사용 가능.

코드 셀

코드 셀의 실행 모습

  • 코드를 실핼할 수 있다.

노트북

코랩 노트북의 전체 화면

  • 구글 클라우드의 컴퓨트 엔진에 연결되어 있고, 가상 서버를 사용한다.

1-2 확인 문제

  1. 구글에서 제공하는 웹 브라우저 기반의 파이썬 실행 환경은 무엇인가요?
    정답: 코랩
  2. 코랩 노트북에서 쓸 수 있는 마크다운 중에서 기울임 꼴로 쓰는 것은?
    정답: _혼공머신_
  3. 코랩 노트북은 어디에서 실행되나요?
    정답: 구글 클라우드

01-3 마켓과 머신러닝

생선 분류 문제

프로그램으로 생선을 분류한다고 가정하자.

  • 머신러닝으로 기준을 찾고, 그 기준을 활용해 생선이 도미인지 아닌지 판별 가능하게 한다.
  • 분류: 여러 개의 클래스 중 하나를 구별해 내는 문제
    • 이 생선 분류 문제처럼, 2개의 클래스 중 하나를 고르는 문제를 이중 분류

도미 데이터 준비하기

  • 도미의 길이와 무게를 파이썬 리스트로 만들어서 만든다.
    • 생선의 길이와 무게와 같은 특징들을 특성이라고 한다.

  • 특성을 그래프로 표현해 데이터를 더 잘 이해하고 활용하기 위해 산점도로 표시한다.
    • 파이썬에서 과학계산용 그래프를 그리는 대표적 패키지는 matplotlib
    • 파이썬 패키지는 import를 통해 불러와 활용할 수 있음.
    • as 키워드를 통해 해당 패키지를 줄여서 쓸 수 있다.
      • ex) matplot -> plt, numpy -> np

  • 산점도 그래프가 일직선에 가까운 형태로 나타나는 경우 선형적이라고 한다.

위 코드를 실행한 결과. 선형적인 산점도 그래프다.

빙어 데이터 준비하기

  • 데이터를 입력해 하나의 산점도에 표현하게 되면, 두 항목의 색을 구분해서 나타내준다.

첫 번째 머신러닝 프로그램

  • k-최근접 이웃 알고리즘어떤 데이터에 대한 답을 구할 때 주위의 다른 데이터를 보고 다수를 차지하는 것을 정답으로 사용.
    • 살펴볼 데이터만 있으면 되지만 데이터가 아주 많으면 메모리가 필요하고, 직선거리를 계산하는 데 시간이 많이 든다.
    • 참고할 데이터 수의 기본값은 5로, n_neighbors 파라미터로 기준을 바꿀 수 있다.
  • 사이킷런 패키지를 사용하기 위해 2차원 리스트를 만든다.
  • k-최근접 이웃 알고리즘을 구현한 클래스인 KNeighborsClassifier를 임포트 후 해당 클래스의 객체 생성
  • fit() 메서드를 사용해 도미를 찾기 위한 기준을 학습시키는데 이 과정을 훈련
  • score() 메서드를 사용해 모델을 평가할 수 있고, 정확도라고 하는 값을 리턴
  • predict() 메서드를 사용해 새로운 데이터의 정답을 예측
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 # bream == 1, smelt == 0

from sklearn.neighbors import KNeighborsClassifier # k-최근접 이웃 알고리즘을 구현한 클래스인 KNeighborsClassifier를 임포트

kn = KNeighborsClassifier() # KNeighborsClassifier의 객체 생성

kn.fit(fish_data, fish_target) # 도미를 찾기 위한 기준을 학습시키는데 이 과정을 훈련

kn.score(fish_data, fish_target) # 모델을 평가할 수 있고, 정확도라고 하는 값을 리턴

import matplotlib.pyplot as plt

plt.scatter(bream_length, bream_weight)
plt.scatter(smelt_length, smelt_weight)
plt.scatter(30, 600, marker='^') # length == 30, weight == 600 인 물고기
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

kn.predict([[30, 600]]) # length == 30, weight == 600 인 물고기가 무엇인지 예측.

초록 삼각형인 길이 30, 몸무게 600의 물고기를 예측한 산개도

 

코드를 실행한 결과인 산개도를 보면, 길이 30, 몸무게 600의 물고기는 도미로 판별났다.

1-3 확인 문제

  1. 데이터를 표현하는 하나의 성질로써, 예를 들어 국가 데이터의 경우 인구 수, GDP, 면적 등이 하나의 국가를 나타냅니다. 머신러닝에서 이런 성질을 무엇이라고 부르나요?
    정답: 특성
  2. 가장 가까운 이웃을 참고하여 정답을 예측하는 알고리즘이 구현된 사이킷런 클래스는 무엇인가요?
    정답: KNeighborsClassifier
  3. 사이킷런 모델을 훈련할 때 사용하는 메서드는 어떤 것인가요?
    정답: fit()
  4. 모델의 정확도를 계산하는 방법은?
    정답: (정확히 맞힌 개수) / (전체 데이터 개수)

02-1 훈련세트와 테스트세트

지도학습과 비지도 학습

  • 지도 학습은 훈련하기 위한 데이터와 정답이 필요하고, 이를 입력타깃이라고 하며, 합쳐서 훈련 데이터라고 한다.
    • 정답이 있으니 알고리즘이 정답을 맞히는 것을 학습한다.
  • 비지도 학습은 타깃 없이 입력 데이터만 사용하기에 무언가를 맞힐 수 없다. 데이터를 잘 파악하거나 변형하는데 도움을 준다.

훈련세트와 테스트 세트

  • 머신러닝 알고리즘의 성능을 제대로 평가하려면 훈련 데이터와 평가에 사용할 데이터가 각각 달라야 한다.
  • 평가를 위해 또 다른 데이터를 준비하거나, 이미 준비된 데이터 중에서 일부를 떼어내어 활용
  • 평가에 사용하는 데이터를 테스트 세트, 훈련에 사용되는 데이터를 훈련세트라고 한다.
  • 각 생선의 길이와 무게를 하나의 리스트로 만들고 이와 같은 데이터를 샘플이라고 한다.
  • 리스트처럼 배열의 요소를 선택할 때는 배열의 위치, 즉 인덱스를 지정한다.
  • 인덱스 외에도 슬라이싱이라는 연산자를 통해서 인덱스의 범위를 지정해 원소를 선택할 수 있다.
  • 하지만 슬라이싱은 마지막 인덱스의 원소는 포함되지 않는다.

샘플링 편향

  • 훈련하는 데이터와 테스트하는 데이터에는 도미와 빙어가 골고루 섞여 있어야 한다.
  • 일반적으로 훈련 세트와 테스트 세트에 샘플이 골고루 섞여있지 않으면 샘플링이 한쪽으로 치우쳤다는 의미로 샘플링 편향이라고 한다.
  • 골고루 샘플을 뽑거나 데이터 세트를 나누기 전에 섞기 위해 파이썬의 대표적인 배열 라이브러리인 numpy를 활용한다.

넘파이

  • 넘파이 배열은 핵심 부분이 C, C++과 같은 저수준 언어로 개발되어 빠르고, 데이터 과학 분야에 알맞게 최적화되어 있기에 사용,
  • 파이썬 리스트를 넘파이 배열로 만들기 위해 array() 함수에 파이썬 리스트를 전달한다
  • 넘파이 배열의 크기를 알기 위해서는 shape 속성을 사용
  • 입력과 타깃을 같은 위치에 있어야 하기 때문에 넘파이의 arrange() 함수를 사용해 인덱스를 만든다.
  • shuffle() 함수를 통해 인덱스를 무작위로 섞고, 입력과 타깃에 전달하여 랜덤하게 훈련 세트와 테스트 세트를 만든다.

두 번째 머신러닝 프로그램

# 생선의 길이와 무게 리스트

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

fish_data = [[l, w] for l, w in zip(fish_length, fish_weight)]
fish_target = [1]*35 + [0]*14

from sklearn.neighbors import KNeighborsClassifier

kn = KNeighborsClassifier()

import numpy as np

# 리스트를 넘파이 배열로 변환

input_arr = np.array(fish_data)
target_arr = np.array(fish_target)

# 인덱스를 무작위로 섞는다

np.random.seed(42)
index = np.arange(49)
np.random.shuffle(index)

# 랜덤하게 35개의 샘플을 훈련 세트

train_input = input_arr[index[:35]]
train_target = target_arr[index[:35]]

# 랜덤하게 14개의 샘플을 테스트 세트

test_input = input_arr[index[35:]]
test_target = target_arr[index[35:]]

# 산점도 그래프 생성

import matplotlib.pyplot as plt

plt.scatter(train_input[:, 0], train_input[:, 1])
plt.scatter(test_input[:, 0], test_input[:, 1])
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

kn.fit(train_input, train_target)

kn.score(test_input, test_target)

print(kn.predict(test_input))

print(test_target)

확인 문제

  1. 머신러닝 알고리즘의 한 종류로서 샘플의 입력과 타깃을 알고 있을 때 사용할 수 있는 학습 방법은?
    정답: 지도 학습
  2. 훈련 세트와 테스트 세트가 잘못 만들어져 전체 데이터를 대표하지 못하는 현상은?
    정답: 샘플링 편향
  3. 사이킷런은 입력 데이터가 어떻게 구성되어 있을 것으로 기대하나요?
    정답: 행: 샘플, 열: 특성
  4. 배열 arr에서 두 번째 원소에서부터 다섯 번째 원소까지 선택하기 위한 방법은?
    정답: arr[1:5]

02-2 데이터 전처리

넘파이로 데이터 준비하기.

  • 넘파이의 column_stack() 함수를 사용하면, 전달받은 리스트를 일렬로 세운 다음 차례대로 나란히 연결한다.
  • 넘파이의 ones() 함수와 zeros() 함수를 통해 원하는 개수의 1과 0을 채운 배열을 만들어 타깃 데이터를 만들 수 있다.

사이킷런으로 훈련세트와 테스트 세트 나누기

  • 사이킷런 model_section 모듈 아래에 있는 train_test_split() 함수는 함수로 전달되는 리스트나 배열을 비율에 맞게 훈련 세트와 테스트 세트로 나누어 준다.
  • train_test_split() 함수에는 자체적으로 랜덤 시드를 지정할 수 있는 random_state 파라미터가 있다.
  • train_test_split() 함수의 stratify 파라미터에 타깃 데이터를 전달하면 클래스 비율에 맞게 데이터를 나눌 수 있어 훈련 데이터가 작거나 특정 클래스의 샘플 개수가 적을 때 샘플링 편향을 줄일 수 있다.

수상한 도미 한 마리, 기준을 맞춰라

  • 산점도의 그래프에 나타난 거리 비율이 다르기에, 어느 한 축으로 거리가 조금만 멀어져도 아주 큰 값으로 계산된다.
  • 특성의 값이 놓인 범위가 다를 때, 특성의 스케일이 다르다고도 한다.
  • 데이터를 표현하는 기준이 다르면 알고리즘이 올바르게 예측할 수 없기에 (특히 거리 기반일 때), 제대로 사용하려면 특성값을 일정한 기준에 맞춰 주어야 하는데 이를 데이터 전처리라고 한다.
  • 가장 널리 사용하는 전처리 방법 중 하나는 표준점수로, 각 특성 값이 평균에서 표준편차의 몇 배만큼 떨어져 있는지를 나타낸다.
    • 분산은 데이터에서 평균을 뺀 값을 모두 제곱한 다음 평균을 내어 구하고, 표준편차는 분산의 제곱근.
    • 데이터를 표준점수로 변환하는 과정을 표준화라고 한다.
  • np.mean() 함수로 평균을 계산하고, np.std() 함수로 표준 편차를 계산한다.
  • 특성마다 값의 스케일이 다르고 평균과 표준편차는 각 특성별로 계산해야 하기에 axis=0으로 지정.
  • 넘파이에서 산술 연산 대상이 되는 배열들의 모양이 다른 경우에도, 연산이 가능하도록 배열들의 모양을 처리하는 방법 브로드캐스팅이라고 한다.

브로드캐스팅 조건

  1. 둘 중 하나의 배열이 1차원 배열인 경우
  2. 두 배열의 짝이 맞을 때
  3. 두 배열이 뒤에서 부터 대응하는 축의 크기가 동일하거나, 1이어야만 한다.

전처리 데이터로 모델 훈련하기

  • 샘플을 동일한 비율로 변환해줘야 하는데, 훈련 세트의 mean, std를 이용해서 변환해야 한다.
  • 훈련을 마치고 테스트 세트로 평가할 때는, 테스트 세트도 훈련 세트의 평균과 표준편차로 변환해야 하기 때문에 이를 주의해야 한다.
fish_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, 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]
fish_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, 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 numpy as np

fish_data = np.column_stack((fish_length, fish_weight))

fish_target = np.concatenate((np.ones(35), np.zeros(14)))

from sklearn.model_selection import train_test_split

train_input, test_input, train_target, test_target = train_test_split(
    fish_data, fish_target, random_state=42)

train_input, test_input, train_target, test_target = train_test_split(
    fish_data, fish_target, stratify=fish_target, random_state=42)

mean = np.mean(train_input, axis=0)
std = np.std(train_input, axis=0)

train_scaled = (train_input - mean) / std

new = ([25, 150] - mean) / std

from sklearn.neighbors import KNeighborsClassifier

kn = KNeighborsClassifier()

kn.fit(train_scaled, train_target)

test_scaled = (test_input - mean) / std

distances, indexes = kn.kneighbors([new])

import matplotlib.pyplot as plt

plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(new[0], new[1], marker='^')
plt.scatter(train_scaled[indexes,0], train_scaled[indexes,1], marker='D')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

훈련이 끝난 모델의 산개도 그래프

확인문제

  1. 이 방식은 스케일 조정 방식의 하나로 특성값을 평균에서 표준편차의 몇 배수만큼 떨어져 있는지로 변환한 값은?
    정답: 표준점수
  2. 테스트 세트의 스케일을 조정하려고 할 때, 어떤 데이터의 통계 값을 사용해야 하나요?
    정답: 훈련세트
  3. for 반복문을 사용하지 않고 넘파이의 배열의 모든 원소에 대해 산술 연산이 적용되는 기능이 무엇인가요?
    정답: 브로드캐스팅

'머신러닝' 카테고리의 다른 글

[혼공머신] 3. 🛝🌞🫠  (4) 2025.07.21
[혼공머신] 2. 🤷🏻‍♂️😵‍💫🌀  (2) 2025.07.13