newhaneul

[Advanced Python Programming] Lecture 20. Machine Learning 본문

4. University Study/Advanced Python Programming

[Advanced Python Programming] Lecture 20. Machine Learning

뉴하늘 2026. 6. 11. 22:28
728x90

포스팅은 인하대학교 허혜선 교수님의 [202601-EEC3408-001] 고급파이썬프로그래밍을 수강하고 공부한 내용을 정리하기 위한 포스팅입니다.

 

 

1. 머신러닝의 개요

 

지도 학습

  • 훈련 데이터에 대한 정답이 주어진 상태에서 학습하는 방법
  • 분류(Classification): 범주형 값을 예측하는 방법
  • 회귀(Regression): 연속적인 값을 예측하는 방법

 

비지도 학습

훈련 데이터에 대한 정답이 주어지지 않은 상태에서 학습하는 방법

 

절차

  • 1. 데이터 수집: 문제를 해결하기 위한 데이터를 수집하는 단계. 데이터의 크기와 질을 고려해서 데이터를 수집해야 함
  • 2. 데이터 전처리: 수집한 데이터를 학습에 적합한 형태로 가공하는 단계. 데이터에 결측값이 있다면 처리하고, 데이터를 훈련 세트와 테스트 세트로 나눈다.
  • 3. 모델 생성 단계: 문제를 해결하는 머신러닝 모델을 생성하는 단계. 문제에 적합한 모델을 선택하고 훈련 세트를 이용해서 선택한 모델을 학습시키면 모델이 완성됨
  • 4. 모델 평가 단계: 모델의 성능을 평가하는 단계. 주로 정확도를 기준으로 성능을 평가

 

2. 머신러닝 분류

  • K-최근접 이웃(K-NN) 알고리즘
    • 거리가 가까운 데이터 끼리는 속성이 유사할 것이라는 가정을 기반으로 하며 주로 머신러닝의 분류 알고리즘으로 사용된다.
    • 새로운 데이터를 분류할 때 기존 데이터 중 새로운 데이터와 거리가 가까운 이웃 데이터 K개를 이용하는 방식
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np

iris = datasets.load_iris()

print('iris 키:', iris.keys()) # ['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module']
print('데이터:\n', iris['data'][:5]) # [5.1 3.5 1.4 0.2] ...
print('특성 이름:', iris['feature_names']) # ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
print('타깃:\n', iris['target'][:5]) # [0 0 0 0 0]
print('타깃 이름:', iris['target_names']) # ['setosa' 'versicolor' 'virginica']
print('데이터 크기:', iris['data'].shape) # (150, 4)
print('타깃 크기:', iris['target'].shape) # (150,)

X_train, X_test, y_train, y_test = train_test_split(iris['data'], iris['target'], random_state=0)
print(X_train.shape, y_train.shape) # (112, 4) (112,)
print(X_test.shape, y_test.shape) # (38, 4) (38,)

knn = KNeighborsClassifier(n_neighbors=3) # 모델 생성
knn.fit(X_train, y_train) # KNeighborsClassifier 객체 knn이 X_train과 y_train을 사용하여 학습

y_pred = knn.predict(X_test)
print('테스트 세트 예측 값:', y_pred) # [2 1 0 2 0 2 ...]
print('테스트 세트 실제 값:', y_test) # [2 1 0 2 1 2 ...]

print(f'훈련 세트 정확도: {knn.score(X_train, y_train):.3f}') # 0.964
print(f'테스트 세트 정확도: {knn.score(X_test, y_test):.3f}') # 0.974
iris 키: dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
데이터:
 [[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]]
특성 이름: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
타깃:
 [0 0 0 0 0]
타깃 이름: ['setosa' 'versicolor' 'virginica']
데이터 크기: (150, 4)
타깃 크기: (150,)
(112, 4) (112,)
(38, 4) (38,)
테스트 세트 예측 값: [2 1 0 2 0 2 0 1 1 1 2 1 1 1 1 0 1 1 0 0 2 1 0 0 2 0 0 1 1 0 2 1 0 2 2 1 0
 2]
테스트 세트 실제 값: [2 1 0 2 0 2 0 1 1 1 2 1 1 1 1 0 1 1 0 0 2 1 0 0 2 0 0 1 1 0 2 1 0 2 2 1 0
 1]
훈련 세트 정확도: 0.964
테스트 세트 정확도: 0.974

 

