<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Data-SSung</title>
    <link>https://data-ssung.tistory.com/</link>
    <description>Looking for direction</description>
    <language>ko</language>
    <pubDate>Fri, 22 May 2026 18:45:43 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Data-SSung</managingEditor>
    <image>
      <title>Data-SSung</title>
      <url>https://tistory1.daumcdn.net/tistory/4049224/attach/8442e2f089e54a4598b31b00e0082028</url>
      <link>https://data-ssung.tistory.com</link>
    </image>
    <item>
      <title>머신러닝 파이프라인 완벽 가이드: 프로젝트 성공의 핵심 워크플로우</title>
      <link>https://data-ssung.tistory.com/348</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;머신러닝 파이프라인이란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머신러닝 파이프라인은 &lt;b&gt;데이터 수집부터 모델 배포까지의 전체 과정을 체계적으로 관리하는 자동화된 워크플로우&lt;/b&gt;입니다. 마치 공장의 생산라인처럼 각 단계가 순차적으로 연결되어 있어, 효율적이고 일관된 머신러닝 개발을 가능하게 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 파이프라인이 중요할까요?&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 재현성 보장&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동일한 결과를 언제든지 다시 만들어낼 수 있습니다&lt;/li&gt;
&lt;li&gt;실험 결과의 신뢰성을 높입니다&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 자동화를 통한 효율성&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;반복적인 작업을 자동화하여 시간을 절약합니다&lt;/li&gt;
&lt;li&gt;휴먼 에러를 최소화합니다&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 협업 개선&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;팀원들과 일관된 방식으로 작업할 수 있습니다&lt;/li&gt;
&lt;li&gt;코드의 가독성과 유지보수성이 향상됩니다&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;머신러닝 파이프라인의 7단계 워크플로우&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1단계: 문제 정의 및 목표 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 머신러닝 프로젝트의 출발점입니다. 명확한 문제 정의 없이는 성공적인 프로젝트를 기대하기 어렵습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 질문들:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해결하고자 하는 비즈니스 문제는 무엇인가?&lt;/li&gt;
&lt;li&gt;머신러닝이 정말 필요한 문제인가?&lt;/li&gt;
&lt;li&gt;성공 지표는 무엇으로 측정할 것인가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;문제: 고객 이탈 예측
목표: 이탈 가능성이 높은 고객을 사전에 식별하여 맞춤형 마케팅 실시
성공 지표: 정밀도 85% 이상, 재현율 80% 이상
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2단계: 데이터 수집 및 탐색&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양질의 데이터는 머신러닝의 생명선입니다. 가비지 인, 가비지 아웃(Garbage In, Garbage Out)이라는 말처럼 데이터 품질이 모델 성능을 결정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터 수집 방법:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내부 데이터베이스&lt;/li&gt;
&lt;li&gt;외부 API&lt;/li&gt;
&lt;li&gt;웹 크롤링&lt;/li&gt;
&lt;li&gt;공개 데이터셋&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;탐색적 데이터 분석(EDA) 체크리스트:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# 기본 정보 확인
print(f&quot;데이터 크기: {df.shape}&quot;)
print(f&quot;결측값: {df.isnull().sum()}&quot;)
print(f&quot;데이터 타입: {df.dtypes}&quot;)

# 통계적 요약
df.describe()

# 상관관계 분석
correlation_matrix = df.corr()
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3단계: 데이터 전처리 및 특성 공학&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원시 데이터를 모델이 학습할 수 있는 형태로 변환하는 과정입니다. 전체 머신러닝 프로젝트 시간의 약 60-70%를 차지하는 중요한 단계입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주요 전처리 작업:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결측값 처리:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# 수치형 데이터: 평균/중앙값으로 대체
df['age'].fillna(df['age'].median(), inplace=True)

# 범주형 데이터: 최빈값으로 대체
df['category'].fillna(df['category'].mode()[0], inplace=True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이상치 탐지 및 처리:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;# IQR 방법을 이용한 이상치 탐지
Q1 = df['price'].quantile(0.25)
Q3 = df['price'].quantile(0.75)
IQR = Q3 - Q1
outliers = df[(df['price'] &amp;lt; Q1 - 1.5 * IQR) | (df['price'] &amp;gt; Q3 + 1.5 * IQR)]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특성 공학 예시:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;prolog&quot;&gt;&lt;code&gt;# 새로운 특성 생성
df['age_group'] = pd.cut(df['age'], bins=[0, 18, 35, 50, 100], labels=['청소년', '청년', '중년', '노년'])
df['income_per_family'] = df['income'] / df['family_size']
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4단계: 모델 선택 및 학습&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제 유형에 따라 적절한 알고리즘을 선택하고 모델을 학습시킵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문제 유형별 알고리즘 선택:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제 유형 추천 알고리즘 특징&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;회귀 문제&lt;/td&gt;
&lt;td&gt;Linear Regression, Random Forest, XGBoost&lt;/td&gt;
&lt;td&gt;연속값 예측&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;분류 문제&lt;/td&gt;
&lt;td&gt;Logistic Regression, SVM, Random Forest&lt;/td&gt;
&lt;td&gt;범주 예측&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;군집화&lt;/td&gt;
&lt;td&gt;K-Means, DBSCAN&lt;/td&gt;
&lt;td&gt;비지도 학습&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;모델 학습 코드 예시:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 모델 학습
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# 예측 및 평가
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f&quot;정확도: {accuracy:.4f}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5단계: 모델 평가 및 검증&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델의 성능을 객관적으로 평가하고 실제 환경에서의 성능을 예측합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;평가 지표:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;분류 문제&lt;/b&gt;: 정확도, 정밀도, 재현율, F1-score, AUC-ROC&lt;/li&gt;
&lt;li&gt;&lt;b&gt;회귀 문제&lt;/b&gt;: MSE, RMSE, MAE, R&amp;sup2;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;교차 검증 예시:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;from sklearn.model_selection import cross_val_score

# 5-fold 교차 검증
cv_scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')
print(f&quot;교차 검증 평균 정확도: {cv_scores.mean():.4f} (+/- {cv_scores.std() * 2:.4f})&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6단계: 하이퍼파라미터 튜닝&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델의 성능을 최적화하기 위해 하이퍼파라미터를 조정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그리드 서치 예시:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;from sklearn.model_selection import GridSearchCV

# 하이퍼파라미터 범위 설정
param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [None, 10, 20],
    'min_samples_split': [2, 5, 10]
}

# 그리드 서치 실행
grid_search = GridSearchCV(RandomForestClassifier(), param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train, y_train)

print(f&quot;최적 하이퍼파라미터: {grid_search.best_params_}&quot;)
print(f&quot;최고 점수: {grid_search.best_score_:.4f}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7단계: 모델 배포 및 모니터링&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습된 모델을 실제 환경에 배포하고 지속적으로 모니터링합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배포 방법:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;API 서버&lt;/b&gt;: Flask, FastAPI를 이용한 웹 API&lt;/li&gt;
&lt;li&gt;&lt;b&gt;클라우드 서비스&lt;/b&gt;: AWS SageMaker, Google Cloud ML Engine&lt;/li&gt;
&lt;li&gt;&lt;b&gt;엣지 배포&lt;/b&gt;: 모바일 앱, IoT 기기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;모니터링 요소:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모델 성능 지표 추적&lt;/li&gt;
&lt;li&gt;데이터 드리프트 감지&lt;/li&gt;
&lt;li&gt;시스템 리소스 모니터링&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;파이프라인 자동화 도구들&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Scikit-learn Pipeline&lt;/h3&gt;
&lt;pre class=&quot;clean&quot;&gt;&lt;code&gt;from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier

# 파이프라인 생성
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('classifier', RandomForestClassifier())
])

