728x90
반응형




👉이전글에서 봤던 것처럼 RNN이라는 딥러닝 모델은 자연어 문장과 같은 시퀀스 데이터를 입력으로 받아 학습시킬 수 있도록 설계된 모델입니다. 이를 통해 자연어처리 분야에 딥러닝 모델이 활용될 수 있었습니다.


이러한 RNN 모델을 활용하여 자연어 기반의 분류 모델을 구현하고자 하는데,
구현에 앞서 딥러닝이 무엇인지 짚어보겠습니다.


딥러닝 개요




딥러닝 모델은 위 그림과 같이 표현될 수 있습니다.
위 구조를 이루고 있는 파란색 원을 퍼셉트론이라고 하는데,
입력층에서 입력으로 들어온 데이터가 다수의 퍼셉트론을 거쳐 사전 학습된대로 출력층에서 데이터를 출력하게 됩니다.


딥러닝이란?

딥러닝은 위 그림의 구조와 같은 심층신경망에 학습시키는 것을 가리키는 말입니다.



  • 심층신경망 : 위 그림과 같이 다수의 퍼셉트론으로 이루어진 은닉층이 2개 이상인 신경망


딥러닝의 등장

위 그림과 같이 단층퍼셉트론을 활용해도 AND 게이트 연산을 위한 직선의 선형함수를 찾으면 AND 게이트 구현이 가능했습니다.


하지만 위 그림의 XOR 게이트는 직선의 선형함수로는 구현이 불가능한 게이트이고,
XOR 연산을 위해 다수의 은닉층으로 구성된 심층신경망이 등장하게 됩니다. 그리고 이러한 심층신경망을 학습시키는 일련의 과정인 딥러닝이 대두됩니다.


심층신경망의 학습 (딥러닝)



학습과정

👉이전글에서 봤던 것처럼 머신러닝의 학습과정은 각 뉴런의 가중치 W를 찾아가는 과정입니다.
이러한 학습과정은 딥러닝에도 동일하게 적용됩니다. (퍼셉트론의 가중치 W를 찾아가는 과정)


  1. 학습데이터 입력 : 학습데이터가 입력되면 심층신경망을 이루는 각 퍼셉트론을 단계별로 거치게되고, 거칠 때마다 초기화된 가중치 W와 바이어스b를 기반으로 출력값이 계산되어 다음 층 퍼셉트론의 입력값으로 전달됩니다.
  2. 예측값과 실제값 비교 : 심층신경망을 통해 출력된 예측값과 실제값의 차이를 기반으로 하는 Loss Function을 통해 차이를 최소화하는 가중치W와 바이어스b를 찾게됩니다. 어떤 모델이냐에 따라 최적의 Loss Function이 달라집니다. (회귀모델은 MSE(평균제곱오차)가 최적이라고 함) (👉Cost Function 글 참고)
  3. Back Propagation : 출력층부터 은닉층을 역방향으로 진행하면서 실제값-예측값 오차 기반의 미분 값을 활용하여 가중치W와 바이어스b를 업데이트 합니다. 해당 과정이 반복되면서 Loss가 최소가 되는 지점을 찾게되면, 최적의 가중치W/바이어스b 값을 찾을 수 있습니다.
  4. Optimizer : 어떤 Optimizer를 사용하느냐에 따라 결정되는 Loss의 최솟값이 달라집니다. Optimizer의 성능이 좋을수록 정확한 최솟값을 찾을 수 있습니다. 아래 그림을 예시로 잘못된 Optimizer를 선정했을 경우, 로컬 미니멈을 최솟값으로 선정하게될 것입니다. Optimizer의 예로 기본적인 경사하강법(Gradient Descent)과 좀 더 응용된 Adam이 있습니다.



  • 수치기반 실제 학습과정 예시 (순전파->역전파)
    : 수치를 통해 실제 학습되는 과정에 대한 예시는 아래 링크를 참고하면 됩니다.
    https://wikidocs.net/37406


에포크/배치크기/이터레이션

아래 개념은 실제 모델에 학습을 시킬 때 모델의 성능을 좌우할 수 있는 파라미터입니다.

  1. 에포크 : 전체 학습데이터에 대해 순전파와 역전파 과정이 진행되는 단위입니다. 예를들어 50에포크는 전체데이터를 50번 학습한다는 의미입니다. 에포크가 너무 크거나 작으면 과적합이나 과소적합 현상이 발생할 수 있습니다.
  2. 배치크기 : 전체 데이터에서 몇 개 데이터 단위로 학습시킬지 결정하는 단위입니다.
  3. 이터레이션(step) : 전체 데이터를 모두 학습시키기 위해 배치크기 단위로 몇 번 학습 loop를 돌려야하는지 결정하는 단위입니다.


활성화 함수 (Activation Function)

  • 활성화함수란? 심층신경망 은닉층/출력층의 출력값을 결정하는 함수입니다. 이러한 매커니즘은 실제 뇌를 구성하는 신경 세포 뉴런이 전위가 일정치 이상이 되면 시냅스가 서로 화학적으로 연결되는 모습을 모방한 것입니다.


  • 사용이유 : 퍼셉트론의 출력 값은 보통 wx + b 함수의 형태로 선형함수의 출력 값으로 이루어짐 -> 인공신경망의 능력을 높이기 위해 은닉층을 계속 추가해줌 -> 활성화 함수 없이 선형함수의 출력 값이 중첩되기만 한다면 1개층의 은닉층을 사용하는 것이 여러층의 은닉층을 사용하는 것과 크게 차이가 없음 (ex. 0.20.20.2x 출력 값의 3개 은닉층은 0.004x 출력 값의 1개 은닉층과 차이가 없음) -> 비선형함수의 활성화 함수를 각 퍼셉트론의 연산에 활용하여 은닉층을 여러개 쌓았을 때 능력을 극대화시킬 수 있음 (각 퍼셉트론의 특성을 잘 살릴 수 있음)


활성화 함수 종류

  1. 시그모이드 함수 (Sigmoid function)

# 시그모이드 함수 그래프를 그리는 코드
def sigmoid(x):
    return 1/(1+np.exp(-x))
x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)

