본문 바로가기
● Social Talks/Issues

AICE Associate 시험 대비 기술 스킬 정리

by DATA Canvas 2025. 11. 20.
반응형


1. 탐색적 데이터 분석 (EDA)

라이브러리 임포트

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

데이터 로딩 및 기본 정보 확인

# CSV 파일 읽기
df = pd.read_csv('파일명.csv')

# 기본 정보 확인
df.head()          # 상위 5개 행
df.tail()          # 하위 5개 행
df.info()          # 데이터 타입, 결측치 개수
df.describe()      # 기술 통계량 (평균, 표준편차, 최소/최대값)
df.shape           # (행, 열) 개수
df.columns         # 컬럼명 리스트
df.dtypes          # 각 컬럼의 데이터 타입

데이터 선택 및 조작

# 컬럼 선택
df['column']                    # 단일 컬럼
df[['col1', 'col2']]           # 여러 컬럼

# 슬라이싱 (범위 선택)
df[10:20]                       # 10~19번 행
df[:5]                          # 처음 5개 행

# 조건부 선택
df[df['price'] > 12000]
df[(df['price'] > 12000) & (df['airline'] == 'Air_India')]

# 위치 기반 선택
df.iloc[0]                      # 첫 번째 행
df.iloc[0, 0]                   # 첫 번째 행, 첫 번째 열
df.iloc[:, -1]                  # 마지막 열 전체

# 인덱스 기반 선택
df.loc[0]                       # 인덱스 0인 행
df.loc[:, 'column']             # 특정 컬럼 전체

상관분석

# 상관계수 계산
correlation_matrix = df.corr()

# 히트맵으로 시각화
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')
plt.show()
반응형

2. 데이터 전처리

결측치 처리

# 결측치 확인
df.isnull().sum()
df.isna().sum()

# 결측치가 있는 행 삭제
df.dropna()                     # 결측치가 있는 행 전체 제거
df.dropna(axis=1)               # 결측치가 있는 열 제거
df.dropna(how='any')            # 하나라도 결측치 있으면 제거
df.dropna(how='all')            # 모두 결측치인 경우만 제거

# 결측치 대체
df['column'].fillna(df['column'].mean())        # 평균값
df['column'].fillna(df['column'].median())      # 중간값
df['column'].fillna(df['column'].mode()[0])     # 최빈값
df.fillna(method='ffill')                       # 앞의 값으로 채우기
df.fillna(method='bfill')                       # 뒤의 값으로 채우기
df.replace(np.NaN, 0)                           # 특정 값으로 대체

이상치 처리

# IQR 방법으로 이상치 식별
Q1 = df['column'].quantile(0.25)
Q3 = df['column'].quantile(0.75)
IQR = Q3 - Q1

# 이상치 범위 계산
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

# 이상치 제거
df = df[(df['column'] >= lower_bound) & (df['column'] <= upper_bound)]

# 특정 조건으로 이상치 제거
df = df[df['Fasting Blood Sugar'] < 900]

# 이상치 개수 확인
outliers = df[(df['column'] < lower_bound) | (df['column'] > upper_bound)]
outliers_count = outliers.shape[0]

데이터 타입 변환

# 열 타입 변환
df['column'] = df['column'].astype(type='float')
df['column'] = df['column'].astype('int')
df['column'] = df['column'].astype('str')

컬럼 삭제

# 특정 컬럼 삭제
df = df.drop('column_name', axis=1)
df = df.drop(['col1', 'col2'], axis=1)

# 불필요한 행 삭제
df = df.drop(index=[0, 1, 2])

라벨 인코딩

from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
df['category_encoded'] = le.fit_transform(df['category'])

# 예: 'A', 'B', 'C' → 0, 1, 2

원-핫 인코딩

# pandas 방식 (추천)
df = pd.get_dummies(data=df, columns=['category'], drop_first=True)

# object 타입 전체 컬럼 대상
obj_columns = df.select_dtypes(include='object').columns
df = pd.get_dummies(df, columns=obj_columns, drop_first=True)

# sklearn 방식
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(sparse=False)
encoded = encoder.fit_transform(df[['category']])

데이터 분리

from sklearn.model_selection import train_test_split

# X, y 분리
X = df.drop('target', axis=1)
y = df['target']

# 학습/테스트 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(
    X, y, 
    test_size=0.2,        # 테스트 데이터 비율 (20%)
    random_state=42,      # 재현성을 위한 난수 시드
    stratify=y            # 클래스 비율 유지 (분류 문제)
)

# 훈련/검증 분할 (3-way split)
X_train, X_valid, y_train, y_valid = train_test_split(
    X, y, test_size=0.2, random_state=22, stratify=y
)

