머신러닝 기초

김승오·2024년 1월 3일
0

머신러닝

목록 보기
1/9

머신러닝

1. 머신러닝이란?

  • 일반 소프트웨어와 다르게 머신러닝 기반 소프트웨어는 데이터와 사용된 알고리즘에 따라 때로는 다른 결과를 추론해낸다.
  • 머신러닝이란 데이터와 알고리즘을 기반으로 추론하는 프로그램이라고 정의할 수 있다.

Untitled

2. 지도와 비지도 학습

  • 지도학습: 정답을 알려주면서 진행되는 학습, 주로 주어진 데이터와 레이블을 이용해 새로운 데이터의 레이블을 예측해야 할 때 사용됨.(일반화)
  • 비지도학습: 정답 없이 진행되는 학습, 학습 할 때 레이블 없이 데이터만 필요.(분류)
  • 강화학습

3.1 예제: iris 데이터셋

from sklearn import datasets

d=datasets.load_iris()

for i in range(0,len(d.data)):
    print(i+1, d.data[i], d.target[i])
  • iris 데이터셋은 Setosa, Versicolor, Virginia 세 부류로 구성.
  • 각 샘플은 4개의 변수 - sepal length, sepal width, petal length, petal width - 로 구성됨.
  • 기계 학습에서 각 변수를 특징이라 부름.
  • 샘플 하나에 여러 개의 특징이 있으므로 벡터로 표현하는데, 이 벡터를 특징 벡터라 부름.
  • 기계 학습에서는 부류 정보를 레이블 또는 참값이라 부른다.
  • 프로그램 출력 결과를 보면 Setosa 50개, Versicolor 50개, Virginia 50개가 각각의 부류임을 알 수 있다.

샘플 [특징 벡터] 레이블


1 [5.1 3.5 1.4 0.2] 0
2 [4.9 3. 1.4 0.2] 0
3 [4.7 3.2 1.3 0.2] 0
4 [4.6 3.1 1.5 0.2] 0
5 [5. 3.6 1.4 0.2] 0
6 [5.4 3.9 1.7 0.4] 0
7 [4.6 3.4 1.4 0.3] 0
8 [5. 3.4 1.5 0.2] 0
9 [4.4 2.9 1.4 0.2] 0
10 [4.9 3.1 1.5 0.1] 0
11 [5.4 3.7 1.5 0.2] 0
12 [4.8 3.4 1.6 0.2] 0
13 [4.8 3. 1.4 0.1] 0
14 [4.3 3. 1.1 0.1] 0
15 [5.8 4. 1.2 0.2] 0
16 [5.7 4.4 1.5 0.4] 0
17 [5.4 3.9 1.3 0.4] 0
18 [5.1 3.5 1.4 0.3] 0
19 [5.7 3.8 1.7 0.3] 0
20 [5.1 3.8 1.5 0.3] 0
21 [5.4 3.4 1.7 0.2] 0
22 [5.1 3.7 1.5 0.4] 0
23 [4.6 3.6 1. 0.2] 0
24 [5.1 3.3 1.7 0.5] 0
25 [4.8 3.4 1.9 0.2] 0
26 [5. 3. 1.6 0.2] 0
27 [5. 3.4 1.6 0.4] 0
28 [5.2 3.5 1.5 0.2] 0
29 [5.2 3.4 1.4 0.2] 0


  • iris데이터 셋 (n=150, d=4)(데이터 셋의 크기, d 개의 특징 벡터)
  • 레이블은 y로 표기.
  • 부류의 개수는 3개이며 y는 0, 1, 2 중 한 값을 가짐.

3.2 모델링과 예측

  • SVM(SupportVectorMachine)모델 사용
from sklearn import datasets
from sklearn import svm  #sklearn 라이브러리가 제공하는 svm 클래스 import

d=datasets.load_iris()

s = svm.SVC(gamma=0.1, C=10)  #svm 클래스가 제공하는 분류 모델 SVC를 생성해 객체 s에 저장
s.fit(d.data, d.target) #fit 함수를 사용해 모델을 학습

new_d=[[6.5, 3.2, 6.0, 2.5], [7.1, 3.1, 4.7, 1.35]] #예측하기위한 새로운 데이터 테스트 집합

res=s.predict(new_d) #예측
print("새로운 2개 샘플의 부류는", res)

새로운 2개 샘플의 부류는 [2 1]