plt.plot(x, y)
plt.plot([0,0],[1.0,0.0], ':') # 가운데 점선 추가
plt.title('Sigmoid Function')
plt.show()

위 그림의 그래프는 시그모이드 함수의 그래프입니다.
양수 값이 클수록 1의 가까운 값을, 음수 값이 클수록 0에 가까운 값을 출력하게 됩니다.


  • Vanishing Gradient (기울기 소실)

인공신경망을 Back Propagation(역전파)을 통해 학습시킬 때, Vanishing Gradient (기울기 소실) 문제가 발생할 수 있습니다.
학습시키는 과정에서 시그모이드 활성화 함수를 미분하게 되는데, 미분 최댓값은 0.25로 작은 값이고,
역전파가 진행되면서 미분 최댓값(0.25) 이하의 값이 중첩되어 곱해지면 0으로 수렴하게 되어
기울기가 앞단으로 잘 전달되지 않게 됩니다.


기울기 소실 문제를 방지하기 위해 가중치 초기화나 배치 정규화, 층 정규화 등의 기법이 활용될 수 있습니다.


그래서 시그모이드 함수는 은닉층에서의 사용은 지양되고, 이진 분류를 위해 출력층에서 활용하게 됩니다.


  1. 하이퍼볼릭탄젠트 함수 (Hyperbolic tangent function)

x = np.arange(-5.0, 5.0, 0.1) # -5.0부터 5.0까지 0.1 간격 생성
y = np.tanh(x)

plt.plot(x, y)
plt.plot([0,0],[1.0,-1.0], ':')
plt.axhline(y=0, color='orange', linestyle='--')
plt.title('Tanh Function')
plt.show()

하이퍼볼릭탄젠트 함수는 미분했을 때의 최댓값이 1로
은닉층에서 시그모이드 함수보다는 선호되는 함수입니다.


  1. 렐루 함수 (ReLU)

def relu(x):
    return np.maximum(0, x)

x = np.arange(-5.0, 5.0, 0.1)
y = relu(x)

plt.plot(x, y)
plt.plot([0,0],[5.0,0.0], ':')
plt.title('Relu Function')
plt.show()

렐루 함수는 음수는 0을 출력하고, 양수는 입력값 그대로 반환하는 함수입니다.
그리고 양수일 때의 기울기는 항상 1이라서 깊은 신경망의 은닉층에서 시그모이드 함수보다 훨씬 더 잘 작동합니다.
또한, 단순 임계값을 반환하는 연산이라서, 연산 속도도 빠릅니다.


그러나 음수일 때 기울기는 항상 0입니다. 그래서 기울기가 0인 경우는 퍼셉트론이 죽게되어 다시 회생하는 것이 매우 어렵게 되는 죽은 렐루(dying ReLU) 현상이 발생할 수 있습니다.


  1. 리키 렐루 (Leaky ReLU)

a = 0.1

def leaky_relu(x):
    return np.maximum(a*x, x)

x = np.arange(-5.0, 5.0, 0.1)
y = leaky_relu(x)

plt.plot(x, y)
plt.plot([0,0],[5.0,0.0], ':')
plt.title('Leaky ReLU Function')
plt.show()

리키 렐루 함수는 죽은 렐루 현상을 보완하기 위해 등장한 함수 중 하나입니다.
입력 값이 음수일 경우에 0이 아니라 매우 작은수를 반환하도록 하여 0이 아닌 아주 작은 값의 기울기를 갖게됩니다.
이를 통해 ReLU는 죽지 않습니다.


Reference

반응형

'개발 > AI' 카테고리의 다른 글

[LLM] LLM 발전기  (2) 2025.01.05
[AI] pandas/sklearn을 활용한 머신러닝 모델링  (0) 2024.04.12
[AI] pandas를 활용한 데이터 핸들링 및 전처리  (2) 2024.04.10
KT AI 해커톤 회고 (2)  (2) 2023.11.02
KT AI 해커톤 회고 (1)  (2) 2023.10.27
728x90
반응형




Open LLM Model을 활용하여 Fine Tuning한 모델을 가지고 실제 비즈니스에 적용한 서비스를 만들기 위해
LLM을 테마로 하여 LLM 모델에 대한 개요와 원리 등을 공부하여 블로그로 연재하겠습니다.


먼저 본 글에서는 현재까지의 LLM 발전기에 대해 다뤄보겠습니다.


딥러닝 기반 언어모델의 등장

LLM(Large Language Model)이란? 인간이 활용하는 수많은 자연어를 학습한 딥러닝 기반의 언어모델입니다.



LLM은 딥러닝 기술을 통해 더욱 효율적이고 개선된 성능으로 자연어 처리 및 생성을 수행하기 때문에 위 사진과 같은 벤다이어그램으로 표현할 수 있습니다.


딥러닝의 자연어 처리 분야 적용

RNN(Recurrent Neural Network)이란? 순환신경망, 자연어 문장과 같은 시퀀스한 입력데이터를 받는 모델입니다. 입력으로 주어지는 시퀀스한 데이터의 순서가 달라질 경우, 모델이 의미를 다르게 해석하여 출력도 달라질 수 있습니다.



RNN의 개념부터 다른 이유는 RNN이 자연어 문장과 같은 시퀀스 데이터를 처리하기 위해 처음 등장한 모델이기 때문입니다. (1986년 등장)


위 그림에서 볼 수 있는 것처럼 RNN모델은 토큰(단어) 단위 현재 시점의 입력 정보와 과거 시점의 출력 정보 두 개의 정보를 입력하여 연속적으로 학습시킬 수 있습니다. 하지만 입력 정보의 길이가 길어짐에 따라 학습도 길어지게 되면 오래된 정보일수록 의미가 희미해지는 현상이 발견됩니다. (Vanishing Gradient) 그래서 1997년 아래와 같은 아키텍처의 모델이 등장하게 됩니다.


  • LSTM (Long Short Term Memory)




