목적 : 주어진 원본 데이터를 신경망에 적용하기 쉽도록 만드는 것
방법 : 벡터화, 정규화, 결측치 처리, 피처 엔지니어링
모든 특성이 대체로 비슷한 범위를 가져야한다 -> 학습이 잘 되는 요소 중 하나
-> 어떤 특성은 작은 부동 소수 값이고 다른 특성은 매우 큰 정수 값을 가질 수 있음
비교적 큰 값이나 균일하지 않은 데이터를 신경망에 주입하는 것은 위험하다
-> 업데이트할 기울기가 커져 네트워크가 수렴하는 것을 방해할 수 있음
방법: min_max_scaler, standard_scaler
import numpy as np
x -= x.np.mean(axis = 0)
x /= x.np.std(axis = 0)
1. 삭제 (Deletion)
import pandas as pd
# 행 삭제
df.dropna(inplace=True)
# 열 삭제
df.dropna(axis=1, inplace=True)
2. 값 대체 (Imputation)
# 평균 대체
df['column'].fillna(df['column'].mean(), inplace=True)
# 중앙값 대체
df['column'].fillna(df['column'].median(), inplace=True)
# 최빈값 대체
df['column'].fillna(df['column'].mode()[0], inplace=True)
# 고정값 대체
df['column'].fillna(0, inplace=True)
3. 예측 대체 (Predictive Imputation)
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='mean') # 또는 'median', 'most_frequent', 'constant'
df['column'] = imputer.fit_transform(df[['column']])
4. KNN Imputation
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=5)
df_imputed = imputer.fit_transform(df)
from sklearn.linear_model import LinearRegression
# 결측치가 없는 데이터로 학습
train_data = df[df['column'].notna()]
test_data = df[df['column'].isna()]
model = LinearRegression()
model.fit(train_data.drop('column', axis=1), train_data['column'])
# 결측치 예측
predicted_values = model.predict(test_data.drop('column', axis=1))
df.loc[df['column'].isna(), 'column'] = predicted_values
6. 결측치 표시 (Missing Indicator)
결측치가 있는 위치를 표시하는 새로운 이진 변수를 추가합니다. 결측치 처리를 하면서 동시에 결측치의 패턴을 모델에 제공할 수 있습니다.
df['column_missing'] = df['column'].isna().astype(int)
결측치 처리는 데이터 분석 및 머신러닝 모델링에서 필수적인 단계로, 데이터의 완전성과 일관성을 보장하기 위해 적절한 방법을 선택하는 것이 중요합니다.
피처 엔지니어링은 원시 데이터를 머신러닝 알고리즘에 더 적합하게 만들기 위해 데이터를 변환하고 특성(피처)을 생성하는 과정입니다. 피처 엔지니어링은 모델의 성능을 극대화하는 데 중요한 역할을 하며, 데이터 과학 및 머신러닝 프로젝트의 성공에 큰 영향을 미칩니다.
피처 엔지니어링의 주요 단계는 다음과 같습니다:
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# 이미지 데이터 제너레이터 설정
datagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)
train_generator = datagen.flow_from_directory(
'path_to_clock_images',
target_size=(224, 224),
batch_size=32,
class_mode='sparse',
subset='training'
)
validation_generator = datagen.flow_from_directory(
'path_to_clock_images',
target_size=(224, 224),
batch_size=32,
class_mode='sparse',
subset='validation'
)
from tensorflow.keras.applications import VGG16
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
# VGG16 모델을 기반으로 CNN 모델 생성
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
model = Sequential([
base_model,
Flatten(),
Dense(128, activation='relu'),
Dense(24, activation='softmax') # 24시간 형식으로 시간 예측
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()
history = model.fit(
train_generator,
epochs=10,
validation_data=validation_generator
)
import cv2
import numpy as np
def extract_features(image_path):
img = cv2.imread(image_path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(img_gray, 50, 150)
# Hough Line Transform을 사용하여 시계 바늘 추출
lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=80, minLineLength=30, maxLineGap=10)
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
# 중심과 끝 좌표로 벡터 계산 (여기서는 간단히 첫 번째 선만 사용)
angle = np.arctan2(y2 - y1, x2 - x1) * 180 / np.pi
return angle
return None
angle = extract_features('path_to_sample_clock_image.jpg')
print('Extracted angle:', angle)
# 예제에서는 각도 피처를 사용하여 새로운 모델을 설계할 수 있습니다.
# 피처 엔지니어링을 통해 추가적인 유의미한 피처를 생성하여 모델 성능을 높일 수 있습니다.
과적합과 과소적합은 머신러닝 모델의 성능과 관련된 두 가지 주요 문제입니다. 이 개념들을 이해하고 적절한 조치를 취하는 것은 모델의 일반화 성능을 향상시키는 데 매우 중요합니다.
해결 방법:

두 규제 방식은 모두 과적합을 방지하고 모델의 일반화 성능을 향상시키는 데 사용되지만, 구체적인 상황과 데이터셋에 따라 선택해야 합니다. 예를 들어, L1 규제는 특징 선택이 중요한 경우에 유리하며, L2 규제는 대부분의 특징이 중요하고 큰 데이터셋을 다룰 때 유리합니다.
드롭아웃(Dropout)은 인공신경망의 학습 과정에서 무작위로 일부 뉴런을 비활성화(드롭)함으로써 과적합(overfitting)을 방지하고 모델의 일반화 성능을 향상시키는 정규화 기법입니다. 드롭아웃은 학습 과정 중 각 훈련 단계에서 네트워크의 일부 뉴런을 무작위로 선택하여 0으로 설정하고, 이를 통해 네트워크가 특정 뉴런이나 경로에 지나치게 의존하지 않도록 합니다.
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
# MNIST 데이터셋 로드 및 전처리
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(-1, 784).astype('float32') / 255
x_test = x_test.reshape(-1, 784).astype('float32') / 255
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
# 모델 정의
model = Sequential([
Dense(512, activation='relu', input_shape=(784,)),
Dropout(0.5, name='dropout_1'),
Dense(512, activation='relu'),
Dropout(0.5, name='dropout_2'),
Dense(10, activation='softmax')
])
# 모델 컴파일
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 모델 훈련
history = model.fit(x_train, y_train, epochs=10, batch_size=128, validation_split=0.2)
단순 홀드아웃 검증은 데이터셋을 두 개의 부분으로 나누어 모델을 평가하는 가장 기본적인 방법입니다. 데이터셋을 훈련 데이터와 테스트 데이터로 나누고, 훈련 데이터를 사용하여 모델을 학습시킨 후 테스트 데이터를 사용하여 모델의 성능을 평가합니다.
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# 데이터 로드
data = load_iris()
X, y = data.data, data.target
# 데이터 분할 (훈련: 80%, 테스트: 20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 모델 학습
model = RandomForestClassifier()
model.fit(X_train, y_train)
# 모델 평가
y_pred = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))
K-겹 교차 검증은 데이터셋을 K개의 부분으로 나누어 K번의 학습과 평가를 진행하는 방법입니다. 각 부분이 한 번씩 테스트 데이터로 사용되고 나머지 K-1개의 부분이 훈련 데이터로 사용됩니다.
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
# 데이터 로드
data = load_iris()
X, y = data.data, data.target
# K-겹 교차 검증 (K=5)
model = RandomForestClassifier()
scores = cross_val_score(model, X, y, cv=5)
print("Cross-Validation Scores:", scores)
print("Mean Accuracy:", scores.mean())
셔플링은 데이터셋을 무작위로 섞는 과정입니다. 셔플링은 데이터셋이 정렬되어 있거나 특정 순서가 있을 때, 이를 무작위로 섞어 학습 과정에서 편향을 줄이고 모델의 일반화 성능을 높이는 데 사용됩니다.
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
# 데이터 로드
data = load_iris()
X, y = data.data, data.target
# 데이터 셔플링 및 분할
X, y = np.random.permutation(X), np.random.permutation(y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 모델 학습 및 평가
model = RandomForestClassifier()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))
요약
각 방법은 데이터의 특성, 모델의 복잡도, 계산 자원 등을 고려하여 적절히 선택해야 합니다.