# 한 번에 전처리와 학습 수행
pipeline.fit(X_train, y_train)
predictions = pipeline.predict(X_test)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. MLflow&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실험 추적 및 관리&lt;/li&gt;
&lt;li&gt;모델 버전 관리&lt;/li&gt;
&lt;li&gt;모델 배포 자동화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Apache Airflow&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;복잡한 워크플로우 스케줄링&lt;/li&gt;
&lt;li&gt;의존성 관리&lt;/li&gt;
&lt;li&gt;장애 복구 기능&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실전 파이프라인 구현 예시&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 고객 이탈 예측 파이프라인의 전체 코드입니다:&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
import joblib

class CustomerChurnPipeline:
    def __init__(self):
        self.scaler = StandardScaler()
        self.label_encoder = LabelEncoder()
        self.model = RandomForestClassifier(n_estimators=100, random_state=42)
        
    def preprocess_data(self, df):
        &quot;&quot;&quot;데이터 전처리&quot;&quot;&quot;
        # 결측값 처리
        df['age'].fillna(df['age'].median(), inplace=True)
        
        # 범주형 변수 인코딩
        df['gender_encoded'] = self.label_encoder.fit_transform(df['gender'])
        
        # 특성 생성
        df['tenure_years'] = df['tenure'] / 12
        
        # 수치형 특성 정규화
        numerical_features = ['age', 'tenure', 'monthly_charges']
        df[numerical_features] = self.scaler.fit_transform(df[numerical_features])
        
        return df
    
    def train(self, X, y):
        &quot;&quot;&quot;모델 학습&quot;&quot;&quot;
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
        
        # 모델 학습
        self.model.fit(X_train, y_train)
        
        # 평가
        y_pred = self.model.predict(X_test)
        print(&quot;분류 리포트:&quot;)
        print(classification_report(y_test, y_pred))
        
        return self.model
    
    def save_model(self, filepath):
        &quot;&quot;&quot;모델 저장&quot;&quot;&quot;
        joblib.dump(self.model, filepath)
    
    def load_model(self, filepath):
        &quot;&quot;&quot;모델 로드&quot;&quot;&quot;
        self.model = joblib.load(filepath)