입력 정보가 길어질수록 과거 정보의 의미가 희미해지는 현상을 보완하기 위해 LSTM 아키텍처가 등장하게 됩니다.
위 그림에서 볼 수 있는 것처럼 LSTM 아키텍처는 각 노드마다 과거 시점의 입력 정보를 추가로 받고,
게이트 단에서 세 개의 입력정보 (과거 시점 입력정보/과거 시점 출력정보/현재 시점 입력정보)를 입력받아서 데이터 활용여부와 방법을 결정하게 됩니다.
자세한 내용은 추후 작성될 RNN글에서 다뤄보겠습니다.


그럼에도 불구하고 과거 시점의 의미가 희미해지는 현상이 완전히 해소되지 않아서 숙제로 남게됩니다.


딥러닝의 대두

2012년 이미지 인식 대회인 ImageNet에서 딥러닝 기술을 활용한 AlexNet 모델이 우승하였습니다.
당시에 AlexNet 모델은 기존 방식을 활용한 이미지 인식 모델의 오류율을 크게 개선하였는데요.
뿐만 아니라 해당 모델을 특정 문제를 해결하는데 뿐만 아니라 다른 문제를 해결하는 데에도 범용적으로 활용할 수 있어서
해당 사건을 계기로 딥러닝 기술에 대한 사람들의 관심이 다시 높아졌습니다.


AlexNet 모델은 대표적은 CNN(Convolutional Neural Network) 모델입니다. 다음에 기회가 된다면 상세히 살펴보겠습니다.


Word2Vec 기술 등장

2013년, 구글의 연구원들은 Word2Vec 이라는 기술을 개발하게 됩니다.
Word2Vec 기술은 단어를 실수벡터 형태로 변환하는 기술입니다. 그리고 실수벡터 형태로 변환하는 과정을 Embedding이라고 합니다.




  • 등장 배경

컴퓨터가 이해할 수 있도록 자연어를 숫자로 변환하는 방식인 One-Hot 인코딩은 표현하고자 하는 단어의 인덱스를 1로, 나머지 단어의 인덱스는 0으로 세팅하는 방식입니다. 하지만 해당 방식은 단어 간의 유사성을 확인할 수 없다는 단점이 있었습니다.
이러한 단점을 보완하기 위해 Word2Vec 기술이 등장하게 됩니다.


  • 유사성을 벡터화하는 방법

단어간의 유사성 정보를 어떻게 벡터에 담을 수 있을까요?
Word2Vec을 관통하는 핵심 개념은 "비슷한 문맥에서 등장하는 단어들은 비슷한 의미를 가진다." 입니다.
강아지라는 단어는 귀엽다, 예쁘다 등의 단어가 주로 함께 등장하는 것처럼요.


위 개념을 기반으로 하는 분포 가설이라는 것을 정의하고,
정의한 분포 가설을 활용하여 학습한 모델에 자연어를 입력하면,
해당 자연어는 유사성 정보가 담긴 벡터로 변환됩니다.


자세한 내용은 👉Embedding글에서 참고 바랍니다.


Transformer 모델의 등장

2017년, 자연어 처리 분야의 딥러닝 연구가 지속되고 있는 중에 구글의 연구진은 "Attention is All you need"라는 논문을 통해 Transforemer 모델 아키텍처를 공개하게 됩니다. 해당 모델은 학습 텍스트가 길어질수록 과거의 정보가 희미해지는 RNN의 고질적인 문제를 획기적으로 해결하였습니다.
RNN의 순차 처리방식을 버리고 맥락을 모두 참조하는 Attention 연산을 이용한 것입니다.


그리고 현재까지 해당 트랜스포머 모델을 기반으로 구글, 메타, OpenAI 등 주요 테크기업을 중심으로 여러 LLM 모델이 개발되거나 개발중이고,
OpenAI의 ChatGPT 서비스가 일반 사용자에게 공개됨에 따라 AI에 대한 대중의 관심이 크게 증가하여
다양한 분야에 LLM을 접목하는 시도가 많이 나타나고 있습니다.


트랜스포머 모델의 자세한 내용은 다음 글에서 다뤄보겠습니다.


Reference

반응형
728x90
반응형

본 글에서는 👉이전글에서 전처리된 데이터를 기반으로 선형회귀, 로지스틱 회귀, 의사결정나무 모델에 학습시키고 성능을 평가해볼 것입니다.

데이터 준비

  • 샘플데이터 : boston.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd

df = pd.read_csv("./data/boston.csv")
  1. 데이터 분리
    : 모델의 Overfitting(과적합)을 방지하기 위해 학습용, 평가용, 검증용(Option) 데이터를 나누는 과정입니다.
    Overfitting(과적합) : 학습용(train) 데이터에 과도하게 적합해져서 새로운 데이터에 대한 예측력이 떨어지는 현상
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['MEDV'])
y = df['MEDV']

# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split

# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=42)



지도학습 회귀 - 선형회귀

  • 샘플데이터 : boston.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd

df = pd.read_csv("./data/boston.csv")
  1. 데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['MEDV'])
y = df['MEDV']

# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split

# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=42)
  1. 단순선형회귀 (Linear Regression)
    : 1개의 feature를 기반으로 수치를 예측하는 모델, 👉Linear Regression글 참고
# 라이브러리 호출
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

# 모델 선언
model = LinearRegression()

# 학습하기
model.fit(x_train[['RM']], y_train)

# 예측하기
y_pred = model.predict(x_test)

# 평가하기
print("MSE : ", mean_squared_error(y_test, y_pred))
# MSE(Mean Squared Error) : 평균제곱오차, 예측값과 실제값과의 차이를 제곱한 것의 평균
# 모델의 성능과 MSE는 반비례

# 선형회귀 분석 결과 시각화
# 회귀계수 확인
w = model.coef_
b = model.intercept_
print("기울기 : ", w)    # 기울기
print("절편 : ", b)     # 절편

# 선형회귀식
x = x_test[['RM']]
y = w * x + b

# 시각화
import matplotlib.pyplot as plt
plt.scatter(x_test[['RM']], y_test)
plt.plot(x, y, color='r')
plt.xlabel('RM')
plt.ylabel('MEDV')

plt.show()

# 예측값 실제값 비교
# 실제값과 예측값을 비교하기 위해 데이터프레임으로 만들기
df_lr = pd.DataFrame()
df_lr['y_test'] = y_test
df_lr['y_pred'] = y_pred
df_lr.reset_index(drop=True, inplace=True)