데이터 정규화 및 표준화

StandardScaler (표준화)

from sklearn.preprocessing import StandardScaler

# 평균 0, 표준편차 1로 변환
# (x - 평균) / 표준편차
scaler = StandardScaler()
scaler.fit(X_train)                              # 학습
X_train_scaled = scaler.transform(X_train)       # 변환
X_test_scaled = scaler.transform(X_test)         # 테스트 데이터도 동일하게 변환

# fit_transform으로 한번에
X_train_scaled = scaler.fit_transform(X_train)
  • 정규분포를 따르는 데이터에 적합
  • 아웃라이어가 없는 경우 사용
  • 거리 기반 모델(KNN, SVM, K-Means)에서 효과적

MinMaxScaler (정규화)

from sklearn.preprocessing import MinMaxScaler

# 0~1 범위로 변환
# (x - 최소값) / (최대값 - 최소값)
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
  • 데이터 범위를 0과 1로 제한하고자 할 때 사용
  • 딥러닝 모델에서 주로 사용
  • 최소값과 최대값을 알 때 적합

RobustScaler

from sklearn.preprocessing import RobustScaler

# 중앙값과 사분위 범위 사용
# (x - Q2) / (Q3 - Q1)
rs = RobustScaler()
X_train_scaled = rs.fit_transform(X_train)
  • 아웃라이어가 많은 데이터에 적합
  • 이상치의 영향을 덜 받음

3. 데이터 시각화

Matplotlib

# 기본 설정
plt.figure(figsize=(10, 6))

# 선 그래프
plt.plot(df['column'])
plt.plot(df['x'], df['y'], label='label_name')

# 산점도
plt.scatter(df['x'], df['y'])

# 히스토그램
plt.hist(df['column'], bins=20)

# 막대 그래프
plt.bar(df['category'], df['value'])

# 라벨 및 제목
plt.xlabel('X Label')
plt.ylabel('Y Label')
plt.title('Title')
plt.legend()
plt.show()

Seaborn

# 히스토그램
sns.histplot(data=df, x='column', hue='category')

# 박스플롯 (이상치 확인)
sns.boxplot(x='category', y='value', data=df)

# 산점도
sns.scatterplot(x='x', y='y', data=df)

# 조인트플롯 (산점도 + 히스토그램)
sns.jointplot(x='x', y='y', data=df)

# 상관계수 히트맵
sns.heatmap(df.corr(), annot=True, cmap='coolwarm')

# 카운트플롯 (범주형 데이터 개수)
sns.countplot(x='category', hue='target', data=df)

# 범주형 플롯
sns.catplot(x='x', y='y', col='category', data=df)

4. 머신러닝 모델링

분류 모델

K-Nearest Neighbors (KNN)

from sklearn.neighbors import KNeighborsClassifier

knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
score = knn.score(X_test, y_test)

Decision Tree (의사결정나무)

from sklearn.tree import DecisionTreeClassifier

dt = DecisionTreeClassifier(
    max_depth=5,              # 트리 최대 깊이
    random_state=42
)
dt.fit(X_train, y_train)
y_pred = dt.predict(X_test)

Random Forest (랜덤포레스트)

from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(
    n_estimators=100,         # 트리 개수
    max_depth=12,             # 트리 최대 깊이
    random_state=42
)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)

Logistic Regression (로지스틱 회귀)

from sklearn.linear_model import LogisticRegression

lr = LogisticRegression(max_iter=1000)
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)

회귀 모델

Linear Regression (선형 회귀)

from sklearn.linear_model import LinearRegression

model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

Decision Tree Regressor

from sklearn.tree import DecisionTreeRegressor

dt_reg = DecisionTreeRegressor(max_depth=10, random_state=42)
dt_reg.fit(X_train, y_train)
y_pred = dt_reg.predict(X_test)

Random Forest Regressor

from sklearn.ensemble import RandomForestRegressor

rf_reg = RandomForestRegressor(
    n_estimators=70,          # 트리 개수
    max_depth=12,             # 트리 최대 깊이
    max_features=10,          # 최대 Feature 개수
    min_samples_split=3,      # 노드 분할 최소 샘플 수
    random_state=3030
)
rf_reg.fit(X_train, y_train)
y_pred = rf_reg.predict(X_test)

5. 딥러닝 모델링

기본 ANN 모델 구조

라이브러리 임포트

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint

이진 분류 모델

# 모델 생성
model = Sequential()

# 입력층 + 첫 번째 은닉층
model.add(Dense(64, activation='relu', input_shape=(X_train.shape[1],)))
model.add(Dropout(0.2))         # 과적합 방지 (20% 뉴런 임시 비활성화)