gamma는 결정 경계의 유연성을 조절하고, C는 오분류에 대한 페널티를 조절

원리: 새로운 특징 공간 내에서 선형 모델을 이용해 분류

Untitled

  1. gamma: gamma 매개변수는 결정 경계의 유연성을 조절합니다. gamma 값이 작을수록 결정 경계가 더 부드러워지고, 큰 영향을 받는 데이터 포인트가 적어집니다. 작은 gamma 값은 결정 경계를 평활화하여 단순한 모델을 생성합니다. 반대로, 큰 gamma 값은 결정 경계를 더 정확하게 적합시키는데 사용되며, 학습 데이터에 더 적합하게 모델을 구축할 수 있습니다. 너무 작은 gamma 값은 과소적합을, 너무 큰 gamma 값은 과적합을 유발할 수 있습니다.
    ⇒ gamma 크기가 작을수록 선형 분리에 가까워짐
  2. C: C 매개변수는 오분류에 대한 페널티를 조절합니다. C 값이 작을수록 오분류를 허용하며, 모델은 일반화되고 부드러운 결정 경계를 만듭니다. 작은 C 값은 데이터 포인트 중 일부에 대한 오분류를 허용하므로 모델이 더 일반화될 수 있습니다. 반대로, 큰 C 값은 오분류에 대해 더 엄격한 페널티를 부과하여 정확한 결정 경계를 만듭니다. 큰 C 값은 학습 데이터에 더 적합하게 모델을 구축할 수 있지만, 과적합의 위험도 증가할 수 있습니다.
    ⇒C 크기가 작을수록 선형 분리에 가까워짐

과적합: 과다하게 복잡한 결정 경계

(둘 다 비슷한 얘기 아닌가?)

3.3 데이터 분포

import plotly.express as px #Plotly Express를 px로 import. Plotly Express는 데이터 시각화 인터페이스
import plotly.offline as offline #오프라인 파일로 저장하는 인터페이스

df = px.data.iris() # iris 데이터셋을 df 변수에 할당

fig = px.scatter_3d(df, x='sepal_length', y='sepal_width', z='petal_width', color='species') 
#x, y, z는 각각 x축, y축, z축에 해당하는 열의 이름을 지정하고, 
#color는 데이터 포인트를 색으로 구분할 열의 이름을 지정. 
#열의 이름은(sepal_length), (sepal_width), (petal_width)을 사용하며, 종(species)에 따라 색으로 구분

offline.plot(fig, filename='scatter_plot.html') #오프라인 파일로 저장

Untitled

  • 기계 학습의 전형적인 과정

데이터 수집 → 특징 추출 → 모델링 → 예측

3.6 성능 측정

TP: 긍정을 긍정으로 예측(참 긍정)

FN: 긍정을 부정으로 잘 못 예측(거짓 부정)

FP: 부정을 긍정으로 잘 못 예측(거짓 긍정)

TN: 부정을 부정으로 예측(참 부정)

혼동 행렬: 부류별로 옳은 분류와 틀린 분류의 개수를 기록한 행렬

그라운드 트루스
긍정부정
예측값긍정TP(참 긍정)FP(거짓 긍정)
부정FN(거짓 부정)TN(참 부정)

일반화: 새로운 데이터로 성능을 측정하는 일

성능 측정 기준

  • 정확률: 가장 널리 쓰임
정확률=맞힌샘플수전체샘플수정확률 = \frac{맞힌 샘플 수}{전체 샘플 수}
  • 특이도, 민감도: 주로 의학분야에서 쓰이며 양성과 음성을 잘 구분했는지 판단
민감도=TP(TP+FN)민감도=\frac{TP}{(TP+FN)}
특이도=TN(TN+FP)특이도=\frac{TN}{(TN+FP)}

Untitled

Untitled

  • 정밀도, 재현율: 주로 불균형한 데이터셋이나 거짓 양성(FP) 또는 거짓 음성(FN) 오류가 중요한 경우에 활용
정밀도=TP(TP+FP)정밀도=\frac{TP}{(TP + FP)}
재현율=TP(TP+FN)재현율 =\frac{TP}{(TP + FN)}

Untitled


훈련/검증/테스트 집합으로 쪼개기

  • 객관적인 성능 측정을 위해 데이터를 적절한 비율로 훈련 집합, 검증 집합(정확률 측정, 다른 모델과 비교), 테스트 집합으로 나누어 사용함.