# 시각화
plt.plot(df_lr['y_test'], label='Actual')
plt.plot(df_lr['y_pred'], label='Predicted')
plt.legend()
plt.show()
  • MSE (Mean Squared Error)
  1. 다중선형회귀 (Linear Regression)
    : 다수의 feature를 기반으로 수치를 예측하는 모델, 👉Linear Regression글 참고
# 라이브러리 호출
from sklearn.linear_model import LinearRegression

# 모델 선언
model2 = LinearRegression()

# 학습하기
model2.fit(x_train, y_train)

# 예측하기
y_pred = model2.predict(x_test)

# 평가하기
print("MSE : ", mean_squared_error(y_test, y_pred))

# 선형회귀 분석 결과 시각화
# 회귀계수 확인
w = model.coef_
b = model.intercept_
print("기울기 : ", w)    # 기울기
print("절편 : ", b)     # 절편

# 선형회귀식
formula = "MEDV = {:.2f}".format(b)
for i, feature_name in enumerate(x_test.columns):
    formula += " + {:.2f} * {}".format(w[i], feature_name)
print("선형회귀식: " + formula)

# 시각화
import matplotlib.pyplot as plt
plt.plot(y_test.values[:50], label='Actual')
plt.plot(y_pred[:50], label='Predicted')
plt.legend()
plt.show()



지도학습 분류

  • 샘플데이터 : wine.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd

df = pd.read_csv("./data/wine.csv")
  1. 데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['class'])
y = df['class']

# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split

# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
  1. 로지스틱 회귀 (Logistic Regression)
    : 다수의 feature를 기반으로 이진분류하는 모델, 👉Logistic Regression글 참고
# 라이브러리 호출
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

# 모델 선언
model = LogisticRegression()

# 이진분류를 위한 테스트데이터 세팅
x_train_b = x_train.loc[y_train[y_train !='class_2'].index]
y_train_b = y_train[y_train !='class_2']
x_test_b = x_test.loc[y_test[y_test !='class_2'].index]
y_test_b = y_test[y_test !='class_2']

# 학습하기
model.fit(x_train_b, y_train_b)

# 예측하기
y_pred = model.predict(x_test_b)

# 평가하기
print("accuracy : ", accuracy_score(y_test_b, y_pred))
# accuracy_score : 정확도를 계산하기 위한 sklearn패키지 함수 (예측결과가 동일한 데이터 건수 / 전체 예측 데이터 건수)

# 예측값 실제값 비교
# 실제값과 예측값을 비교하기 위해 데이터프레임으로 만들기
df_result = pd.DataFrame()
df_result['y_test_b'] = y_test_b
df_result['y_pred'] = y_pred
df_result.reset_index(drop=True, inplace=True)
  1. 소프트맥스 회귀 (Softmax Regression)
    : 다수의 feature를 기반으로 다중분류하는 모델, 👉Softmax Regression글 참고
# 라이브러리 호출
from sklearn.linear_model import LogisticRegression

# 모델 선언
model_softmax = LogisticRegression(multi_class='multinomial')

# 학습하기
model_softmax.fit(x_train, y_train)

# 예측하기
y_pred = model_softmax.predict(x_test)

# 평가하기
print("accuracy : ", accuracy_score(y_test, y_pred))

# 예측값 실제값 비교
# 실제값과 예측값을 비교하기 위해 데이터프레임으로 만들기
df_result = pd.DataFrame()
df_result['y_test'] = y_test
df_result['y_pred'] = y_pred
df_result.reset_index(drop=True, inplace=True)



지도학습 - 의사결정나무

: 의사결정나무 모델은 아래 그림처럼 여러 target으로 분기하는 과정에서 여러 기준에 의거하여 데이터를 분류하거나 결과값을 예측하는 모델
학습을 통해 기준 수치를 조정하여 모델을 일반화하게 되고, 회귀/분류 모델로서 활용 가능합니다.
아래 그림은 outlook, humidity, windy 기준으로 경기가 열릴지 안열리지를 판단하는 모델을 도식화한 그림입니다.

  • 샘플데이터 : wine.csv, boston.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd

df = pd.read_csv("./data/wine.csv"
  1. 데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['class'])
y = df['class']

# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split

# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
  1. 의사결정나무 - 분류
# 라이브러리 호출
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

# 모델 선언
model = DecisionTreeClassifier()

# 학습하기
model.fit(x_train, y_train)

# 예측하기
y_pred = model.predict(x_test)

# 평가하기
print("accuracy : ", accuracy_score(y_test, y_pred))

# 의사결정나무(Decision Tree) 구조 보기
# 시각화 모듈 불러오기
from sklearn.tree import export_graphviz

# 이미지 파일 만들기
export_graphviz(model,                        # 모델이름
                out_file='tree_wine.dot',
                feature_names=x.columns,      # Feature 이름
                class_names=y.unique(),       # Target Class 이름
                rounded=True, 
                precision = 3, 
                filled = True)
!dot -Tpng tree_wine.dot -o tree_wine.png -Gdpi=300

# 이미지 파일 로딩
from IPython.display import Image
Image(filename='tree_wine.png', width=600)        # 사이즈 조정

# 예측값 실제값 비교
# 실제값과 예측값을 비교하기 위해 데이터프레임으로 만들기
df_result = pd.DataFrame()
df_result['y_test'] = y_test
df_result['y_pred'] = y_pred
df_result.reset_index(drop=True, inplace=True)
  1. 의사결정나무 - 회귀
# 데이터 불러오기
df = pd.read_csv("./data/boston.csv")

# 데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['MEDV'])
y = df['MEDV']

# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split

# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)



# 라이브러리 호출
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error

# 모델 선언
model = DecisionTreeRegressor()

# 학습하기
model.fit(x_train, y_train)

# 예측하기
y_pred = model.predict(x_test)

# 평가하기
print("MSE : ", mean_squared_error(y_test, y_pred))

# 의사결정나무(Decision Tree) 구조 보기
# 시각화 모듈 불러오기
from sklearn.tree import export_graphviz