LAB: 와인 분류하기

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np

# 데이터 수집하기
wine = datasets.load_wine()
print('wine 키:', wine.keys()) # ['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module']
print('데이터:\n', wine['data'][:5]) # [[1.423e+01 1.710e+00 2.430e+00 ... 1.040e+00 3.920e+00 1.065e+03] ...
print('특성 이름:', wine['feature_names']) # ['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids', 'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue', 'od280/od315_of_diluted_wines', 'proline']
print('타깃:\n', wine['target'][:5]) # [0 0 0 0 0]
print('타깃 이름:', wine['target_names']) # ['class_0' 'class_1' 'class_2']
print('데이터 크기:', wine['data'].shape) # (178, 13)
print('타깃 크기:', wine['target'].shape) # (178,)

# 데이터 전처리하기
X_train, X_test, y_train, y_test = train_test_split(wine['data'], wine['target'], random_state=0)

print(X_train.shape, y_train.shape) # (133, 13) (133,)
print(X_test.shape, y_test.shape) # (45, 13) (45,)

# 모델 생성하기
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, y_train)

# 모델 이용해 예측하기
y_pred = knn.predict(X_test)
print('테스트 세트 예측 값:', y_pred) # [1 0 2 1 0 1 ...]
print('테스트 세트 실제 값:', y_test) # [1 0 2 1 0 1 ...]

# 모델 평가하기
print(f'훈련 세트 정확도: {knn.score(X_train, y_train):.3f}') # 0.977
print(f'테스트 세트 정확도: {knn.score(X_test, y_test):.3f}') # 0.978
wine 키: dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names'])
데이터:
 [[1.423e+01 1.710e+00 2.430e+00 1.560e+01 1.270e+02 2.800e+00 3.060e+00
  2.800e-01 2.290e+00 5.640e+00 1.040e+00 3.920e+00 1.065e+03]
 [1.320e+01 1.780e+00 2.140e+00 1.120e+01 1.000e+02 2.650e+00 2.760e+00
  2.600e-01 1.280e+00 4.380e+00 1.050e+00 3.400e+00 1.050e+03]
 [1.316e+01 2.360e+00 2.670e+00 1.860e+01 1.010e+02 2.800e+00 3.240e+00
  3.000e-01 2.810e+00 5.680e+00 1.030e+00 3.170e+00 1.185e+03]
 [1.437e+01 1.950e+00 2.500e+00 1.680e+01 1.130e+02 3.850e+00 3.490e+00
  2.400e-01 2.180e+00 7.800e+00 8.600e-01 3.450e+00 1.480e+03]
 [1.324e+01 2.590e+00 2.870e+00 2.100e+01 1.180e+02 2.800e+00 2.690e+00
  3.900e-01 1.820e+00 4.320e+00 1.040e+00 2.930e+00 7.350e+02]]
특성 이름: ['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids', 'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue', 'od280/od315_of_diluted_wines', 'proline']
타깃:
 [0 0 0 0 0]
타깃 이름: ['class_0' 'class_1' 'class_2']
데이터 크기: (178, 13)
타깃 크기: (178,)
(133, 13) (133,)
(45, 13) (45,)
테스트 세트 예측 값: [0 1 1 0 1 1 0 1 1 1 0 1 0 2 0 1 0 0 1 0 1 0 1 1 0 1 1 1 2 2 0 0 1 0 0 0 0
 1 1 0 2 0 1 1 1]
테스트 세트 실제 값: [0 2 1 0 1 1 0 2 1 1 2 2 0 1 2 1 0 0 1 0 1 0 0 1 1 1 1 1 1 2 0 0 1 0 0 0 2
 1 1 2 0 0 1 1 1]
훈련 세트 정확도: 0.887
테스트 세트 정확도: 0.733

 

 

3. 머신러닝 회귀

  • 회귀분석: 하나 이상의 독립 변수가 변할 때 종속 변수가 얼마나 변할 것인지, 즉 하나 이상의 독립 변수가 종속 변수에 미치는 영향력을 예측하는 분석 기법
  • 회귀분석의 결과로 독립 변수와 종속 변수 사이의 구체적인 관계를 식으로 표현할 수 있고, 이 식을 회귀식이라 함
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
import numpy as np

