[인공지능] chatgpt를 활용한 기계 학습과 인식1 #AI #SVC #SVM #chatgpt

2023. 4. 5. 18:00_Study/AI

728x90

기계 학습과 인식🐇¸.•*¨*•¸.•*¨*•¸.•*¨*•¸.•*¨*•

해당 자료는 강의 학습자료입니다. 강의 이외의 내용은 검색 및 다양한 자료를 통해 공부하며 정리한 내용의 포스팅입니다.

#AI #인공지능 #기계학습과인식 #chatgpt #python #study

 


 

사람은 끊임없이 주위 환경을 인식한다. 이는 생존과 자기 발전에 필수적이다. 예를 들어 타인이 말한 소리, 얼굴 감정 등과 같은 정보가 주어진다. 인공지능도 주위 환경을 인식한다. 이러한 인식 프로그램을 만드는데 필요한 기계 학습의 기초 지식을 공부하기로 한다.

 

 

 

 

기계학습에선 데이터가 중요하다. 이는 에너지를 만드는 연료에 해당하며, 데이터가 없으면 기계학습 적용이 불가능하다.

 

가장 단순 iris 데이터로 이를 알아보자.

 

사이킷럿(scikit-learn) 라이브러리 설치

pip install scikit-learn

 

import를 사용하여 따로 다운받지 않고 dataset이 바로 올라올 수 있다.

from sklearn import datasets

d= datasets.load_iris()
print(d.DESCR)

1. sklearn의 datasets클래스를 불러오기

2. datasets.load_iris함수를 이용해 객체 d에 저장

3. 객체 d의 DESCR 변수 출력

 

 

기계 학습의 용어

- 샘플로 구성되는 데이터셋

- 특징으로 구성되는 특징 벡터(feature vector)

- 부류 (class)

 

기계 학습이 사용하는 데이터는 여러 개의 샘플을 담고 있어서 데이터셋이라고 부르기도 한다. 여기서는 데이터와 데이터 셋을 구분하지 않고 함께 사용하는데, 데이터셋은 iris와 같이 특정한 데이터를 가리킬 때 주로 사용한다.

 

d.data(특징벡터), d.target(레이블)

 

기계 학습에서 데이터 셋의 표현

- 샘플을 특징 벡터와 레이블로 표현

특징 벡터는 x로 표기(d는 특징의 개수로서 특징벡터의 차원)

 

레이블은 0,1,2,,,,,c-1의 값 또는 1,2,,,,c-1,c의 값 또는 원핫 코드

- 원핫 코드는 한 요소만 1인 이진열

SVM(Support vector machine)이라는 기계 학습 모델을 사용하여 예시를 설명하고 있다.

SVC의 분류기 모델 SVC 클래스의 객체를 생성하여 s에 저장하였다.

s의 fit 함수는 훈련 집합을 가지고 학습을 수행(매개변수로 특징 벡터 iris.data와 레이블 iris, target을 설정)

객체 s의 predict 함수는 테스트 집합을 가지고 예측 수행

 

이처럼 기계학습은 모델링과 예측을 위해서 두 집합이 필요하다.

훈련 집합(Training set)

기계 학습 모델을 학습하는데 쓰는 데이터로서 특징 벡터와 레이블 정보를 모두 제공

 

테스트 집합 (Test set)

학습을 마친 모델의 성능을 측정하는데 쓰는 데이터로서 예측할 때는 특징 벡터 정보만 제공하고, 예측 결과를 가지고 정확률을 측정할 때 레이블 정보를 사용

위에선 new_d를 의미한다.

 

하이퍼 매개변수 설정

하이퍼 매개변수(hyper parameter)란 모델의 동작을 제어하는데 쓰는 변수로, 모델의 학습을 시작하기 전에 설정해야 하는데 적절한 값으로 설정해야 좋은 성능을 얻을 수 있다. 최적의 하이퍼 매개변수 값을 자동으로 설정하는 일을 하이퍼 매개변수 최적화라고 한다.

 

 

인공지능을 설계하는데 4가지의 단계가 있다. 예를들어 사과를 분류하는 인공지능을 설계한다고 가정해보자.

1. 데이터 확보

- 상중하 비율이 비슷하게 수천 개의 사과를 수집한다 (데이터 편향 data bias을 방지하기 위해 여러 농장에서 이를 수집한다)