# 이미지 파일 만들기
export_graphviz(model,                        # 모델이름
                max_depth=5,
                out_file='tree_boston.dot',
                feature_names=x.columns,      # Feature 이름
                rounded=True, 
                precision = 3, 
                filled = True)
!dot -Tpng tree_boston.dot -o tree_boston.png -Gdpi=300

# 이미지 파일 로딩
from IPython.display import Image
Image(filename='tree_boston.png', width=600)        # 사이즈 조정

# 예측값 실제값 비교
# 실제값과 예측값을 비교하기 위해 데이터프레임으로 만들기
df_result = pd.DataFrame()
df_result['y_test'] = y_test
df_result['y_pred'] = y_pred
df_result.reset_index(drop=True, inplace=True)

# 시각화
plt.plot(y_test.values[:50], label='Actual')
plt.plot(y_pred[:50], label='Predicted')
plt.legend()
plt.show()



예측과 성능 평가

  • 샘플데이터 : boston.csv, wine.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("./data/boston.csv")
  1. 데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['MEDV'])
y = df['MEDV']

# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split

# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
  1. 회귀모델 성능 평가
# 라이브러리 호출
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

# 모델 선언
model_lr = LinearRegression()
model_dt = DecisionTreeRegressor()

# 모델 학습
model_lr.fit(x_train, y_train)
model_dt.fit(x_train, y_train)

# 예측하기
y_pred_lr = model_lr.predict(x_test)
y_pred_dt = model_dt.predict(x_test)

# 평가하기
print("LinearRegression 모델")
print("MSE : ", mean_squared_error(y_test, y_pred_lr))
print("RMSE :", mean_squared_error(y_test, y_pred_lr)**(1/2))
print("MAE : ", mean_absolute_error(y_test, y_pred_lr))
print("R2 Score : ", r2_score(y_test, y_pred_lr))
print("")
print("DecisionTreeRegressor 모델")
print("MSE : ", mean_squared_error(y_test, y_pred_dt))
print("RMSE :", mean_squared_error(y_test, y_pred_dt)**(1/2))
print("MAE : ", mean_absolute_error(y_test, y_pred_dt))
print("R2 Score : ", r2_score(y_test, y_pred_dt))

# R2_Score (결정계수) = SSR/SST = 1 - SSE/SST, 해당 수치가 클 수록 회귀 모델의 성능이 높음
# SST (Total Sum of Squares) : 실제값에서 실제값의 평균을 뺀 차이의 제곱을 모두 합한 수치
# SSR (Sum of Squares due to Regression) : 예측값에서 실제값의 평균을 뺀 차이의 제곱을 모두 합한 수치
# SSE (Sum of Squares Residual of Error) : 실제값에서 예측값을 뺀 차이의 제곱을 모두 합한 수치
  • SST/SSR/SSE
  1. 분류모델 성능 평가
# 데이터 불러오기
df = pd.read_csv("./data/wine.csv")

# 데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['class'])
y = df['class']

# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split

# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=42)

# 라이브러리 호출
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import confusion_matrix, precision_score, recall_score, accuracy_score, f1_score, classification_report

# 모델 선언
model_lr = LogisticRegression()
model_dt = DecisionTreeClassifier()

# 모델 학습
model_lr.fit(x_train, y_train)
model_dt.fit(x_train, y_train)

# 예측하기
y_pred_lr = model_lr.predict(x_test)
y_pred_dt = model_dt.predict(x_test)

# 평가하기
print("LogisticRegression 모델")
print("Precision : ", precision_score(y_test, y_pred_lr, average='macro'))
print("Recall :", recall_score(y_test, y_pred_lr, average='macro'))
print("Accuracy : ", accuracy_score(y_test, y_pred_lr))
print("F1 Score : ", f1_score(y_test, y_pred_lr, average='macro'))
print("")
print("DecisionTreeClassifier 모델")
print("Precision : ", precision_score(y_test, y_pred_dt, average='macro'))
print("Recall :", recall_score(y_test, y_pred_dt, average='macro'))
print("Accuracy : ", accuracy_score(y_test, y_pred_dt))
print("F1 Score : ", f1_score(y_test, y_pred_dt, average='macro'))

# precision_score : 정밀도, 모델이 1이라고 예측한 것중에 실제로 1인 것의 정도
# accuracy_score : 정확도, 모델이 예측한 값과 실제 값이 일치하는 정도
# recall_score : 재현율, 실제로 1인 것중에 모델이 1이라고 예측한 비율
# f1_score : 정밀도와 회수율을 고르게 활용하기 위한 조화평균, 1에 가까울수록 성능이 좋음
  • Precision/Recall



Cross Validation (교차 검증)

: 데이터를 train set과 test set으로 나누는 방식에서 train set을 train set + validation set으로 추가로 나누어 검증하는 방식
데이터를 train set과 test set으로 나누고, test set을 활용하여 모델의 성능을 검증 및 개선 과정을 반복하면 모델이 test set 과적합(overfitting)될 우려가 있음. 이를 방지하기 위해 교차 검증으로 모델의 성능 검증 및 개선을 진행함.

교차검증

  • 샘플데이터 : boston.csv, wine.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("./data/boston.csv")

# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['MEDV'])
y = df['MEDV']
  1. 회귀모델 교차검증
# 라이브러리 호출
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score

# 모델 선언하기
model_lr = LinearRegression()
model_dt = DecisionTreeRegressor()

# 학습, 예측, 평가하기
lr_cv_score = cross_val_score(model_lr, x, y, cv=10, scoring='neg_mean_squared_error')    
dt_cv_score = cross_val_score(model_dt, x, y, cv=10, scoring='neg_mean_squared_error')    # cv는 위 사진에서 Fold의 갯수를 가리킴

# 결과 확인
# 확인
print("LinearRegression 모델")
print(lr_cv_score)
print("MSE : ", -lr_cv_score.mean())
print("DecisionTreeRegressor 모델")
print(dt_cv_score)
print("MSE : ", -dt_cv_score.mean())
  1. 분류모델 교차검증
# 데이터 불러오기
df = pd.read_csv("./data/wine.csv")

# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['class'])
y = df['class']