# 데이터 수집하기
housing = datasets.fetch_california_housing()
print('housing 키:', housing.keys()) # ['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module']
print('데이터:\n', housing['data'][:3]) # [[8.3252e+00 4.1000e+00 6.9841e+00 1.0230e+00 3.2200e+02 2.5556e+00 3.8800e+01 -1.1900e+02] ...
print('특성 이름:', housing['feature_names']) # ['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']
print('타깃:\n', housing['target'][:3]) # [4.526 3.585 3.521]
print('타깃 이름:', housing['target_names']) # ['MedHouseVal']
print('데이터 크기:', housing['data'].shape) # (20640, 8)
print('타깃 크기:', housing['target'].shape) # (20640,)

# 데이터 전처리하기
X_train, X_test, y_train, y_test = train_test_split(housing['data'], housing['target'], random_state=0)
print(X_train.shape, y_train.shape) # (15480, 8) (15480,)
print(X_test.shape, y_test.shape) # (5160, 8) (5160,)

# 모델 생성하기
model = LinearRegression()
model.fit(X_train, y_train)

# 모델 절편과 계수 확인하기
print('절편:', model.intercept_) # -36.94186147644124
print('계수:', np.round(model.coef_, 3)) # [ 4.362e-01 -1.071e-02 -1.073e-01 2.953e-01 -4.057e-06 -4.316e-03 -4.205e+00 -4.421e+00]

# 모델 이용해 예측하기
y_pred = model.predict(X_test)
print('테스트 세트 예측 값:', np.round(y_pred[:5], 3)) # [0.501 0.486 0.741 1.422 0.265]
print('테스트 세트 실제 값:', np.round(y_test[:5], 3)) # [0.526 0.486 0.741 1.422 0.265]

# 모델 평가하기
print(f'훈련 세트 정확도: {model.score(X_train, y_train):.3f}') # 0.611
print(f'테스트 세트 정확도: {model.score(X_test, y_test):.3f}') # 0.591
housing 키: dict_keys(['data', 'target', 'frame', 'target_names', 'feature_names', 'DESCR'])
데이터:
 [[ 8.32520000e+00  4.10000000e+01  6.98412698e+00  1.02380952e+00
   3.22000000e+02  2.55555556e+00  3.78800000e+01 -1.22230000e+02]
 [ 8.30140000e+00  2.10000000e+01  6.23813708e+00  9.71880492e-01
   2.40100000e+03  2.10984183e+00  3.78600000e+01 -1.22220000e+02]
 [ 7.25740000e+00  5.20000000e+01  8.28813559e+00  1.07344633e+00
   4.96000000e+02  2.80225989e+00  3.78500000e+01 -1.22240000e+02]]
특성 이름: ['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']
타깃:
 [4.526 3.585 3.521]
타깃 이름: ['MedHouseVal']
데이터 크기: (20640, 8)
타깃 크기: (20640,)
(15480, 8) (15480,)
(5160, 8) (5160,)
절편: -36.60959377871424
계수: [ 0.439  0.01  -0.103  0.617 -0.    -0.004 -0.417 -0.431]
테스트 세트 예측 값: [2.278 2.796 1.909 1.026 2.959]
테스트 세트 실제 값: [1.369 2.413 2.007 0.725 4.6  ]
훈련 세트 정확도: 0.611
테스트 세트 정확도: 0.591

 

 

LAB: 당뇨병 진행 정도 예측하기

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
import numpy as np

# 데이터 수집하기
diabetes = datasets.load_diabetes()
print('diabetes 키:', diabetes.keys()) # ['data', 'target', 'frame', 'DESCR', 'feature_names', 'data_filename', 'target_filename', 'data_module']
print('데이터:\n', diabetes['data'][:3])
print('특성 이름:', diabetes['feature_names']) # ['age', 'sex', 'bmi', 'bp', 's1', 's2', 's3', 's4', 's5', 's6']
print('타깃:\n', diabetes['target'][:3]) # [151.  75. 141.]
print('데이터 크기:', diabetes['data'].shape) # (442, 10)
print('타깃 크기:', diabetes['target'].shape) # (442,)

# 데이터 전처리하기
X_train, X_test, y_train, y_test = train_test_split(diabetes['data'], diabetes['target'], random_state=0)
print(X_train.shape, y_train.shape) # (331, 10) (331,)
print(X_test.shape, y_test.shape) # (111, 10) (111,)

# 모델 생성하기
model = LinearRegression()
model.fit(X_train, y_train)