- 카메라로 촬용하여 파일에 저장한다.

 

2. 특징 벡터와 레이블 준비

사과의 크기, 색깔, 표면의 균일도와 같은 분별력이 높은 특징을 사용한다.

컴퓨터 비전 기술로 특징 추출 프로그램을 작성하여 특징을 추출하여 apple.data에 저장

사과 분류 전문가를 고용하여 레이블링. apple.target 파일에 저장

 

3. 학습하는 과정을 프로그래밍 (훈련 데이터 사용)

from sklearn import svm
s = svm.SVC(gamma=0.1, C=10)
s.fit(apple.data, apple.target)

SVC : Support Vector Classification , 표준 SVM 오류 처리 방식이 조금 차이가 있고 거의 똑같은 방식

SVM : Support Vector Machine

 

4. 예측 과정을 프로그래밍 (새로 수집한 테스트 데이터 사용)

s.predict(x)

 

SVM 알고리즘의 목표는 한 클래스의 데이터 점을 다른 클래스의 데이터 점과 가능한 한 가장 잘 구분해내는 초평면을 찾는 것입니다. 여기서 "가장 잘 구분해내는"은 두 클래스 사이의 가장 큰 마진을 갖는 초평면으로 정의

 

C : float, default=1.0

Regularization parameter. The strength of the regularization is inversely proportional to C. Must be strictly positive. The penalty is a squared l2 penalty.

 

- 정규화 매개변수. 무조건 양의 값을 가져야 한다.

- 정규화 강도는 C에 반비례한다.

- 패널티는 I2의 제곱

 

무슨 소린가 싶어서 좀 더 알아봤다. C를 작게하면 훈련 데이터 분류를 부정확하게(직선화) Margin을 크게하고 C를 크게하면 훈련데이터 분류를 정확하게 한다. 따라서 Noise가 많은 데이터라면 C를 작게. Noise가 적은 데이터라면 C를 크게하는 것이 좋다고 한다. 여기서 Margin이란 두 데이터 사이의 간격이다.

 

gamma : {‘scale’, ‘auto’} or float, default=’scale’

Kernel coefficient for ‘rbf’, ‘poly’ and ‘sigmoid’.

  • if gamma='scale' (default) is passed then it uses 1 / (n_features * X.var()) as value of gamma,
  • if ‘auto’, uses 1 / n_features
  • if float, must be non-negative.

scale, auto 또는 float, default값은 scale

rgv, poly, sigmoid 사용가능

- scale인 경우 :  1 / (n_features * X.var())

- auto 인 경우 : 1 / n_features

- float 인 경우 : 음수가 아니어야한다. (양수)

 

 

이게 뭔소린고 싶어서 직접 SVC 데이터를 시각화 해보기로 했다. 2차원 시각화를 위해선 두 특징 sepal length와 sepal width만 사용하기로 했다.

DESCR : 자세한 정보

 

 

import mglearn

mglearn 사용시 해당 버전이 1.2이상부터는 삭제가 되어 다른 방법으로 시각화를 해야한다.

 

 

이 뒤로 어떻게 해야할지 몰라서 chat gpt의 도움을 받았다.

 

 

 

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets, svm

# Load iris dataset
iris = datasets.load_iris()
X = iris.data[:, :2]  # we only take the first two features
y = iris.target

# Fit SVM classifier
C = 1.0  # regularization parameter
svc = svm.SVC(kernel='linear', C=C)
svc.fit(X, y)

# Create a meshgrid to plot decision boundary
xmin, xmax = X[:, 0].min() - 1, X[:, 0].max() + 1
ymin, ymax = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(xmin, xmax, 0.02),
                     np.arange(ymin, ymax, 0.02))

# Predict class labels for each point in the meshgrid
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

# Plot decision boundary and scatter plot of the data points
plt.contourf(xx, yy, Z, cmap=plt.cm.coolwarm, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.coolwarm)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.xticks(())
plt.yticks(())
plt.title('SVC with linear kernel')
plt.show()

 

C를 바꾸어 보았다. 변하는 게 눈에 안보여서 chat gpt에게 물어봤다.

 

 