# 두 번째 은닉층
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.2))

# 세 번째 은닉층
model.add(Dense(16, activation='relu'))
model.add(Dropout(0.2))

# 출력층 (이진 분류)
model.add(Dense(1, activation='sigmoid'))

# 모델 요약
model.summary()

다중 분류 모델

model = Sequential()
model.add(Dense(128, activation='relu', input_shape=(X_train.shape[1],)))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.5))
# 출력층 (다중 분류 - 클래스 개수만큼)
model.add(Dense(num_classes, activation='softmax'))

회귀 모델

model = Sequential()
model.add(Dense(64, activation='relu', input_shape=(X_train.shape[1],)))
model.add(Dropout(0.2))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.2))
# 출력층 (회귀)
model.add(Dense(1, activation='linear'))

활성화 함수 (Activation Function)

  • relu: 은닉층에서 사용, 0보다 작으면 0으로 변환
  • sigmoid: 이진 분류 출력층, 0~1 사이 값 출력
  • softmax: 다중 분류 출력층, 클래스별 확률 합이 1
  • linear: 회귀 출력층, 값 그대로 출력

모델 컴파일

# 이진 분류
model.compile(
    optimizer='adam',                    # 최적화 알고리즘
    loss='binary_crossentropy',          # 손실 함수
    metrics=['accuracy']                 # 평가 지표
)

# 다중 분류
model.compile(
    optimizer='adam',
    loss='categorical_crossentropy',     # 다중 분류 손실 함수
    metrics=['accuracy']
)

# 회귀
model.compile(
    optimizer='adam',
    loss='mse',                          # Mean Squared Error
    metrics=['mae']                      # Mean Absolute Error
)

콜백 함수 (Callbacks)

# EarlyStopping: 성능 개선이 없으면 조기 종료
es = EarlyStopping(
    monitor='val_loss',      # 모니터링할 지표
    patience=5,              # 5 에포크 동안 개선 없으면 중단
    mode='min',              # 최소화 목표
    verbose=1
)

# ModelCheckpoint: 최적 모델 저장
mc = ModelCheckpoint(
    'best_model.keras',      # 저장 파일명
    monitor='val_loss',
    save_best_only=True,     # 최적 모델만 저장
    mode='min',
    verbose=1
)

모델 학습

history = model.fit(
    X_train, y_train,
    epochs=30,                           # 학습 반복 횟수
    batch_size=16,                       # 배치 크기
    validation_data=(X_valid, y_valid),  # 검증 데이터
    callbacks=[es, mc],                  # 콜백 함수
    verbose=1                            # 진행 상황 출력
)

다중 분류 원-핫 인코딩

from tensorflow.keras.utils import to_categorical

# 레이블을 원-핫 인코딩
y_train_ohe = to_categorical(y_train)
y_test_ohe = to_categorical(y_test)

model.fit(X_train, y_train_ohe, validation_data=(X_test, y_test_ohe))

# 예측 시 argmax로 클래스 선택
predictions = model.predict(X_test)
predicted_class = np.argmax(predictions, axis=1)

학습 곡선 시각화

plt.figure(figsize=(12, 4))

# 손실 곡선
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()

# 정확도 곡선
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()

plt.show()

모델 저장 및 로드

# 딥러닝 모델 저장
model.save('deep_model.h5')

# 모델 로드
from tensorflow.keras.models import load_model
best_model = load_model('best_model.keras')

# 머신러닝 모델 저장
import joblib
joblib.dump(rf, 'rfc_model.pkl')

# 머신러닝 모델 로드
rfc_loaded = joblib.load('rfc_model.pkl')

딥러닝 모델 구조 개념

ANN (Artificial Neural Network)

  • 입력층 → 은닉층 → 출력층 구조
  • 비선형 활성화 함수로 복잡한 패턴 학습
  • 일반적인 데이터 분류/회귀에 사용

RNN (Recurrent Neural Network)

  • 시계열 데이터 처리에 특화
  • hidden state가 시간에 따라 유지됨
  • 시간별로 같은 weight 공유
  • 주식 예측, 자연어 처리 등에 사용
  • BPTT (Back-propagation through time)로 학습
  • 장기 의존성 문제 존재 → LSTM으로 해결

LSTM (Long Short-Term Memory)

  • RNN의 장기 문맥 의존성 문제 해결
  • Cell state를 통해 장기 정보 보존
  • 시계열 데이터의 장기 패턴 학습

CNN (Convolutional Neural Network)

  • 이미지 데이터 처리에 특화
  • 구역별로 같은 필터를 적용하여 weight 공유
  • 이미지 분류, 객체 탐지 등에 사용