# 모델 절편과 계수 확인하기
print('절편:', np.round(model.intercept_, 3)) # 153.068
print('계수:', np.round(model.coef_, 3)) # [ -43.262 -208.666  593.407  302.891 -560.191  261.408   -8.867  135.932  703.184   28.35 ]

# 모델 이용해 예측하기
y_pred = model.predict(X_test)
print('테스트 세트 예측 값:', np.round(y_pred[:5], 3)) # [241.845 250.119 164.968 119.116 188.232]
print('테스트 세트 실제 값:', np.round(y_test[:5], 3)) # [321. 215. 127.  64. 175.]

# 모델 평가하기
print(f'훈련 세트 정확도: {model.score(X_train, y_train):.3f}') # 0.555
print(f'테스트 세트 정확도: {model.score(X_test, y_test):.3f}') # 0.359
diabetes 키: dict_keys(['data', 'target', 'frame', 'DESCR', 'feature_names', 'data_filename', 'target_filename', 'data_module'])
데이터:
 [[ 0.03807591  0.05068012  0.06169621  0.02187239 -0.0442235  -0.03482076
  -0.04340085 -0.00259226  0.01990749 -0.01764613]
 [-0.00188202 -0.04464164 -0.05147406 -0.02632753 -0.00844872 -0.01916334
   0.07441156 -0.03949338 -0.06833155 -0.09220405]
 [ 0.08529891  0.05068012  0.04445121 -0.00567042 -0.04559945 -0.03419447
  -0.03235593 -0.00259226  0.00286131 -0.02593034]]
특성 이름: ['age', 'sex', 'bmi', 'bp', 's1', 's2', 's3', 's4', 's5', 's6']
타깃:
 [151.  75. 141.]
데이터 크기: (442, 10)
타깃 크기: (442,)
(331, 10) (331,)
(111, 10) (111,)
절편: 153.068
계수: [ -43.262 -208.666  593.407  302.891 -560.191  261.408   -8.867  135.932
  703.184   28.35 ]
테스트 세트 예측 값: [241.845 250.119 164.968 119.116 188.232]
테스트 세트 실제 값: [321. 215. 127.  64. 175.]
훈련 세트 정확도: 0.555
테스트 세트 정확도: 0.359

 

 

4. MNIST 분류하기

from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt

# 데이터 수집하기
mnist = fetch_openml('mnist_784', as_frame=False, parser='auto')
print(mnist.keys())
print('데이터 크기:', mnist['data'].shape) # (70000, 784)
print('타깃 크기:', mnist['target'].shape) # (70000,)

# 이미지 출력하기
plt.figure(figsize=(4,4))
for i in range(9):
    plt.subplot(3, 3, i+1)
    plt.xticks([])
    plt.yticks([])
    plt.imshow(mnist['data'][i].reshape(28, 28), cmap='binary')
    plt.xlabel(mnist['target'][i])
plt.show()

# 데이터 전처리하기
X_train, X_test, y_train, y_test = train_test_split(mnist['data'], mnist['target'], random_state=0)
print(X_train.shape, y_train.shape) # (52500, 784) (52500,)
print(X_test.shape, y_test.shape) # (17500, 784) (17500,)

# 모델 생성하기
knn = KNeighborsClassifier()
knn.fit(X_train, y_train)

# 모델 이용해 예측하기
y_pred = knn.predict(X_test)
print('테스트 세트 예측 값:', y_pred[:10]) # ['0' '4' '1' '2' '7' '9' '7' '1' '1' '7']
print('테스트 세트 실제 값:', y_test[:10]) # ['0' '4' '1' '2' '7' '9' '7' '1' '1' '7']

# 모델 평가하기
print(f'훈련 세트 정확도: {knn.score(X_train, y_train):.3f}') # 0.555
print(f'테스트 세트 정확도: {knn.score(X_test, y_test):.3f}') # 0.359
dict_keys(['data', 'target', 'frame', 'categories', 'feature_names', 'target_names', 'DESCR', 'details', 'url'])
데이터 크기: (70000, 784)
타깃 크기: (70000,)

(52500, 784) (52500,)
(17500, 784) (17500,)
테스트 세트 예측 값: ['0' '4' '1' '2' '7' '9' '7' '1' '1' '7']
테스트 세트 실제 값: ['0' '4' '1' '2' '7' '9' '7' '1' '1' '7']

728x90