from sklearn import datasets
from sklearn import svm
from sklearn.model_selection import train_test_split
import numpy as np

# 데이터셋을 읽고 훈련 집합과 테스트 집합으로 분할
digit = datasets.load_digits()
x_train, x_test, y_train, y_test = train_test_split(digit.data, digit.target, train_size=0.6)
#특징 벡터, 레이블, 훈련집합 0.6, 테스트집합 0.4

#svm의 분류 모델 SVC를 학습
s=svm.SVC(gamma=0.001)
s.fit(x_train, y_train)

res = s.predict(x_test)

#혼동 행렬 구함
conf=np.zeros((10,10))
for i in range(len(res)):
    conf[res[i]][y_test[i]]+=1
print(conf)

#정확률 측정하고 출력
no_correct = 0
for i in range(10):
    no_correct += conf[i][i]
accuracy = no_correct/len(res)
print("테스트 집합에 대한 정확률은", accuracy*100, "%입니다.")

[[64. 0. 0. 0. 0. 0. 0. 0. 0. 0.][ 0. 75. 0. 0. 0. 0. 0. 0. 1. 0.]
[ 0. 0. 61. 0. 0. 0. 0. 0. 0. 0.][ 0. 0. 0. 69. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 74. 0. 0. 0. 0. 0.][ 0. 0. 0. 1. 0. 77. 0. 0. 0. 1.]
[ 0. 0. 0. 0. 0. 1. 82. 0. 0. 0.][ 0. 0. 1. 1. 0. 0. 0. 66. 0. 1.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 73. 0.][ 0. 0. 0. 0. 0. 1. 0. 0. 0. 70.]]
테스트 집합에 대한 정확률은 98.88734353268428 %입니다.

출력 결과

  • 부류 0에 속하는 샘플 64개는 모두 맞혔다. 부류 2는 62개인데 61개를 2로 맞추고. 1개를 7로 잘 못 분류했다.
  • 총719개의 샘플에서 7개를 틀려 정확률은 약 98.887%이다.

교차 검증

  • 우연히 높은 정확률을 얻을 경우를 배제하기 위함.
  • k-겹 교차 검증: 훈련 집합을 같은 크기의 부분집합 k개로 나누어 학습.
from sklearn import datasets
from sklearn import svm
from sklearn.model_selection import cross_val_score
import numpy as np

# 데이터셋을 읽고 5겹 교차 검증
digit = datasets.load_digits()
s=svm.SVC(gamma=0.001)
accuracies = cross_val_score(s, digit.data, digit.target, cv=5)

print(accuracies)
print("정확률(평균)=%0.3f, 표준편차=%0.3f"%(accuracies.mean()*100, accuracies.std()))

[0.975 0.95 0.98328691 0.99164345 0.96100279]
정확률(평균)=97.219, 표준편차=0.015

신뢰도 향상

4. 신경망 기초

퍼셉트론의 원리

  • 퍼셉트론(기계) = 뉴런(생물)

Untitled

  • 퍼셉트론을 활성화 함수를 거쳐 최종 출력값 결정(1과 -1로 분류)
  • 출력값과 기댓값(레이블)을 비교해 오차 계산(손실 함수 적용) 후
  • weight값과 bias 값을 학습에 따라 바꿈 (최적화 함수 적용)
from sklearn.linear_model import Perceptron

#훈련 집합 구축
X= [[0,0], [0,1], [1,0], [1,1]]
y= [-1, 1, 1, 1]

#fit 함수로 Perceptron 학습
p=Perceptron()
p.fit(X,y)

print("학습된 퍼셉트론의 매개변수: ",p.coef_, p.intercept_) #가중치w1, w2 / 가중치w0
print("훈련집합에 대한 예측: ", p.predict(X)) #예측값
print("정확률 측정: ", p.score(X,y)*100,"%")

학습된 퍼셉트론의 매개변수: [[2. 2.]][-1.]
훈련집합에 대한 예측: [-1 1 1 1]
정확률 측정: 100.0 %


다층 퍼셉트론

  • 입력층, 은닉층, 출력층으로 구성
  • 퍼셉트론 여러 개를 병렬로 배치하고 순차적으로 이어 붙인 신경망

Untitled

  • 새로운 특징 공간으로 변환
  • 활성함수 Relu 사용

손실 함수

  • 레이블과 예측값의 차이
  • 레이블=y, 예측값=o 라고 한다면
  1. 퍼셉트론