# 라이브러리 호출
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score

# 모델 선언하기
model_lr = LogisticRegression()
model_dt = DecisionTreeClassifier()

# 학습, 예측, 평가하기
lr_cv_score = cross_val_score(model_lr, x, y, cv=5, scoring='f1_macro')
dt_cv_score = cross_val_score(model_dt, x, y, cv=5, scoring='f1_macro')

# 결과 확인
# 확인
print("LogisticRegression 모델")
print(lr_cv_score)
print("F1 Score : ", lr_cv_score.mean())
print("DecisionTreeClassifier 모델")
print(dt_cv_score)
print("F1 Score : ", dt_cv_score.mean())
반응형

'개발 > AI' 카테고리의 다른 글

[LLM] 딥러닝 개요와 학습  (0) 2025.03.06
[LLM] LLM 발전기  (2) 2025.01.05
[AI] pandas를 활용한 데이터 핸들링 및 전처리  (2) 2024.04.10
KT AI 해커톤 회고 (2)  (2) 2023.11.02
KT AI 해커톤 회고 (1)  (2) 2023.10.27
728x90
반응형

👉이전글에서 소개된 것처럼 AI 모델은 많은 데이터를 기반으로 생성됩니다.
그렇기때문에 양질의 데이터는 높은 퀄리티의 AI 모델을 생성하기 위해 반드시 필요한 요소죠.

본 글에서는 일반적인 데이터를 AI 모델에 활용할 양질의 데이터로 가공하기 위한 방법들을 다뤄보겠습니다.

사용 환경은 아래와 같습니다.

  • IDE : Jupyter Notebook
  • Language : python
  • library : pandas

데이터 탐색

  • 샘플데이터 : ratings.csv
  1. 데이터 확인
# 라이브러리 불러오기
import pandas as pd

# 샘플데이터 가져오기
df = pd.read_csv("./data/ratings.csv")

# 앞에서부터 데이터확인
df.head() # 앞 10개 (default)
df.head(5) # 앞 5개

# 뒤에서부터 데이터확인
df.tail() # 뒤 10개 (default)
df.tail(5) # 뒤 5개
  1. 데이터프레임 정보 확인
    : 데이터 컬럼정보 확인
df.info()

## 결과
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 100836 entries, 0 to 100835
# Data columns (total 4 columns):
#  #   Column     Non-Null Count   Dtype  
# ---  ------     --------------   -----  
#  0   userId     100836 non-null  int64  
#  1   movieId    100836 non-null  int64  
#  2   rating     100836 non-null  float64
#  3   timestamp  100836 non-null  object 
# dtypes: float64(1), int64(2), object(1)
# memory usage: 3.1+ MB
  1. 통계적 특성 확인
    : 데이터의 row수와 평균, 최소/최대값 등을 확인
df.describe()

#     userId    movieId    rating
# count    100836.000000    100836.000000    100836.000000
# mean    326.127564    19435.295718    3.501557
# std    182.618491    35530.987199    1.042529
# min    1.000000    1.000000    0.500000
# 25%    177.000000    1199.000000    3.000000
# 50%    325.000000    2991.000000    3.500000
# 75%    477.000000    8122.000000    4.000000
# max    610.000000    193609.000000    5.000000



데이터 결합과 정렬

  • 샘플데이터 : movies.csv, links.csv, ratings.csv, users.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd

df_movies = pd.read_csv("./data/movies.csv")
df_links = pd.read_csv("./data/links.csv")
df_ratings = pd.read_csv("./data/ratings.csv")
df_users = pd.read_csv("./data/users.csv")
  1. 데이터 붙이기 : concat()
# 단순 위/아래로 row를 붙임
df_concat_1 = pd.concat([df_movies, df_ratings])

# 옆으로 row를 붙임
df_concat_2 = pd.concat([df_movies, df_ratings], axis=1)

# 합치는 두 데이터프레임에 모두 존재하는 row의 인덱스만 가져옴
df_concat_3 = pd.concat([df_movies, df_ratings], join='inner')
  1. 데이터 병합하기 : merge()
# on='key값'이 없을 경우, default 설정대로 같은 이름을 가진 열이 자동으로 key값으로 지정됨
pd.merge(df_movies, df_ratings)

# movieId 기준 병합
pd.merge(df_movies, df_ratings, on='movieId')

# join 방법 설정
pd.merge(df_movies, df_ratings, how='outer' on='movieId') # outer join
pd.merge(df_movies, df_ratings, how='left' on='movieId') # left outer join
pd.merge(df_movies, df_ratings, how='right' on='movieId') # right outer join
  1. 정렬하기 : sort_values()
# movieId기준 오름차순 정렬
df.sort_values(by='movieId')

# movieId기준 내림차순 정렬
df.sort_values(by='movieId', ascending=False)

# movieId기준 오름차순 정렬 후 바로 적용
df.sort_values(by='movieId', inplace=True)

# 정렬로 인해 뒤섞인 인덱스를 재배열
df.reset_index()
df.reset_index(drop=True, inplace=True) # 기존 인덱스 삭제 후, 재배열된 인덱스 적용



데이터 필터링과 편집

  • 샘플데이터 : preprocessing_03.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd

df = pd.read_csv("./data/preprocessing_03.csv")
  1. 데이터 필터링
# 성별의 구성을 확인합니다. 
df['gender'].value_counts()

# 성별이 남자인지를 확인해 봅니다.
df['gender']=='M'

# 전체 데이터프레임에서 성별이 남자인 사람으로 필터링한 정보를 가져옵니다.
df[df['gender']=='M']

# 전체 데이터프레임에서 'userId'가 5인 고객이 본 영화 목록을 확인합니다.
df[df['userId']==5]
len(df[df['userId']==5])

# 전체 데이터프레임에서 'userId'가 5인 고객이 평점 2점 이하를 준 영화 목록을 확인합니다.
df[(df['userId']==5) & (df['rating']<=2) ]

# 필터링 결과 중 'title'만 출력
df[(df['userId']==5) & (df['rating']<=2)]['title']
  1. 컬럼명 변경
# 기존 컬럼명 확인하기
df.columns