# 사용 예시
pipeline = CustomerChurnPipeline()
# 데이터 로드 및 전처리
df = pd.read_csv('customer_data.csv')
df_processed = pipeline.preprocess_data(df)
# 모델 학습
X = df_processed.drop('churn', axis=1)
y = df_processed['churn']
pipeline.train(X, y)
# 모델 저장
pipeline.save_model('churn_model.pkl')
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;파이프라인 최적화 팁&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 버전 관리&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터, 코드, 모델 모두 버전을 관리하세요&lt;/li&gt;
&lt;li&gt;Git + DVC(Data Version Control) 조합을 추천합니다&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 로깅 및 모니터링&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def train_model(X, y):
    logger.info(&quot;모델 학습 시작&quot;)
    # 모델 학습 코드
    logger.info(&quot;모델 학습 완료&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 테스트 자동화&lt;/h3&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;import unittest

class TestPipeline(unittest.TestCase):
    def test_data_preprocessing(self):
        # 전처리 테스트
        pass
    
    def test_model_training(self):
        # 모델 학습 테스트
        pass
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머신러닝 파이프라인은 성공적인 머신러닝 프로젝트의 핵심입니다. 체계적인 워크플로우를 구축하면 다음과 같은 이점을 얻을 수 있습니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;재현 가능한 결과&lt;/b&gt;: 언제든지 동일한 결과를 얻을 수 있습니다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;효율적인 개발&lt;/b&gt;: 자동화를 통해 시간을 절약할 수 있습니다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;안정적인 운영&lt;/b&gt;: 체계적인 모니터링으로 안정적인 서비스를 제공할 수 있습니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>Data-SSung</author>
      <guid isPermaLink="true">https://data-ssung.tistory.com/348</guid>
      <comments>https://data-ssung.tistory.com/348#entry348comment</comments>
      <pubDate>Thu, 3 Jul 2025 23:54:52 +0900</pubDate>
    </item>
    <item>
      <title>KNN(K-Nearest Neighbors) 알고리즘 완벽 가이드</title>
      <link>https://data-ssung.tistory.com/347</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KNN(K-Nearest Neighbors)은 머신러닝의 가장 직관적이고 간단한 알고리즘 중 하나입니다. &quot;유유상종&quot;이라는 속담처럼, 비슷한 특성을 가진 데이터들은 비슷한 결과를 가질 것이라는 가정에 기반합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;KNN 알고리즘이란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KNN은 &lt;b&gt;게으른 학습(Lazy Learning)&lt;/b&gt; 알고리즘으로, 별도의 훈련 과정 없이 새로운 데이터가 들어올 때 기존 데이터와의 거리를 계산하여 가장 가까운 K개의 이웃을 찾아 예측을 수행합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주요 특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;비모수적(Non-parametric)&lt;/b&gt;: 데이터의 분포에 대한 가정이 없음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인스턴스 기반 학습&lt;/b&gt;: 모든 훈련 데이터를 메모리에 저장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;지연 학습&lt;/b&gt;: 예측 시점에 계산 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;작동 원리&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 거리 계산&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 데이터 포인트와 모든 훈련 데이터 간의 거리를 계산합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;유클리드 거리 (가장 일반적)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;gml&quot;&gt;&lt;code&gt;d = &amp;radic;[(x₁-x₂)&amp;sup2; + (y₁-y₂)&amp;sup2;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;맨하탄 거리&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;gherkin&quot;&gt;&lt;code&gt;d = |x₁-x₂| + |y₁-y₂|
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;민코프스키 거리&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;coq&quot;&gt;&lt;code&gt;d = (&amp;Sigma;|xᵢ-yᵢ|ᵖ)^(1/p)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. K개의 최근접 이웃 선택&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계산된 거리를 기준으로 가장 가까운 K개의 데이터 포인트를 선택합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 예측 수행&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;분류 문제&lt;/b&gt;: 다수결 투표&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;K개 이웃 중 가장 많은 클래스로 분류&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;회귀 문제&lt;/b&gt;: 평균값 계산&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;K개 이웃의 타겟 값 평균 또는 가중 평균&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;핵심 매개변수&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;K값 선택&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;K값이 작을 때 (K=1, 3, 5)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장점: 지역적 패턴을 잘 포착&lt;/li&gt;
&lt;li&gt;단점: 노이즈에 민감, 과적합 위험&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;K값이 클 때 (K=15, 20+)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장점: 노이즈에 강함, 안정적 예측&lt;/li&gt;
&lt;li&gt;단점: 지역적 패턴 무시, 과소적합 위험&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;최적 K값 선택 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;교차 검증을 통한 성능 평가&lt;/li&gt;
&lt;li&gt;일반적으로 &amp;radic;n (n: 훈련 데이터 수)을 시작점으로 사용&lt;/li&gt;
&lt;li&gt;홀수 선택 (분류에서 동점 방지)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;장단점 분석&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;구현 용이성&lt;/b&gt;: 알고리즘이 직관적이고 간단&lt;/li&gt;
&lt;li&gt;&lt;b&gt;범용성&lt;/b&gt;: 분류와 회귀 모두 적용 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비선형 패턴 처리&lt;/b&gt;: 복잡한 결정 경계 학습 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;새로운 데이터 적응&lt;/b&gt;: 온라인 학습 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;계산 복잡도&lt;/b&gt;: O(n) - 모든 훈련 데이터와 거리 계산 필요&lt;/li&gt;
&lt;li&gt;&lt;b&gt;메모리 사용량&lt;/b&gt;: 모든 훈련 데이터를 저장해야 함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;차원의 저주&lt;/b&gt;: 고차원에서 성능 저하&lt;/li&gt;
&lt;li&gt;&lt;b&gt;불균형 데이터&lt;/b&gt;: 다수 클래스에 편향&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;성능 최적화 방법&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 데이터 전처리&lt;/h3&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;# 특성 스케일링 (필수!)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 차원 축소&lt;/h3&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;# PCA를 통한 차원 축소
from sklearn.decomposition import PCA
pca = PCA(n_components=10)
X_reduced = pca.fit_transform(X)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 효율적인 탐색 알고리즘&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;KD-Tree&lt;/b&gt;: 저차원 데이터에 효과적&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ball Tree&lt;/b&gt;: 고차원 데이터에 적합&lt;/li&gt;
&lt;li&gt;&lt;b&gt;LSH (Locality Sensitive Hashing)&lt;/b&gt;: 근사 최근접 이웃 탐색&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제 적용 예시&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 추천 시스템&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;from sklearn.neighbors import NearestNeighbors

# 사용자-아이템 행렬 기반 협업 필터링
model = NearestNeighbors(n_neighbors=5, metric='cosine')
model.fit(user_item_matrix)

# 유사한 사용자 찾기
distances, indices = model.kneighbors(user_profile)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 이상치 탐지&lt;/h3&gt;
&lt;pre class=&quot;haskell&quot;&gt;&lt;code&gt;from sklearn.neighbors import LocalOutlierFactor

# LOF를 이용한 이상치 탐지
lof = LocalOutlierFactor(n_neighbors=20)
outlier_scores = lof.fit_predict(data)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 분류 문제&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV

# 하이퍼파라미터 튜닝
param_grid = {
    'n_neighbors': [3, 5, 7, 9, 11],
    'weights': ['uniform', 'distance'],
    'metric': ['euclidean', 'manhattan']
}

knn = KNeighborsClassifier()
grid_search = GridSearchCV(knn, param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train, y_train)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;성능 평가 지표&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;분류 문제&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정확도(Accuracy)&lt;/b&gt;: 전체 예측 중 맞힌 비율&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정밀도(Precision)&lt;/b&gt;: 양성 예측 중 실제 양성 비율&lt;/li&gt;
&lt;li&gt;&lt;b&gt;재현율(Recall)&lt;/b&gt;: 실제 양성 중 예측한 양성 비율&lt;/li&gt;
&lt;li&gt;&lt;b&gt;F1-Score&lt;/b&gt;: 정밀도와 재현율의 조화 평균&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;회귀 문제&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;MAE (Mean Absolute Error)&lt;/b&gt;: 절대 오차의 평균&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MSE (Mean Squared Error)&lt;/b&gt;: 제곱 오차의 평균&lt;/li&gt;
&lt;li&gt;&lt;b&gt;RMSE (Root Mean Squared Error)&lt;/b&gt;: MSE의 제곱근&lt;/li&gt;
&lt;li&gt;&lt;b&gt;R&amp;sup2; Score&lt;/b&gt;: 결정계수&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실전 팁&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 데이터 전처리가 핵심&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 특성을 동일한 스케일로 정규화&lt;/li&gt;
&lt;li&gt;범주형 변수는 원-핫 인코딩 적용&lt;/li&gt;
&lt;li&gt;결측값 처리 필수&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. K값 선택 전략&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;작은 데이터셋: K = 3~7&lt;/li&gt;
&lt;li&gt;중간 데이터셋: K = &amp;radic;n&lt;/li&gt;
&lt;li&gt;큰 데이터셋: 교차 검증으로 최적화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 거리 메트릭 선택&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;연속형 데이터: 유클리드 거리&lt;/li&gt;
&lt;li&gt;범주형 데이터: 해밍 거리&lt;/li&gt;
&lt;li&gt;고차원 데이터: 코사인 유사도&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 불균형 데이터 처리&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가중치 적용 (weights='distance')&lt;/li&gt;
&lt;li&gt;SMOTE 등으로 데이터 증강&lt;/li&gt;
&lt;li&gt;계층적 샘플링 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KNN은 간단하면서도 강력한 알고리즘입니다. 특히 지역적 패턴이 중요한 문제나 복잡한 결정 경계를 가진 데이터에서 우수한 성능을 보입니다. 하지만 적절한 전처리와 하이퍼파라미터 튜닝이 성공의 열쇠입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;언제 KNN을 사용해야 할까요?&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터의 지역적 패턴이 중요한 경우&lt;/li&gt;
&lt;li&gt;비선형 관계를 모델링해야 하는 경우&lt;/li&gt;
&lt;li&gt;해석 가능한 모델이 필요한 경우&lt;/li&gt;
&lt;li&gt;소규모~중규모 데이터셋을 다루는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Data Analysis/기계학습(Machine Learning)</category>
      <author>Data-SSung</author>
      <guid isPermaLink="true">https://data-ssung.tistory.com/347</guid>
      <comments>https://data-ssung.tistory.com/347#entry347comment</comments>
      <pubDate>Wed, 2 Jul 2025 23:25:15 +0900</pubDate>
    </item>
    <item>
      <title>랜덤포레스트(Random Forest) 완벽 가이드: 숲으로 보는 머신러닝</title>
      <link>https://data-ssung.tistory.com/346</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 결정을 내려야 한다면, 한 명의 전문가 의견을 듣는 것과 여러 명의 전문가 의견을 종합하는 것 중 어느 것이 더 신뢰할 만할까요? 대부분 후자를 선택할 것입니다. 랜덤포레스트는 바로 이런 &quot;집단 지성&quot;의 개념을 머신러닝에 적용한 알고리즘입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;랜덤포레스트란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜덤포레스트는 &lt;b&gt;앙상블(Ensemble) 학습법&lt;/b&gt;의 대표적인 예시로, 여러 개의 의사결정트리(Decision Tree)를 결합하여 예측 성능을 향상시키는 알고리즘입니다. 이름 그대로 &quot;무작위로 만든 숲&quot;이라는 뜻으로, 수많은 나무(의사결정트리)들이 모여 하나의 숲을 이루는 구조입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;핵심 아이디어&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;배깅(Bagging)&lt;/b&gt;: 원본 데이터에서 복원추출로 여러 개의 부분 데이터셋 생성&lt;/li&gt;
&lt;li&gt;&lt;b&gt;랜덤 특성 선택&lt;/b&gt;: 각 노드에서 무작위로 선택된 특성들만 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;다수결 투표&lt;/b&gt;: 분류는 투표, 회귀는 평균으로 최종 결과 결정&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;랜덤포레스트의 작동 원리&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1단계: 부트스트랩 샘플링&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본 데이터에서 복원추출로 여러 개의 훈련 데이터셋을 만듭니다. 각 데이터셋은 원본과 같은 크기지만 일부 데이터는 중복되고 일부는 누락됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2단계: 랜덤 특성 선택&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 의사결정트리를 학습할 때, 모든 특성을 사용하지 않고 무작위로 선택된 일부 특성만 사용합니다. 일반적으로 전체 특성의 제곱근 개수만큼 선택합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3단계: 의사결정트리 학습&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 부트스트랩 샘플과 랜덤 특성 조합으로 의사결정트리를 학습시킵니다. 이때 각 트리는 서로 다른 패턴을 학습하게 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4단계: 예측 결합&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;분류&lt;/b&gt;: 모든 트리의 예측 결과를 투표로 결정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;회귀&lt;/b&gt;: 모든 트리의 예측값의 평균을 계산&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;랜덤포레스트의 장점&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 높은 예측 성능&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개별 의사결정트리보다 일반적으로 더 높은 정확도를 보입니다. 여러 모델의 예측을 결합함으로써 각 모델의 오차가 상쇄되는 효과를 얻습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 과적합 방지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개별 트리는 과적합될 수 있지만, 여러 트리의 결과를 평균내면서 과적합이 크게 줄어듭니다. 특히 노이즈가 많은 데이터에서 강건한 성능을 보입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 특성 중요도 제공&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 특성이 예측에 얼마나 기여하는지 자동으로 계산해줍니다. 이는 특성 선택이나 도메인 이해에 매우 유용합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 결측값 처리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결측값이 있어도 비교적 잘 작동하며, 대체 분할 기준을 사용해 처리할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 병렬 처리 가능&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 트리는 독립적으로 학습되므로 병렬 처리가 가능하여 학습 속도를 크게 향상시킬 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;랜덤포레스트의 단점&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 해석성 부족&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개별 의사결정트리는 해석하기 쉽지만, 수백 개의 트리가 결합된 랜덤포레스트는 해석이 어렵습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 메모리 사용량&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 개의 트리를 저장해야 하므로 메모리 사용량이 상당히 클 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 예측 시간&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 트리의 예측을 결합해야 하므로 단일 트리보다 예측 시간이 길어집니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 범주형 특성 편향&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;범주가 많은 특성에 편향될 수 있으며, 이는 특성 중요도 계산에 영향을 줄 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제 활용 사례&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 금융 분야&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;신용 평가&lt;/b&gt;: 고객의 신용도 예측&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사기 탐지&lt;/b&gt;: 이상 거래 패턴 식별&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주가 예측&lt;/b&gt;: 다양한 금융 지표 기반 주가 움직임 예측&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 의료 분야&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;질병 진단&lt;/b&gt;: 의료 영상이나 검사 결과 기반 진단 보조&lt;/li&gt;
&lt;li&gt;&lt;b&gt;약물 효과 예측&lt;/b&gt;: 환자 특성에 따른 치료 효과 예측&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 마케팅&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;고객 세분화&lt;/b&gt;: 구매 패턴 기반 고객 그룹 분류&lt;/li&gt;
&lt;li&gt;&lt;b&gt;추천 시스템&lt;/b&gt;: 사용자 선호도 예측&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이탈 예측&lt;/b&gt;: 고객 이탈 가능성 사전 감지&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 제조업&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;품질 관리&lt;/b&gt;: 제품 불량 예측&lt;/li&gt;
&lt;li&gt;&lt;b&gt;예측 정비&lt;/b&gt;: 장비 고장 시점 예측&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;하이퍼파라미터 튜닝 가이드&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주요 파라미터&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;n_estimators&lt;/b&gt;: 트리 개수 (100~1000, 많을수록 성능 향상되지만 계산 비용 증가)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;max_depth&lt;/b&gt;: 트리 최대 깊이 (과적합 방지를 위해 제한)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;min_samples_split&lt;/b&gt;: 노드 분할 최소 샘플 수 (2~20)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;min_samples_leaf&lt;/b&gt;: 리프 노드 최소 샘플 수 (1~10)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;max_features&lt;/b&gt;: 각 분할에서 고려할 특성 수 ('sqrt', 'log2', 또는 정수)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;튜닝 전략&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;기본값으로 시작&lt;/b&gt;: 대부분의 경우 기본 설정도 좋은 성능을 보입니다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;n_estimators 조정&lt;/b&gt;: 성능이 포화될 때까지 트리 개수를 늘려봅니다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;과적합 방지&lt;/b&gt;: max_depth, min_samples_split 등으로 복잡도를 조절합니다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;교차 검증 활용&lt;/b&gt;: 그리드 서치나 랜덤 서치로 최적 조합을 찾습니다&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜덤포레스트는 사용하기 쉽고 강력한 성능을 보이는 만능 알고리즘입니다. 특별한 데이터 전처리 없이도 좋은 결과를 얻을 수 있어 머신러닝 입문자부터 전문가까지 널리 사용되고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 모든 문제에 완벽한 해답은 아닙니다. 해석성이 중요한 경우에는 단순한 모델을, 매우 큰 데이터셋에서는 더 효율적인 알고리즘을 고려해볼 필요가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼에도 불구하고 랜덤포레스트는 여전히 많은 실무 환경에서 첫 번째 선택지로 고려되는 신뢰할 만한 알고리즘입니다. 여러분도 다음 프로젝트에서 랜덤포레스트를 활용해 &quot;숲의 지혜&quot;를 경험해보시기 바랍니다.&lt;/p&gt;</description>
      <category>Data Analysis/기계학습(Machine Learning)</category>
      <author>Data-SSung</author>
      <guid isPermaLink="true">https://data-ssung.tistory.com/346</guid>
      <comments>https://data-ssung.tistory.com/346#entry346comment</comments>
      <pubDate>Mon, 30 Jun 2025 16:39:23 +0900</pubDate>
    </item>
    <item>
      <title>  Isolation Forest: 이상탐지의 새로운 패러다임</title>
      <link>https://data-ssung.tistory.com/345</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 분석을 하다 보면 &lt;b&gt;이상한 데이터&lt;/b&gt;를 찾아야 하는 경우가 많음.&lt;br /&gt;신용카드 사기 거래, 시스템 해킹 시도, 제조 설비 이상 등 우리 주변에는 탐지해야 할 이상값들이 넘쳐남.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 이상값을 효과적으로 찾아내는 &lt;b&gt;Isolation Forest&lt;/b&gt; 알고리즘에 대해 알아보자.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  Isolation Forest란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Isolation Forest&lt;/b&gt;는 &lt;b&gt;이상탐지(Anomaly Detection)&lt;/b&gt;를 위한 비지도 학습 알고리즘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심 아이디어는 매우 직관적!&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;이상한 데이터는 정상 데이터보다 쉽게 고립(isolation)된다&quot;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마치 파티에서 혼자만 다른 옷을 입고 온 사람이 금방 눈에 띄는 것처럼, 이상값은 적은 분할로도 다른 데이터와 분리됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;⚙️ 작동 원리&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1️⃣ 랜덤 분할&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터를 무작위로 특성(feature)을 선택해 분할&lt;/li&gt;
&lt;li&gt;트리 구조로 데이터를 나누어감&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2️⃣ 분할 깊이 측정&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정상 데이터&lt;/b&gt;: 많은 분할이 필요 (깊은 위치)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이상 데이터&lt;/b&gt;: 적은 분할로 고립 (얕은 위치)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3️⃣ 점수 계산&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분할 깊이가 얕을수록 &amp;rarr; 이상값 점수 높음&lt;/li&gt;
&lt;li&gt;분할 깊이가 깊을수록 &amp;rarr; 정상값 점수 높음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✨ 주요 특징&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;⚡ 빠른 속도&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시간복잡도: O(n log n)&lt;/li&gt;
&lt;li&gt;대용량 데이터 처리 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  메모리 효율&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전체 데이터를 메모리에 저장할 필요 없음&lt;/li&gt;
&lt;li&gt;트리 구조만 유지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  파라미터 단순&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;복잡한 하이퍼파라미터 튜닝 불필요&lt;/li&gt;
&lt;li&gt;기본 설정으로도 좋은 성능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  확장성&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;고차원 데이터에서도 효과적&lt;/li&gt;
&lt;li&gt;실시간 처리 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;한계점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  정상 데이터 가정&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대부분의 데이터가 정상이라고 가정&lt;/li&gt;
&lt;li&gt;이상값 비율이 높으면 성능 저하&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  해석의 어려움&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;왜 이상값인지 구체적 이유 제공 어려움&lt;/li&gt;
&lt;li&gt;블랙박스 특성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  밀도 기반 한계&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클러스터 내부의 이상값 탐지 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  실제 활용 사례&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;금융권: 사기 거래 탐지&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;makefile&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;정상 패턴: 평소 소비 금액, 자주 방문하는 가맹점
이상 패턴: 새벽 시간 고액 결제, 해외 이상 지역 사용
효과: 실시간 사기 거래 차단으로 고객 보호&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;IT 보안: 침입 탐지&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;makefile&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;정상 패턴: 일반적인 로그인 시간, 업무용 접근
이상 패턴: 비정상 시간대 접근, 권한 외 시도
효과: 해킹 시도 조기 차단&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;제조업: 설비 이상 감지&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;makefile&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;정상 패턴: 안정적인 온도, 압력, 진동 수치
이상 패턴: 급격한 수치 변동, 임계값 초과
효과: 설비 고장 예방, 생산 중단 최소화&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;의료: 이상 소견 발견&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;makefile&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;정상 패턴: 일반적인 혈압, 혈당, 콜레스테롤 수치
이상 패턴: 극단적으로 높거나 낮은 검사값
효과: 조기 진단으로 치료 효과 극대화&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  다른 이상탐지 방법과의 비교&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법속도메모리해석성고차원&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt; 방법 &lt;/b&gt;&lt;/td&gt;
&lt;td&gt;속도&lt;/td&gt;
&lt;td&gt;메모리&lt;/td&gt;
&lt;td&gt;해석&lt;/td&gt;
&lt;td&gt;고차원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Isolation Forest&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LOF&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One-Class SVM&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DBSCAN&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  언제 사용하면 좋을까?&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ &lt;b&gt;추천하는 경우&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;대용량 데이터&lt;/b&gt; 처리가 필요한 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;실시간 이상탐지&lt;/b&gt;가 중요한 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;빠른 프로토타이핑&lt;/b&gt;이 필요한 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;고차원 데이터&lt;/b&gt;를 다루는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;❌ &lt;b&gt;피해야 하는 경우&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이상값의 &lt;b&gt;구체적 원인 파악&lt;/b&gt;이 중요한 경우&lt;/li&gt;
&lt;li&gt;이상값 비율이 &lt;b&gt;30% 이상&lt;/b&gt;인 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;작은 데이터셋&lt;/b&gt; (&amp;lt; 1000개)인 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Isolation Forest는 &lt;b&gt;빠르고 효율적인&lt;/b&gt; 이상탐지 알고리즘으로, 특히 &lt;b&gt;대용량 데이터&lt;/b&gt;와 &lt;b&gt;실시간 처리&lt;/b&gt;가 필요한 환경에서 빛을 발합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복잡한 파라미터 튜닝 없이도 좋은 성능을 내기 때문에, &lt;b&gt;이상탐지 입문자&lt;/b&gt;에게도 추천하는 방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 &lt;b&gt;해석성의 한계&lt;/b&gt;가 있으므로, 이상값의 구체적 원인 파악이 중요한 비즈니스라면 다른 방법과 함께 사용하는 것을 권장합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Data Analysis/기계학습(Machine Learning)</category>
      <author>Data-SSung</author>
      <guid isPermaLink="true">https://data-ssung.tistory.com/345</guid>
      <comments>https://data-ssung.tistory.com/345#entry345comment</comments>
      <pubDate>Sun, 22 Jun 2025 23:02:15 +0900</pubDate>
    </item>
    <item>
      <title>mysql 기본 NULL 처리 함수들</title>
      <link>https://data-ssung.tistory.com/344</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;COALESCE (표준 SQL)&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;COALESCE(col1, col2, '기본값')  -- 첫 번째 non-NULL 값 리턴
COALESCE(amount, 0)            -- amount가 NULL이면 0&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;IFNULL (MySQL 전용)&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;IFNULL(amount, 0)              -- amount가 NULL이면 0
IFNULL(customer_name, '미등록') -- NULL이면 '미등록'&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;ISNULL / IS NULL&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;-- 조건문에서
WHERE amount IS NULL           -- NULL 체크
WHERE amount IS NOT NULL       -- NOT NULL 체크
SELECT ISNULL(amount)          -- NULL이면 1, 아니면 0&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 집계함수의 NULL 처리&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;COUNT&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;COUNT(*)                 -- 모든 행 (NULL 포함)
COUNT(column)            -- NULL 제외
COUNT(DISTINCT column)   -- 중복+NULL 제외&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SUM, AVG, MIN, MAX&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;SUM(amount)              -- NULL 제외하고 합계
AVG(amount)              -- NULL 제외하고 평균
-- 결과가 NULL이면 COALESCE 사용
COALESCE(SUM(amount), 0)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 조건문에서 NULL 처리&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;CASE WHEN&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;CASE 
    WHEN amount IS NULL THEN 0
    WHEN amount &amp;gt; 1000 THEN 'high'
    ELSE 'low'
END&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;IF 함수 (MySQL 전용)&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;yaml&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;IF(amount IS NULL, 0, amount)  -- NULL이면 0, 아니면 원값&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. JOIN에서 NULL 처리&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;LEFT JOIN 후 NULL 처리&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;SELECT 
    a.customer_id,
    COALESCE(b.order_count, 0) as order_count
FROM customers a
LEFT JOIN order_summary b ON a.customer_id = b.customer_id&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 실무 패턴들&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;WHERE 절 NULL 처리&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;-- 안전한 비교
WHERE COALESCE(amount, 0) &amp;gt; 100

-- NULL 포함 검색
WHERE name LIKE '%검색어%' OR name IS NULL&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;GROUP BY NULL 처리&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;GROUP BY COALESCE(category, 'uncategorized')&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;ORDER BY NULL 처리&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;ORDER BY COALESCE(order_date, '1900-01-01')  -- NULL을 맨 앞으로
ORDER BY order_date IS NULL, order_date      -- NULL을 맨 뒤로&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 코테에서 자주 쓰는 패턴&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;-- 매출 없는 고객도 0으로 표시
SELECT 
    customer_id,
    COALESCE(SUM(amount), 0) as total_sales
FROM orders
GROUP BY customer_id

-- 활동 없는 날도 0으로 표시  
SELECT 
    activity_date,
    COALESCE(COUNT(DISTINCT user_id), 0) as active_users
FROM calendar_dates
LEFT JOIN user_activity USING(activity_date)
GROUP BY activity_date&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심:&lt;/b&gt; COUNT는 자동 NULL 처리, 나머지는 COALESCE/IFNULL 사용!  &lt;/p&gt;</description>
      <category>Programing Language/SQL</category>
      <author>Data-SSung</author>
      <guid isPermaLink="true">https://data-ssung.tistory.com/344</guid>
      <comments>https://data-ssung.tistory.com/344#entry344comment</comments>
      <pubDate>Tue, 17 Jun 2025 11:09:22 +0900</pubDate>
    </item>
    <item>
      <title>mysql 실무 적용 코딩 (월별 리텐션 분석)</title>
      <link>https://data-ssung.tistory.com/343</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;상황 : oo님 우리 회사 2025년 1~5월까지 월별 리텐션 분석 자료 부탁해요..asap&lt;/b&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1단계 설계&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;리텐션 비중 : 월 방문자 수/첫 월 방문자 수&amp;nbsp;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;단계
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;고객별 첫 방문 월&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;고객별 월 데이터 셋팅&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;첫 월, 기준 월, 월 간 gap, 첫 월 유저 수, 기준 월 유저 수, 리텐션 비율&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;sql 쿼리 작성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1750124467460&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- inner join 
with cust_first_month as (
    --고객별 첫 방문 월
    select cust_id
    	, min(date_format(order_date, '%Y-%m')) first_ym 
    from orders
    group by cust_id
)
, cust_orders as (
	--고객별 월 데이터 셋팅
	select cust_id
    	, date_format(order_date, '%Y-%m') ym
	from orders
)
--첫 월, 기준 월, 월 간 gap, 첫 월 유저 수, 기준 월 유저 수, 리텐션 비율
select cm.first_month, co.ym
	, timestampdiff(month , str_to_date(cm.first_month, '%Y-%m'), str_to_date(co.ym, '%Y-%m')) month_gap
	, count(distinct cm.cust_id) first_cnt
    , count(distinct co.cust_id) reten_cnt
    , first_cnt/reten_cnt*100 retention_rate
from cust_first_month cm
inner join cust_orders co
	on cm.cust_id = co.cust_id
group by cm.first_month, co.ym
order by first_month, month_gap

/*
select *
from retention_tmp
where first_month = '2025-01' and month_gap &amp;lt;=6
*/
;
;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DATE_FORMAT(order_date, '%Y-%m')의 결과&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변환 결과 문자열 (VARCHAR),&amp;nbsp; DATETIME이 X&lt;/li&gt;
&lt;li&gt;결과: '2025-01' (문자열)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Programing Language/SQL</category>
      <author>Data-SSung</author>
      <guid isPermaLink="true">https://data-ssung.tistory.com/343</guid>
      <comments>https://data-ssung.tistory.com/343#entry343comment</comments>
      <pubDate>Tue, 17 Jun 2025 10:55:41 +0900</pubDate>
    </item>
    <item>
      <title>MySQL 데이터 타입 변환 ( cast)</title>
      <link>https://data-ssung.tistory.com/342</link>
      <description>&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;sql&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;sql&quot; style=&quot;color: #383a42; text-align: left;&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;-- 숫자 변환
CAST(amount AS SIGNED)          -- 정수
CAST(amount AS DECIMAL(10,2))   -- 소수점
CAST(amount AS UNSIGNED)        -- 양의 정수

-- 문자열 변환  
CAST(user_id AS CHAR)           -- 문자열
CAST(user_id AS CHAR(10))       -- 길이 지정

-- 날짜 변환
CAST('2025-01-15' AS DATE)      -- 날짜
CAST('2025-01-15 14:30:00' AS DATETIME)  -- 날짜시간
CAST('2025-01-15 14:30:00' AS TIME)  -- 시간&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
      <category>Programing Language/SQL</category>
      <author>Data-SSung</author>
      <guid isPermaLink="true">https://data-ssung.tistory.com/342</guid>
      <comments>https://data-ssung.tistory.com/342#entry342comment</comments>
      <pubDate>Tue, 17 Jun 2025 10:30:41 +0900</pubDate>
    </item>
    <item>
      <title>mysql datediff vs timestampdiff</title>
      <link>https://data-ssung.tistory.com/341</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;함수별 특징&lt;/h2&gt;
&lt;p&gt;함수단위사용법&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DATEDIFF&lt;/td&gt;
&lt;td&gt;&lt;b&gt;일(day)만&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;DATEDIFF(date1, date2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TIMESTAMPDIFF&lt;/td&gt;
&lt;td&gt;&lt;b&gt;모든 단위&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;TIMESTAMPDIFF(MONTH/DAY/YEAR, date1, date2)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TIMESTAMPDIFF 장점:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MONTH, YEAR, QUARTER, WEEK 등 다양한 단위 지원&lt;/li&gt;
&lt;li&gt;월말/월초 경계 처리가 정확&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Programing Language/SQL</category>
      <author>Data-SSung</author>
      <guid isPermaLink="true">https://data-ssung.tistory.com/341</guid>
      <comments>https://data-ssung.tistory.com/341#entry341comment</comments>
      <pubDate>Tue, 17 Jun 2025 10:08:41 +0900</pubDate>
    </item>
    <item>
      <title>B3C 플랫폼 분석 리텐션 개념</title>
      <link>https://data-ssung.tistory.com/340</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;리텐션이란?&lt;/b&gt; 특정 기간에 가입한 고객들이 이후에도 계속 서비스를 이용하는 비율&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 기본 리텐션 (N일 후 재방문율)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시: 1월 가입자들의 1개월 후 리텐션&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;sql&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;-- 1월 신규 가입자 중 2월에도 활동한 비율
with jan_new_users as (
    select customer_id
    from users 
    where date_format(join_date, '%Y-%m') = '2025-01'
),
feb_active_users as (
    select distinct customer_id
    from user_activity
    where date_format(activity_date, '%Y-%m') = '2025-02'
)
select 
    count(distinct j.customer_id) as jan_new_users,
    count(distinct f.customer_id) as feb_retained_users,
    count(distinct f.customer_id) * 100.0 / count(distinct j.customer_id) as retention_rate
from jan_new_users j
left join feb_active_users f on j.customer_id = f.customer_id;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 코호트 리텐션 (월별 추적)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;각 가입월별로 이후 월들의 리텐션 추적&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;sql&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;sql&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;with first_activity as (
    select 
        customer_id,
        date_format(min(activity_date), '%Y-%m') as cohort_month
    from user_activity
    group by customer_id
),
monthly_activity as (
    select 
        customer_id,
        date_format(activity_date, '%Y-%m') as activity_month
    from user_activity
)
select 
    f.cohort_month,
    m.activity_month,
    timestampdiff(month, 
                  str_to_date(f.cohort_month, '%Y-%m'), 
                  str_to_date(m.activity_month, '%Y-%m')) as month_number,
    count(distinct f.customer_id) as cohort_size,
    count(distinct m.customer_id) as retained_users,
    count(distinct m.customer_id) * 100.0 / count(distinct f.customer_id) as retention_rate
from first_activity f
left join monthly_activity m on f.customer_id = m.customer_id
group by f.cohort_month, m.activity_month
order by f.cohort_month, month_number;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결과 예시:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;cohort_month | activity_month | month_number | retention_rate
2025-01     | 2025-01       | 0            | 100.0%
2025-01     | 2025-02       | 1            | 65.5%
2025-01     | 2025-03       | 2            | 45.2%&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>Data Analysis/데이터분석(Data Analysis)</category>
      <author>Data-SSung</author>
      <guid isPermaLink="true">https://data-ssung.tistory.com/340</guid>
      <comments>https://data-ssung.tistory.com/340#entry340comment</comments>
      <pubDate>Tue, 17 Jun 2025 10:07:25 +0900</pubDate>
    </item>
    <item>
      <title>mysql 실무 적용 코딩 (일별로 최근 30일에 대한 rolling mau 구하기)</title>
      <link>https://data-ssung.tistory.com/339</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;상황 : oo님 우리 회사 2025년 5월에 대해서 일별로 최근 30일에 대한 rolling mau 좀 구해주세요. ASAP!&lt;/b&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1단계 설계&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;mau 개념 : 월별 활동 유저 수&lt;/li&gt;
&lt;li&gt;일별 mau 개념 : 현재 일자 기준 최근 30일에 대해 활동 유저 수&lt;/li&gt;
&lt;li&gt;로직 설계
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기준 일자 생성&lt;/li&gt;
&lt;li&gt;유저 데이터 붙이기(현재 일자부터 최근 30일일자까지)&lt;/li&gt;
&lt;li&gt;일자별 유저 수 집계&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;sql 쿼리 작성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1750119741076&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 일자별 유저 수 집계
select a.activity_date
	, count(distinct u.customer_id) user_cnt
from ( -- 기준 일자 생성
	select distinct activity_date
    from users
) a
-- 유저 데이터 붙이기(현재 일자부터 최근 30일일자까지)
inner join users u
	on u.activity_date between date_sub(a.activity_date, interval 29 day) and a.activity_date
group by a.activity_date&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;보고서 작성 끝!&lt;/b&gt;&lt;/p&gt;</description>
      <category>Programing Language/SQL</category>
      <author>Data-SSung</author>
      <guid isPermaLink="true">https://data-ssung.tistory.com/339</guid>
      <comments>https://data-ssung.tistory.com/339#entry339comment</comments>
      <pubDate>Tue, 17 Jun 2025 09:26:49 +0900</pubDate>
    </item>
  </channel>
</rss>