6. 모델 성능 평가

분류 모델 평가 지표

from sklearn.metrics import (
    accuracy_score, precision_score, recall_score,
    f1_score, confusion_matrix, classification_report
)

# 예측
y_pred = model.predict(X_test)

# Accuracy (정확도)
# (TP + TN) / (TP + TN + FP + FN)
accuracy = accuracy_score(y_test, y_pred)

# Precision (정밀도)
# TP / (TP + FP) - 양성 예측 중 실제 양성 비율
precision = precision_score(y_test, y_pred)

# Recall (재현율, 민감도)
# TP / (TP + FN) - 실제 양성 중 양성 예측 비율
recall = recall_score(y_test, y_pred)

# F1 Score (조화평균)
# 2 × (Precision × Recall) / (Precision + Recall)
f1 = f1_score(y_test, y_pred)

# Confusion Matrix (혼동 행렬)
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')

# 종합 리포트
print(classification_report(y_test, y_pred))

딥러닝 다중분류 평가[3]

# 원핫 인코딩된 경우 argmax로 변환
cm = confusion_matrix(y_valid.argmax(axis=1), model_y_pred)

# 원핫 인코딩 없는 경우
cm = confusion_matrix(y_valid, model_y_pred)

회귀 모델 평가 지표

from sklearn.metrics import (
    mean_squared_error, mean_absolute_error,
    mean_absolute_percentage_error, r2_score
)

y_pred = model.predict(X_test)

# MAE (Mean Absolute Error) - 평균 절대 오차
mae = mean_absolute_error(y_test, y_pred)

# MSE (Mean Squared Error) - 평균 제곱 오차
mse = mean_squared_error(y_test, y_pred, squared=True)

# RMSE (Root Mean Squared Error)
rmse = mean_squared_error(y_test, y_pred, squared=False)

# R² Score (결정계수) - 1에 가까울수록 좋음
r2 = r2_score(y_test, y_pred)

print(f"MAE: {mae:.4f}")
print(f"MSE: {mse:.4f}")
print(f"RMSE: {rmse:.4f}")
print(f"R² Score: {r2:.4f}")

단일 샘플 예측

# 검증 데이터 중 1개 샘플 예측
test_data = X_valid[1000].reshape(1, -1)  # (1, feature 수) 형태로 reshape

# 머신러닝 예측
single_pred = best_model.predict(test_data)

# 딥러닝 분류 예측
single_pred = best_model.predict(test_data)
predicted_class = np.argmax(single_pred)

# 딥러닝 회귀 예측
single_pred = best_model.predict(test_data)
print(f"예측 결과: {single_pred[0][0]:.4f}")

7. 고급 기법

교차 검증 (Cross Validation)

from sklearn.model_selection import cross_val_score

# K-Fold 교차 검증 (k=5)
scores = cross_val_score(
    model, X, y, 
    cv=5,                    # 5-fold
    scoring='accuracy'       # 평가 지표
)

print(f'CV Scores: {scores}')
print(f'Mean CV Score: {scores.mean():.4f}')
print(f'Std CV Score: {scores.std():.4f}')

하이퍼파라미터 튜닝 (GridSearchCV)

from sklearn.model_selection import GridSearchCV

# 탐색할 하이퍼파라미터 정의
param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [5, 10, 15],
    'min_samples_split': [2, 5, 10]
}

# GridSearchCV 설정
grid_search = GridSearchCV(
    estimator=RandomForestClassifier(random_state=42),
    param_grid=param_grid,
    cv=5,                    # 5-fold 교차 검증
    scoring='accuracy',
    n_jobs=-1,               # 모든 CPU 코어 사용
    verbose=1
)

# 최적 파라미터 탐색
grid_search.fit(X_train, y_train)

# 결과 확인
print(f'Best Parameters: {grid_search.best_params_}')
print(f'Best Score: {grid_search.best_score_:.4f}')

# 최적 모델 사용
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)

8. Python 기본 문법

리스트 메서드

a = [1, 2, 3]
a.append('yellow')           # 마지막에 추가
a.insert(1, 'black')         # 인덱스 1에 삽입
a.extend([4, 5, 6])          # 리스트 확장
a.remove(90)                 # 값 제거
a.count('aaa')               # 값의 개수 반환
a.sort()                     # 오름차순 정렬

딕셔너리 메서드

members = {'name': 'John', 'age': 30}
members.keys()               # key만 반환
members.values()             # value만 반환
members.items()              # (key, value) 튜플로 반환
members.clear()              # 모두 삭제
members.get('name')          # key로 value 얻기
'name' in members            # key 존재 여부 확인

 

반응형