# 새로운 컬럼명 List를 작성하여 대체하기
df.columns = ['movieId', 'imdbId', 'tmdbId', '영화제목', 'genres', 'userId', 'rating',
       'timestamp', 'gender', 'age', 'occupation', 'zipcode']

# 기존 컬럼명 선택하여 변경 ( df.rename(columns={'기존 컬럼명' : '새 컬럼명'}) )
df = df.rename(columns={'zipcode':'우편번호'})
  1. 컬럼 생성
# 컬럼 생성 후 기본값 세팅 ( df['새로운 컬럼명'] = 기본값 )
df['new'] = 0

# df['영화제목']의 정보를 문자열 처리한 후 괄호'(',')'를 제외한 4자리의 숫자만 가져온 후에 새로운 컬럼 'year'에 세팅
df['year'] = df['영화제목'].str[-5:-1]

# 데이터 분리 후 새로운 컬럼 생성
df['genres'].str.split('|')    # 배열 형태
df['genres'].str.split('|', expand=True).head() # 'expand=True' 옵션을 통해 새로운 데이터프레임으로 생성
  1. 컬럼 삭제
# new 컬럼 삭제
df.drop(columns=['new'])
df.drop(columns=['new'], inplace=True) # 변경내용 적용

# 필요한 컬럼만 선택하여 다시 저장
new_columns = ['movieId', 'imdbId', 'tmdbId', '영화제목', 'year', 'genres', 'userId', 'rating', 'timestamp', 'gender', 'age', 'occupation', '우편번호']
df = df[new_columns]



데이터 결측치 처리

  • 샘플데이터 : preprocessing_04.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd

df = pd.read_csv("./data/preprocessing_04.csv")
  1. 결측치 확인
# 결측치 행 확인 ( 결측치가 있을 경우 True를 반환 )
df.isnull()

# 각 열별 결측치 갯수 확인
df.isnull().sum()
  1. 결측치 제거
# 결측치가 있는 행 모두 삭제
df_temp = df.dropna()

# 결측치가 있는 열 모두 삭제
df_temp2 = df.dropna(axis=1)

# 행 전체가 결측치인 행만 모두 삭제
df_temp3 = df.dropna(how ='all')

# 행의 결측치가 n초과인 행만 모두 삭제
df_temp4 = df.dropna(thresh=n)

# 특정 열 중 결측치가 있는 경우의 행만 모두 삭제
df_temp5 = df.dropna(subset=['MovieId'])
df.dropna(subset=['MovieId'], inplace=True) # 데이터프레임에 바로 적용
  1. 결측치 채우기
# 결측치를 단일 값(0)으로 대체
df.fillna(0)

# 특정 열의 결측치만 0으로 대체하기
df_na_sample2['UserId'].fillna(0, inplace=True) # 데이터프레임에 바로 적용

# 특정 열의 결측치만 평균값으로 대체하기
df['Age'].fillna(df_na_sample2['Age'].mean(), inplace=True)

# 특정 열의 결측치만 최빈값으로 대체하기
df['Gender'].fillna(df_na_sample2['Gender'].mode()[0], inplace=True)

# 결측치 이전값으로 채우기
df.fillna(method='ffill')

# 결측치 이후값으로 채우기
df.fillna(method='bfill')



데이터 타입 변환/중복데이터 제거

  • 샘플데이터 : preprocessing_05.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd

df = pd.read_csv("./data/preprocessing_05.csv")
  1. 데이터 타입 확인
# 모든 컬럼의 데이터타입을 확인
df.dtypes

# 컬럼별 데이터타입 확인
df['MovieId'].dtype
  1. 데이터 타입 변경
# 모든 Columns의 데이터 타입을 'object' 형으로 변경
df_temp = df.astype('object')

# 특정 컬럼의 데이터 타입을 변경
df = df.astype({'Year':'int'})
  1. 중복데이터 처리
# 중복 데이터 확인 ( 첫 번째 값은 False, 두 번째 값부터는 True 반환 )
df.duplicated()

# 데이터프레임 df의 'Title'과 'UserId' 컬럼이 중복이 되는 데이터를 확인
df[df.duplicated(['Title','UserId'])]

# 예제 : 영화 제목이 같은 영화를 두번 본 고객이 존재한다고?!
df[(df['Title']=='Iron Man') & (df['UserId']==550)]
df[df.duplicated(['Title','UserId'])]

# 중복데이터 제거
df.drop_duplicates(['Title','UserId', 'Year'], ignore_index=True)    # 기존 인덱스를 무시하고 새로 인덱스를 부여



데이터 이상치 처리

  • 샘플데이터 : preprocessing_06.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd

df = pd.read_csv("./data/preprocessing_06.csv")
  1. 이상치 탐지
# 컬럼별 통계적 특성 확인
df.describe()

# 시각화를 통한 이상치 탐지
# 라이브러리 불러오기 
import matplotlib.pyplot as plt

# 차트 영역 설정하기 ( box plot 차트 )
plt.figure()
plt.boxplot(df['Age'], labels=['Age'])
plt.show()

  1. 이상치 확인
# IQR의 1.5배 이상 크거나 작은 데이터를 이상치로 판별
# IQR 계산
# 중앙값 계산
Q2 = df['Age'].median()

# 하위 25%, 상위 25% 범위 계산
Q1 = df['Age'].quantile(0.25)
Q3 = df['Age'].quantile(0.75)
IQR = Q3 - Q1

# 이상치 판별
df['IsOutlier_Age'] = (df['Age'] < Q1 - 1.5 * IQR) | (df['Age'] > Q3 + 1.5 * IQR)
  1. 이상치 처리
# 위에서 생성한 이상치여부 컬럼(IsOutlier_Age) 활용하여 이상치 삭제
df = df[df['IsOutlier_Age'] == False]

# 이상치 대체
df.loc[df['IsOutlier_Age'], 'Age'] = df['Age'].median() # 중앙값 대체



데이터 인코딩

  • 샘플데이터 : preprocessing_07.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd

df = pd.read_csv("./data/preprocessing_07.csv")
  1. 레이블 인코딩
    : 범주형 데이터를 숫자로 변환하는 방법으로, 각 범주에 고유한 숫자를 할당하는 방식입니다.
    예를 들어, "남성", "여성"과 같은 범주형 데이터를 각각 0과 1로 변환하는 방법이 있습니다.
# 라이브러리 불러오기
from sklearn.preprocessing import LabelEncoder

# Label Encoder 호출하기
le = LabelEncoder()

# 'Occupation' 컬럼의 데이터를 Label 인코딩하기.
le_occupation = le.fit_transform(df['Occupation'])
df_le['Occupation_Le'] = le_occupation
df_le['Occupation_Le']
# array([ 0, 20,  1, ..., 11, 11,  7])

# label Encoding 매핑 클래스 확인
le.classes_
# array(['K-12 student', 'academic/educator', 'artist', 'clerical/admin',
#        'college/grad student', 'customer service', 'doctor/health care',
#        'executive/managerial', 'farmer', 'homemaker', 'lawyer', 'other',
#        'programmer', 'retired', 'sales/marketing', 'scientist',
#        'self-employed', 'technician/engineer', 'tradesman/craftsman',
#        'unemployed', 'writer'], dtype=object)

# Pandas의 map() 함수를 사용하여 레이블 인코딩
# 'Occupation' 컬럼의 값들을 lable mapping
label_mapping = { "other" : 0 , 
                  "academic/educator" : 1, 
                  "artist" : 2, 
                  "clerical/admin" : 3, 
                  "college/grad student" : 4, 
                  "customer service" : 5, 
                  "doctor/health care" : 6, 
                  "executive/managerial" : 7, 
                  "farmer" : 8, 
                  "homemaker" : 9, 
                  "K-12 student" : 10,
                  "lawyer" : 11, 
                  "programmer" : 12, 
                  "retired" : 13, 
                  "sales/marketing" : 14, 
                  "scientist" : 15, 
                  "self-employed" : 16, 
                  "technician/engineer" : 17, 
                  "tradesman/craftsman" : 18, 
                  "unemployed" : 19, 
                  "writer" : 20 }

# pandas replace() 메소드를 사용해서 값을 대체
df_le['Occupation_Map'] = df['Occupation'].map(label_mapping)
  1. 더미 변수 생성
    : 각 카테고리를 이진 형태로 표현하는 방법
    각각의 값을 고유한 이진 벡터로 변환하여 해당하는 값의 위치에 1을 표시하고, 나머지 위치에는 0을 표시합니다. (원-핫 인코딩)
# | 구분자 기준으로 데이터를 분할하여 생성된 list type 데이터를 다시 저장
df['Genres'] = df['Genres'].str.split('|')

# list type으로 저장된 데이터를 모두 나누어 새로운 row로 생성
df = df.explode('Genres')

# get_dummies() 함수를 사용 더미변수 생성
pd.get_dummies(df, columns=['Genres'])
pd.get_dummies(df['Genres'])
pd.get_dummies(df['Genres'], prefix='Genre_')    # 더미변수 컬럼의 prefix 설정
pd.get_dummies(df['Genres'], drop_first=True)    # 더미변수 첫번째 컬럼 삭제
df = pd.get_dummies(df, columns=['Genres'], prefix='Genre', drop_first=True)    # 최종

# 더미변수 컬럼 외의 컬럼들을 키값으로 그룹화하여 중복데이터 제거
# 'groupby()'는 특정 컬럼의 값을 기준으로 데이터프레임을 그룹화하여 그룹별로 연산을 수행할 수 있습니다.
# 'agg()'는 그룹화된 데이터프레임에 대해 다양한 집계 함수들을 적용하여 그룹 별로 연산 결과를 집계한 결과를 반환합니다.
df = df.groupby(['MovieId', 'ImdbId', 'TmdbId', 'Title', 'Year', 'UserId', 'Rating', 'Gender', 'Age', 'Occupation']).agg('sum').reset_index()



데이터 스케일링

  • 샘플데이터 : preprocessing_08.csv
  1. 데이터 불러오기
# 라이브러리 불러오기
import pandas as pd

df = pd.read_csv("./data/preprocessing_08.csv")
  1. 데이터 정규화
    : 데이터를 일정 범위로 변환하는 스케일링 방법으로, 데이터를 0과 1 사이의 값으로 변환하는 것을 의미
    정규화는 다양한 스케일을 가진 변수들을 동일한 범위로 맞춰줌으로써, 변수 간의 크기 차이를 제거하여 모델이 각 변수를 공평하게 처리할 수 있도록 돕습니다.
# 라이브러리 불러오기
from sklearn.preprocessing import MinMaxScaler

# MinMaxScaler 호출하기
min_max_scaler = MinMaxScaler()

# 'Age', 'Rating' 컬럼의 데이터를 Min Max Scaling 하기
df_normalized = min_max_scaler.fit_transform(df[['Age', 'Rating']])
  1. 데이터 표준화
    : 데이터를 평균이 0이고 표준편차가 1인 분포로 변환하는 스케일링 방법으로, 데이터를 표준정규분포에 따르는 값으로 변환하는 것을 의미
    표준화는 데이터의 분포를 중심으로 조절하여 이상치에 덜 민감하게 만들어줌으로써, 모델의 안정성을 높이고 예측 결과를 개선하는 데 도움을 줍니다.
# 라이브러리 불러오기
from sklearn.preprocessing import StandardScaler

# StandardScaler 호출하기
standard_scaler = StandardScaler()

# 'Age', 'Rating' 컬럼의 데이터를 StandardScaling 하기
df_standardized = standard_scaler.fit_transform(df[['Age', 'Rating']])



이어서

다음은 전처리된 데이터를 이용하여 AI 모델링을 진행하는 과정을 살펴보겠습니다.

반응형

'개발 > AI' 카테고리의 다른 글

[LLM] LLM 발전기  (2) 2025.01.05
[AI] pandas/sklearn을 활용한 머신러닝 모델링  (0) 2024.04.12
KT AI 해커톤 회고 (2)  (2) 2023.11.02
KT AI 해커톤 회고 (1)  (2) 2023.10.27
[AI] Softmax Regression  (0) 2023.10.01

+ Recent posts