(y1o1)2+(y2o2)2+...+(ycoc)2=yo\sqrt{(y_1-o_1)^2+(y_2-o_2)^2+...+(y_c-o_c)^2} = \mid\mid y-o\mid\mid
  1. 다중 퍼셉트론
    1. 미니 배치로 처리: 훈련 데이터를 일정한 크기의 부분집합으로 나누고 부분집합별로 처리
1MxMyo2\frac{1}{\mid M\mid}\sum_{x\in M}\mid\mid y-o\mid\mid^2

Untitled

다층 퍼셉트론 프로그래밍


from sklearn import datasets
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
import numpy as np

#데이터셋을 읽고 훈련 집합과 테스트 집합으로 분할
digit = datasets.load_digits()
x_train, x_test, y_train, y_test = train_test_split(digit.data, digit.target, train_size=0.6)

#MLP 분류기 모델을 학습
mlp = MLPClassifier(hidden_layer_sizes=(100), learning_rate_init=0.001, batch_size=32, max_iter=300, solver='sgd', verbose=True)
mlp.fit(x_train, y_train)

res = mlp.predict(x_test) #테스트 집합으로 예측

#혼동 행렬
conf = np.zeros((10, 10))
for i in range(len(res)):
    conf[res[i]][y_test[i]]+=1
print(conf)

#정확률 계산
no_correct = 0
for i in range(10):
    no_correct+=conf[i][i]
accuracy = no_correct/len(res)
print("테스트 집합에 대한 정확률은 ", accuracy*100, "%입니다.")

hidden_layer_sizes=(100) : 노드가 100개인 은닉층 하나

learning_rate_init=0.001 : 학습률의 초기값. 학습률은 가중치 업데이트 시 사용되는 상수.

batch_size=32 : 미니 배치 경사 하강법에서 한 번의 가중치 업데이트를 위해 사용되는 샘플의 수.

max_iter=300 : 최대 반복 횟수

solver='sgd' : 최적화 알고리즘으로 확률적 경사 하강법을 나타내는 'sgd'를 선택함.

verbose=True : 학습 과정 중에 진행 상황을 출력할지 여부를 나타냄. True로 설정하면 학습 중 출력이 표시.

Iteration 1, loss = 2.32213324
Iteration 2, loss = 0.32505309
Iteration 3, loss = 0.19824941
Iteration 4, loss = 0.14842346
Iteration 5, loss = 0.11559600
Iteration 6, loss = 0.11005246
Iteration 7, loss = 0.08608624
Iteration 8, loss = 0.07677681
Iteration 9, loss = 0.06741344
Iteration 10, loss = 0.05846336
Iteration 11, loss = 0.05638974
Iteration 12, loss = 0.05124250

Iteration 88, loss = 0.00553884
Iteration 89, loss = 0.00548285
Iteration 90, loss = 0.00540366
Iteration 91, loss = 0.00532382
Iteration 92, loss = 0.00524335
Iteration 93, loss = 0.00517307
Iteration 94, loss = 0.00514018
Training loss did not improve more than tol=0.000100 for 10 consecutive epochs. Stopping.
[[68. 0. 0. 0. 0. 0. 1. 0. 0. 0.][ 0. 89. 1. 0. 0. 0. 0. 0. 3. 0.]
[ 0. 0. 72. 0. 0. 0. 0. 0. 0. 0.][ 0. 0. 0. 78. 0. 0. 0. 0. 1. 1.]
[ 0. 0. 0. 0. 75. 1. 0. 0. 0. 0.][ 0. 0. 0. 2. 0. 63. 0. 0. 0. 1.]
[ 0. 1. 0. 0. 0. 0. 69. 0. 0. 0.][ 0. 0. 0. 0. 1. 0. 0. 65. 0. 0.]
[ 0. 0. 0. 1. 0. 0. 0. 0. 55. 1.][ 0. 0. 0. 0. 0. 1. 0. 1. 0. 68.]]
테스트 집합에 대한 정확률은 97.63560500695411 %입니다.

  • 실행이 중단된 이유: max_iter=300으로 300세대 반복하라고 했으나,
    함수 API가 제공하는 기본값tol = 0.0001’과 ‘n_iter_no_change=10’으로 인해 멈추었다.
    이는 10세대 동안 손실 함수의 감소량이 0.0001 이하면 멈추라는 뜻이다.
profile
코딩코

0개의 댓글

관련 채용 정보