C를 0.1로 줄여서 정규화 강도를 증가시켰다. 따라서 더 선형적인 경계값이 생겼다고 한다. 그렇다면 늘리면 동그란 곡선이 되는걸까? 라고 생각했는데 육안으로 변함이 없다. chat gpt에게 다시 물어봤다. 좀 많이 신기하다....  사실 kernel을 linear로 잡았는데 곡선이 될리가 없지만

 

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets, svm

# Load iris dataset
iris = datasets.load_iris()
X = iris.data[:, :2]  # we only take the first two features
y = iris.target

# Set up a meshgrid for plotting
h = .02  # step size in the mesh
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                     np.arange(y_min, y_max, h))

# Set up the plot
fig, axs = plt.subplots(2, 2, figsize=(10, 10))
fig.subplots_adjust(wspace=0.4, hspace=0.4)

# Train an SVM for different values of C and plot the decision boundary
for i, C in enumerate([0.01, 0.1, 1, 10]):
    # Train the SVM
    svc = svm.SVC(kernel='linear', C=C).fit(X, y)

    # Plot the decision boundary
    Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    axs[i//2, i%2].contourf(xx, yy, Z, cmap=plt.cm.coolwarm, alpha=0.8)

    # Plot the data points
    axs[i//2, i%2].scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.coolwarm)
    axs[i//2, i%2].set_xlim(xx.min(), xx.max())
    axs[i//2, i%2].set_ylim(yy.min(), yy.max())
    axs[i//2, i%2].set_xlabel('Sepal length')
    axs[i//2, i%2].set_ylabel('Sepal width')
    axs[i//2, i%2].set_xticks(())
    axs[i//2, i%2].set_yticks(())
    axs[i//2, i%2].set_title('SVC with linear kernel, C = {}'.format(C))

plt.show()

chat gpt : In this code, we first set up a meshgrid for plotting, as well as a 2x2 grid of subplots to visualize the decision boundaries for different values of C. We then train an SVM for each value of C (0.01, 0.1, 1, and 10) using the linear kernel, and plot the decision boundary and the data points for each SVM in a separate subplot. The C parameter is passed to the SVM constructor as an argument, and we use the fit method to train the SVM on the Iris dataset. We then use the predict method to generate class predictions for each point in the meshgrid, and use the contourf method to plot the decision boundary as a color map.

When you run this code, you should see four subplots, each showing the decision boundary for an SVM trained with a different value of C. As you can see, increasing the value of C leads to a more complex decision boundary that fits the training data more closely, while decreasing the value of C leads to a simpler decision boundary with more regularization.

 

보다시피 C 값을 늘리면 교육 데이터에 더 가깝게 적합되는 보다 복잡한 의사 결정 경계가 생성되고 C 값을 줄이면 보다 정규화된 보다 간단한 의사 결정 경계가 생성됩니다.

 

정말 C의 차이로 분류 값의 경계가 달라진다. C가 작을수록 margin을 크게하여 데이터 분류를 부정확하게한다. -> 이 역시 봐도 잘 모르겠다. 다른 데이터로 부탁해보자. 부탁해본 결과 .. 차이가 없다. 아무래도 직선이라 chat gpt말고 사람이 확인하기엔 비슷한가보다... 곡선으로 만들어달라고 부탁하니까 gamma 변수를 사용하기 시작했다. iris data를 곡선으로 분류한 모습이다.

 

 

 

chat gpt : In this code, we first load the Iris dataset and split it into training and test sets. We then create a meshgrid for plotting the decision boundary. We next define a list of C values and loop over them to train multiple SVMs with different values of C. For each SVM, we plot the decision boundary and the training data points using the contourf method and the scatter method, respectively. Finally, we add titles and labels to the plots and show them all together using the subplots function.

When you run this code, you should see a figure with four plots, each showing the decision boundary of an SVM with a different value of C. As C increases, the SVM becomes more prone to overfitting, and the decision boundary becomes more wiggly and more closely aligned with the training data points. Conversely, as C decreases, the SVM becomes more prone to underfitting, and the decision boundary becomes smoother and more separated from the training data points.

 

C가 증가함에 따라 SVM은 과적합되기 쉬워지고 의사 결정 경계는 교육 데이터 포인트와 더 밀접하게 조정됩니다. 반대로, C가 감소하면 SVM이 부족해지기 쉬워지고, 의사 결정 경계가 훈련 데이터 포인트에서 더 매끄럽고 더 분리됩니다.

드디어 원하는 데이터를 추출했다!  C가 커질 수록 빨강, 파랑이 균형있는 모습을 보여주는 거같다.

 

 GridSearchCV를 사용하면 최적의 파라미터를 찾아준다고 한다. 역시 부탁해본다.

 

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.svm import SVC

# Load the Iris dataset
iris = load_iris()

# Split the dataset into training and test sets
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0)

# Define the parameter grid
param_grid = {'C': [0.1, 1, 10, 100],
              'gamma': [0.1, 1, 10, 100]}

# Create an SVM object with the RBF kernel
svm = SVC(kernel='rbf')

# Create a GridSearchCV object
grid_search = GridSearchCV(svm, param_grid, cv=5)

# Fit the GridSearchCV object to the training data
grid_search.fit(X_train[:, :2], y_train)

# Print the best hyperparameters
print('Best hyperparameters: {}'.format(grid_search.best_params_))
print('Best cross-validation score: {:.2f}'.format(grid_search.best_score_))

# Plot the decision boundary with the best hyperparameters
h = 0.02  # step size in the mesh
x_min, x_max = X_train[:, 0].min() - 1, X_train[:, 0].max() + 1
y_min, y_max = X_train[:, 1].min() - 1, X_train[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
svm_best = SVC(kernel='rbf', **grid_search.best_params_)
svm_best.fit(X_train[:, :2], y_train)
Z = svm_best.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.coolwarm, alpha=0.8)
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap=plt.cm.coolwarm)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.xticks(())
plt.yticks(())
plt.title('SVC with RBF kernel, C = {}, gamma = {}'.format(grid_search.best_params_['C'], grid_search.best_params_['gamma']))
plt.show()

 

가장 교차검증 점수가 높은 하이퍼 파라미터를 알려주었다. AI를 개발하는 AI라니... 

 

 

 

규칙 기반 방법

- 분류하는 규칙을 사람이 구현한다.

- ex) a보다 크면 X이고, 작으면 Y이다.

- 큰 데이터셋에서는 불가능하고, 데이터가 바뀌면 처음부터 새로 작업해야하는 비효율성을 가진다.

 

기계 학습 방법

- 특징 벡터를 추출하고 레이블을 붙이는 과정은 규칙 기반과 동일(수작업 특징 hand-crafted feature)

- 규칙 만드는 일은 기계학습 모델을 이용하여 자동으로 수행한다.

 

딥러닝 방법

- 레이블을 붙이는 과정은 기계학습과 동일

- 특징 벡터를 학습이 자동으로 알아낸다. 특징 학습(feature learning) 또는 표현학습(representation learning)을 한다고 말한다.

장점

- 특징 추출과 분류를 동시에 최적화하므로 뛰어난 성능을 보장할 수 있다.

- 인공지능 제품 제작이 빠르다.

 

 

 

 

 

 

 

 

Reference

sklearn.svm.SVC — scikit-learn 1.2.2 documentation

 

sklearn.svm.SVC

Examples using sklearn.svm.SVC: Release Highlights for scikit-learn 0.24 Release Highlights for scikit-learn 0.24 Release Highlights for scikit-learn 0.22 Release Highlights for scikit-learn 0.22 C...

scikit-learn.org

https://bkshin.tistory.com/entry/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-3%EC%84%9C%ED%8F%AC%ED%8A%B8-%EB%B2%A1%ED%84%B0-%EB%A8%B8%EC%8B%A0-SVM-%EC%8B%A4%EC%8A%B5

 

머신러닝 - 3. 서포트 벡터 머신 (SVM) 실습

sklearn을 활용하여 서포트 벡터 머신(SVM) 실습을 해보겠습니다. 코드 및 데이터는 제 깃헙에 모두 있습니다. 본 포스트의 내용은 OpenCV의 글을 정리한 것입니다. (Reference1) Linearly Separable Data without N

bkshin.tistory.com

https://kr.mathworks.com/discovery/support-vector-machine.html

 

Support Vector Machine(SVM)

분류 및 회귀에 support vector machine을 적용하는 방법을 알아봅니다. 다중클래스 SVM 및 Simulink와의 통합을 다루는 설명과 문서 등의 자료가 준비되어 있습니다.

kr.mathworks.com