1. 슈퍼스토어 마케팅 캠페인 데이터셋

슈퍼스토어 마케팅 캠페인 데이터셋은 Superstore 마케팅 캠페인 데이터를 포함하고 있으며, 고객의 인구통계학적 정보(예: 출생 연도, 학력, 결혼 상태, 소득), 가구 구성(어린이와 십대 자녀 수), 구매 기록(와인, 육류, 생선 등 다양한 제품군에 대한 지출), 구매 채널(매장, 웹사이트, 카탈로그), 그리고 고객의 마케팅 캠페인 참여 여부 및 불만 기록 등을 담고 있습니다. 이 데이터는 고객의 행동 패턴과 마케팅 전략의 효과를 분석하는 데 유용합니다.

2. 데이터셋 컬럼 설명

  • ID: 각 고객의 고유 식별 번호입니다.
    • 데이터에서 고객을 구별하기 위한 유일한 값입니다.
  • Year_Birth: 고객의 출생 연도입니다.
    • 이 값을 사용해 고객의 나이를 계산할 수 있습니다.
  • Complain: 지난 2년간 고객이 불만을 제기한 적이 있는지를 나타냅니다.
    • 1: 불만을 제기한 적 있음.
    • 0: 불만을 제기한 적 없음.
  • Dt_Customer: 고객이 회사와 거래를 시작한 날짜입니다.
    • 고객 충성도 또는 거래 기간 분석에 활용할 수 있습니다.
  • Education: 고객의 학력 수준입니다.
    • 예: 고졸, 대졸, 대학원 졸업 등.
  • Marital: 고객의 결혼 상태를 나타냅니다.
    • 예: 독신(Single), 기혼(Married), 이혼(Divorced) 등.
  • Kidhome: 고객 가정에 있는 어린 아이(소아)의 수를 나타냅니다.
    • 나이가 어린 자녀의 수를 분석하는 데 유용합니다.
  • Teenhome: 고객 가정에 있는 십대 자녀의 수를 나타냅니다.
    • 십대 자녀 수와 구매 행동 간의 관계를 분석할 수 있습니다.
  • Income: 고객 가정의 연간 가계 소득입니다.
    • 구매력이나 소비 패턴을 분석하는 중요한 변수입니다.
  • MntFishProducts: 지난 2년 동안 생선 제품에 지출한 금액입니다.
  • MntMeatProducts: 지난 2년 동안 육류 제품에 지출한 금액입니다.
  • MntFruits: 지난 2년 동안 과일 제품에 지출한 금액입니다.
  • MntSweetProducts: 지난 2년 동안 디저트(단 제품)에 지출한 금액입니다.
  • MntWines: 지난 2년 동안 와인 제품에 지출한 금액입니다.
  • MntGoldProds: 지난 2년 동안 금으로 된 제품에 지출한 금액입니다.
    • 고가 상품 소비 경향을 분석할 수 있습니다.
  • NumDealsPurchases: 할인을 통해 구매한 횟수입니다.
    • 고객이 가격 할인에 민감한지 알 수 있습니다.
  • NumCatalogPurchases: 카탈로그를 이용한 구매 횟수입니다.
    • 우편 주문이나 비대면 구매 경향을 나타냅니다.
  • NumStorePurchases: 매장에서 직접 구매한 횟수입니다.
    • 오프라인 구매 성향을 분석하는 데 유용합니다.
  • NumWebPurchases: 웹사이트를 통해 구매한 횟수입니다.
    • 온라인 구매 경향을 평가할 수 있습니다.
  • NumWebVisitsMonth: 지난달 동안 웹사이트를 방문한 횟수입니다.
    • 고객이 웹사이트에서의 관심도를 측정할 수 있습니다.

 

 

3. 데이터 전처리 및 EDA

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

 

mkt_df = pd.read_csv('/본인의 구글드라이브 경로/superstore_data.csv')
mkt_df

 

mkt_df.info()

 

mkt_df.drop('Id', axis=1, inplace=True)

 

mkt_df.describe()

 

mkt_df.sort_values('Year_Birth')

 

mkt_df.sort_values('Income', ascending=False)

 

# mkt_df = mkt_df[mkt_df['Income'] < 200000] # NaN값도 저장되지 않음
mkt_df = mkt_df[mkt_df['Income'] != 666666] # 실수값으로 표현하지 않아도 됨
mkt_df.sort_values('Income', ascending=False)

 

mkt_df.isna().mean()

 

mkt_df = mkt_df.dropna()

 

mkt_df.isna().mean()

 

mkt_df.info()

 

mkt_df['Dt_Customer'] = pd.to_datetime(mkt_df['Dt_Customer'])

 

mkt_df.info()

 

# Dt_Customer 기준으로 Dt_Customer의 마지막 가입일과의 차를 구하기
# 단, "월"로 계산
# 파생변수: pass_month
mkt_df['pass_month'] = (mkt_df['Dt_Customer'].max().year * 12 + mkt_df['Dt_Customer'].max().month) - (mkt_df['Dt_Customer'].dt.year * 12 + mkt_df['Dt_Customer'].dt.month)
mkt_df.head()

 

mkt_df.drop('Dt_Customer', axis=1, inplace=True)

 

mkt_df.head()

 

mkt_df['Total_mnt'] = mkt_df[['MntWines', 'MntFruits', 'MntMeatProducts',
                              'MntFishProducts', 'MntSweetProducts',
                              'MntGoldProds']].sum(axis=1)
mkt_df.head()

 

mkt_df['Children'] = mkt_df[['Kidhome', 'Teenhome']].sum(axis=1)
mkt_df.head()

 

mkt_df.drop(['Kidhome', 'Teenhome'], axis=1, inplace=True)

 

mkt_df.info()

 

mkt_df['Education'].value_counts()

 

mkt_df['Marital_Status'].value_counts()

 

mkt_df = mkt_df[~mkt_df['Marital_Status'].isin(['Absurd', 'YOLO'])]
mkt_df['Marital_Status'].value_counts()

 

mkt_df['Marital_Status'] = mkt_df['Marital_Status'].replace({
    'Married':'Partner',
    'Together':'Partner',
    'Single':'Single',
    'Divorced':'Single',
    'Widow':'Single',
    'Alone':'Single'
})

 

mkt_df['Marital_Status'].value_counts()

 

mkt_df.info()

 

mkt_df = pd.get_dummies(mkt_df, columns=['Education', 'Marital_Status'])
mkt_df.head()

 

from sklearn.preprocessing import StandardScaler

ss = StandardScaler()

 

mkt_df.columns

 

ss.fit_transform(mkt_df[['Income', 'Recency', 'MntWines', 'MntFruits',
       'MntMeatProducts', 'MntFishProducts', 'MntSweetProducts',
       'MntGoldProds', 'NumDealsPurchases', 'NumWebPurchases',
       'NumCatalogPurchases', 'NumStorePurchases', 'NumWebVisitsMonth',
       'Response', 'pass_month', 'Total_mnt', 'Children']])

 

mkt_df[['Income', 'Recency', 'MntWines', 'MntFruits',
       'MntMeatProducts', 'MntFishProducts', 'MntSweetProducts',
       'MntGoldProds', 'NumDealsPurchases', 'NumWebPurchases',
       'NumCatalogPurchases', 'NumStorePurchases', 'NumWebVisitsMonth',
       'Response', 'pass_month', 'Total_mnt', 'Children']] = ss.fit_transform(mkt_df[['Income', 'Recency', 'MntWines', 'MntFruits',
       'MntMeatProducts', 'MntFishProducts', 'MntSweetProducts',
       'MntGoldProds', 'NumDealsPurchases', 'NumWebPurchases',
       'NumCatalogPurchases', 'NumStorePurchases', 'NumWebVisitsMonth',
       'Response', 'pass_month', 'Total_mnt', 'Children']])

 

mkt_df

 

 

4. 클러스터

클러스터(Clusters)는 데이터 분석에서 비슷한 특성을 가진 데이터 포인트들을 그룹화한 결과를 의미합니다. 클러스터링은 비지도 학습의 한 형태로, 데이터 내에 숨겨진 패턴이나 구조를 찾는 데 사용됩니다. 각 클러스터는 내부적으로는 데이터 포인트들이 매우 유사하지만, 다른 클러스터와는 차별화된 특성을 가지도록 구성됩니다. 예를 들어, 고객 데이터를 클러스터링하면 구매 패턴, 소득 수준, 관심사 등에 따라 고객 그룹을 나눌 수 있으며, 이를 통해 타겟 마케팅이나 고객 세그먼테이션과 같은 전략적 의사결정을 내릴 수 있습니다. 대표적인 클러스터링 알고리즘으로는 K-평균(K-Means), 계층적 클러스터링, DBSCAN 등이 있습니다.

from sklearn.datasets import make_blobs

X, y = make_blobs(n_samples=100, centers=3, random_state=2025)

 

X

 

y

 

X = pd.DataFrame(X)
X

 

sns.scatterplot(x=X[0], y=X[1], hue=y)

 

 

5. K-Means

K-Means는 가장 널리 사용되는 클러스터링 알고리즘 중 하나로, 데이터를 K개의 클러스터로 나누는 비지도 학습 기법입니다. 알고리즘은 먼저 데이터 내에서 K개의 초기 중심점(centroid)을 랜덤하게 선택한 뒤, 각 데이터 포인트를 가장 가까운 중심점에 할당하여 클러스터를 형성합니다. 그런 다음, 각 클러스터의 평균값을 계산하여 중심점을 갱신하고, 이 과정을 중심점의 위치가 더 이상 변하지 않을 때까지 반복합니다. K-Means는 계산이 간단하고 대규모 데이터셋에서도 빠르게 작동하지만, 클러스터 수(K)를 사전에 정해야 하고, 데이터가 구형으로 분포하지 않거나 잡음(noise)이 많은 경우 성능이 떨어질 수 있습니다. 이 알고리즘은 고객 세그먼트화, 이미지 압축, 패턴 인식 등 다양한 분야에서 활용됩니다.

 

※ 간단한 예제

 

from sklearn.cluster import KMeans

km = KMeans(n_clusters=3)
km.fit(X)
pred = km.predict(X)

sns.scatterplot(x=X[0], y=X[1], hue=pred)

 

km = KMeans(n_clusters=5)
km.fit(X)
pred = km.predict(X)

sns.scatterplot(x=X[0], y=X[1], hue=pred)

 

km.inertia_

 

※ Inertia

inertia_는 KMeans 군집화 모델에서 계산되는 관성(Inertia) 값을 나타냅니다. 관성은 각 클러스터의 중심(centroid)과 클러스터에 속한 데이터 포인트 사이의 거리 제곱합(Sum of Squared Distances, SSD)으로 계산되며, 클러스터가 얼마나 잘 형성되었는지 평가하는 데 사용됩니다.

  • 클러스터 내 데이터 포인트들이 중심에 얼마나 밀집되어 있는지를 나타냅니다.
  • 관성 값이 작을수록 클러스터링 품질이 좋다는 것을 의미합니다.
  • 관성 값만으로 최적의 클러스터 개수를 결정하지는 않습니다. 관성 값은 클러스터 개수가 많아질수록 항상 감소하기 때문에, 실루엣 점수 등 다른 지표와 함께 고려하는 것이 중요합니다.

 

※ 엘보우 메서드

  • Elbow Method에서는 관성 값을 클러스터 개수(k)에 따라 계산하고, 이 값을 통해 최적의 클러스터 개수를 결정합니다.
  • 일반적으로, kk가 증가하면 관성 값은 감소합니다. 하지만 kk가 어느 순간부터는 감소율이 급격히 줄어들게 됩니다. 이 지점을 Elbow Point라고 하며, 최적의 클러스터 개수로 선택합니다.
inertia_list = []

for i in range(2, 11):
    km = KMeans(n_clusters=i)
    km.fit(X)
    inertia_list.append(km.inertia_)
    
inertia_list

 

sns.lineplot(x=range(2, 11), y=inertia_list)

 

inertia_list = []

for i in range(2, 11):
    km = KMeans(n_clusters=i, random_state=2025)
    km.fit(mkt_df)
    inertia_list.append(km.inertia_)

inertia_list

 

sns.lineplot(x=range(2, 11), y=inertia_list)

 

 

6. 실루엣 스코어

실루엣 스코어(Silhouette Score)는 군집화의 품질을 평가하는 지표로, 각 데이터 포인트가 같은 클러스터 내부에서 얼마나 잘 밀집되어 있고 다른 클러스터와 얼마나 명확히 구분되는지를 측정합니다. 점수는 -1에서 1 사이의 값을 가지며, 1에 가까울수록 각 데이터가 올바른 클러스터에 속해 있고 클러스터 간 분리가 잘 이루어졌음을 의미합니다. 0에 가까우면 클러스터 간 구분이 명확하지 않다는 뜻이고, 음수는 데이터가 잘못된 클러스터에 속해 있음을 나타냅니다. 실루엣 스코어는 클러스터 내 거리(a)와 클러스터 간 최소 거리(b)를 비교하여 계산되며, 클러스터링의 최적화 및 클러스터 개수 선정에 자주 사용됩니다.

from sklearn.metrics import silhouette_score

score = []

for i in range(2, 11):
    km = KMeans(n_clusters=i, random_state=2025)
    km.fit(mkt_df)
    pred = km.predict(mkt_df)
    score.append(silhouette_score(mkt_df, pred))

score

 

sns.lineplot(x=range(2, 11), y=score)

 

 

km = KMeans(n_clusters=3, random_state=2025)
km.fit(mkt_df)

 

pred = km.predict(mkt_df)
pred

 

mkt_df['label'] = pred
mkt_df

 

mkt_df['label'].value_counts()

'AI > ML' 카테고리의 다른 글

호텔 예약 수요 데이터셋  (1) 2025.07.24
서울 자전거 공유 수요 예측 데이터셋  (3) 2025.07.23
주택 임대료 예측 데이터셋  (1) 2025.07.23
Scikit-Learn  (2) 2025.07.23
머신러닝 이론  (0) 2025.07.22

1. 호텔 예약 수요 데이터셋

호텔 예약 수요 데이터셋은 일반적으로 호텔 예약에 대한 수요 패턴을 분석하기 위한 데이터셋입니다. 이 데이터셋은 예약 취소, 체크인 날짜, 고객 유형, 체류 기간, 객실 유형, 예약 경로 등 다양한 요소를 포함하며, 주로 예약 트렌드 분석, 고객 행동 예측, 수요 예측 등에 사용됩니다.

 

 

2. 데이터셋 컬럼 설명

  • hotel: 호텔 유형 (Resort Hotel, City Hotel)
  • is_canceled: 예약 취소 여부 (0: 예약 유지, 1: 예약 취소)
  • lead_time: 예약과 실제 체크인 사이의 기간(일 단위)
  • arrival_date_year: 도착 연도
  • arrival_date_month: 도착 월
  • arrival_date_week_number: 해당 연도의 주
  • arrival_date_day_of_month: 도착 일
  • stays_in_weekend_nights: 주말(토, 일) 동안의 숙박일 수
  • stays_in_week_nights: 주중(월~금) 동안의 숙박일 수
  • adults: 성인 투숙객 수
  • children: 어린이 투숙객 수
  • babies: 유아 투숙객 수
  • meal: 예약된 식사 유형
  • country: 고객의 국가
  • market_segment: 예약 시장 세그먼트
  • distribution_channel: 예약 채널 (예: 온라인, 오프라인)
  • is_repeated_guest: 재방문 여부
  • previous_cancellations: 이전 예약 취소 횟수
  • reserved_room_type: 예약된 객실 유형
  • assigned_room_type: 실제 배정된 객실 유형
  • booking_changes: 예약 변경 횟수
  • deposit_type: 보증금 유형 (No Deposit, Non Refund, Refundable)
  • days_in_waiting_list: 대기자 명단에 있었던 일 수
  • customer_type: 고객 유형 (예: Transient, Group)
  • adr: 평균 일일 요금 (유로)
  • required_car_parking_spaces: 주차 공간 요구 수
  • total_of_special_requests: 특별 요청 수
  • reservation_status: 예약 상태 (Check-Out, Canceled, No-Show)
  • reservation_status_date: 예약 상태가 마지막으로 업데이트된 날짜

3. 데이터 전처리 및 EDA

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

hotel_df = pd.read_csv('/본인의 구글드라이브 경로/hotel_bookings.csv')
hotel_df

 

hotel_df.info()

 

hotel_df.describe()

 

sns.displot(hotel_df['lead_time'])

sns.boxplot(hotel_df['lead_time'])

Q1 = hotel_df['lead_time'].quantile(0.25)
Q3 = hotel_df['lead_time'].quantile(0.75)
print(Q1)	# 18.0
print(Q3)	# 160.0

 

IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
print(lower_bound)	# -195.0
print(upper_bound)	# 373.0

hotel_df = hotel_df[(hotel_df['lead_time'] >= lower_bound) & (hotel_df['lead_time'] <= upper_bound)]

# 원래 119390 에서 줄어듦 -> 이상치가 정리된 것을 알 수 있다.
len(hotel_df)		# 116385

 

sns.barplot(x=hotel_df['distribution_channel'], y=hotel_df['is_canceled'])

# 오차를 확인하기 위해 count 보기
hotel_df['distribution_channel'].value_counts()

# Undefined는 데이터가 적은데 취소한 사람이 1명이라도 있으면 위처럼 많게 나온다.

 

sns.barplot(x=hotel_df['hotel'], y=hotel_df['is_canceled'])

plt.figure(figsize=(15, 5))
sns.barplot(x=hotel_df['arrival_date_month'], y=hotel_df['is_canceled'])

# 월별로 정리해보기!
import calendar

print(calendar.month_name[1])
print(calendar.month_name[2])
print(calendar.month_name[3])

 

month = []
for i in range(1,13):
    month.append(calendar.month_name[i])

month

# ['January',
#  'February',
#  'March',
#  'April',
#  'May',
#  'June',
#  'July',
#  'August',
#  'September',
#  'October',
#  'November',
#  'December']

 

plt.figure(figsize=(15, 5))
# 날짜 정렬 후 barplot
sns.barplot(x=hotel_df['arrival_date_month'], y=hotel_df['is_canceled'], order=months)

hotel_df.info()

 

hotel_df.isna().sum()

 

hotel_df['children'].value_counts(dropna=False)

hotel_df['children'] = hotel_df['children'].fillna(0)

 

hotel_df[hotel_df['adults'] == 0]

 

# people 파생변수
hotel_df['people'] = hotel_df['adults'] + hotel_df['children'] + hotel_df['babies']
hotel_df.head()

 

hotel_df[hotel_df['people'] == 0]

 

# hotel_df = hotel_df[hotel_df['people'] != 0]

# .index를 하면 한번에 지울 수 있음
hotel_df.drop(hotel_df[hotel_df['people'] == 0].index, inplace=True)

 

hotel_df[hotel_df['people'] == 0]
# 0 rows × 33 columns

 

# 컬럼 지우기
hotel_df.drop(['adults', 'children', 'babies'], axis=1, inplace=True)

 

hotel_df['total_nights'] = hotel_df['stays_in_week_nights'] + hotel_df['stays_in_weekend_nights']
hotel_df.head()

 

hotel_df.drop(['stays_in_week_nights', 'stays_in_weekend_nights'], axis=1, inplace=True)

 

# season 파생변수
# arrival_date_month에 따라 아래와 같이 값을 저장
# 12, 1, 2: winter
# 3, 4, 5: spring
# 6, 7, 8: summer
# 9, 10, 11: fall
season_dic = {'spring':[3, 4, 5], 'summer': [6, 7, 8], 'fall': [9, 10, 11], 'winter': [12, 1, 2]}

new_season_dic = {}

for i in season_dic:
    for j in season_dic[i]:
        new_season_dic[calendar.month_name[j]] = i

new_season_dic

# {'March': 'spring',
#  'April': 'spring',
#  'May': 'spring',
#  'June': 'summer',
#  'July': 'summer',
#  'August': 'summer',
#  'September': 'fall',
#  'October': 'fall',
#  'November': 'fall',
#  'December': 'winter',
#  'January': 'winter',
#  'February': 'winter'}

 

hotel_df['season'] = hotel_df['arrival_date_month'].map(new_season_dic)
hotel_df.head()

 

# arrival_data_month 컬럼 지우고 season 컬럼 사용
hotel_df.drop(['arrival_date_month'], axis=1, inplace=True)

 

hotel_df['expected_room_type'] = (hotel_df['reserved_room_type'] == hotel_df['assigned_room_type']).astype(int)
hotel_df.head()

 

hotel_df.drop(['reserved_room_type', 'assigned_room_type'], axis=1, inplace=True)

 

hotel_df['cancel_rate'] = hotel_df['previous_cancellations'] / (hotel_df['previous_cancellations'] + hotel_df['previous_bookings_not_canceled'])
hotel_df.head()

 

hotel_df[hotel_df['cancel_rate'].isna()]

 

hotel_df['cancel_rate'] = hotel_df['cancel_rate'].fillna(-1)

 

hotel_df.drop(['previous_cancellations', 'previous_bookings_not_canceled'], axis=1, inplace=True)

 

hotel_df.info()

 

hotel_df.isna().sum()

 

hotel_df['agent'].value_counts(dropna=False).sort_index()

 

hotel_df['agent'] = hotel_df['agent'].fillna(-1)

 

hotel_df['company'].value_counts(dropna=False).sort_index()

 

hotel_df['company'] = hotel_df['company'].fillna(-1)

 

hotel_df.isna().sum()

 

hotel_df.select_dtypes(exclude=['number']).columns.tolist()

 

for i in hotel_df.select_dtypes(exclude=['number']).columns.tolist():
    print(i, hotel_df[i].nunique())

 

hotel_df.drop(['meal', 'country', 'reservation_status_date'], axis=1, inplace=True)

 

hotel_df = pd.get_dummies(hotel_df, columns=hotel_df.select_dtypes(exclude=['number']).columns.tolist(), drop_first=True)
hotel_df.head()

 

hotel_df.info()

 

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(hotel_df.drop('is_canceled', axis=1), hotel_df['is_canceled'], test_size=0.3, random_state=2025)

 

X_train.shape, y_train.shape
# ((81344, 38), (81344,))

 

X_test.shape, y_test.shape
# ((34862, 38), (34862,))

 

 

3. LogisticRegression

사이킷런의 LogisticRegression은 이진 분류(Binary Classification)와 다중 분류(Multiclass Classification) 문제를 해결하기 위한 머신러닝 알고리즘입니다. 로지스틱 회귀는 선형 모델로, 입력 데이터에 대한 선형 결합을 통해 확률을 예측하고, 이 확률을 로지스틱 함수(시그모이드 함수)를 사용해 이진 또는 다중 클래스에 대한 예측을 수행합니다. 사이킷런의 LogisticRegression은 과적합을 방지하기 위한 규제(Regularization) 기법(penalty)을 지원합니다. 또한, 반복 최적화의 최대 횟수를 max_iter로 설정할 수 있으며, 모델의 성능 평가는 정확도, ROC-AUC 등 다양한 지표를 통해 수행할 수 있습니다. 이 모델은 특히 해석 가능성이 높고, 계산이 효율적이며, 선형적으로 구분 가능한 데이터셋에서 뛰어난 성능을 발휘합니다.

 

※ 규제

규제(Regularization)는 머신러닝 모델이 과적합(Overfitting) 되는 것을 방지하기 위해 사용되는 기법입니다. 과적합은 모델이 학습 데이터에 지나치게 맞춰져서, 새로운 데이터(테스트 데이터)에는 제대로 일반화하지 못하는 현상입니다.

규제는 모델의 복잡도를 줄이고, 불필요한 가중치(Weights)를 작게 만들어 과적합을 방지합니다.

 

from sklearn.linear_model import LogisticRegression

lr = LogisticRegression()
lr.fit(X_train, y_train)

# 반복횟수가 부족해서 학습이 덜 됐다! 라고 에러아닌 에러가 뜬 것임
# 따라서 최적해 못찾음

 

  • 반복 횟수가 부족하면 ConvergenceWarning 경고가 나타날 수 있습니다.
  • 이는 알고리즘이 최적해를 찾지 못했다는 의미입니다.
  • max_iter=1000: 최대 1000번 반복하여 최적의 가중치를 찾습니다.
  • 기본값: max_iter=100

 

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
x_train_scaled = scaler.fit_transform(X_train)
x_test_scaled = scaler.fit_transform(X_test)

x_train_scaled

 

model = LogisticRegression(max_iter=1000)
model.fit(x_train_scaled, y_train)
pred = model.predict(x_test_scaled)

 

※ 데이터 스케일링

데이터 스케일링은 서로 다른 범위와 단위를 가진 데이터를 일정한 범위로 변환하여 모델 학습을 더 효율적으로 수행할 수 있도록 만드는 전처리 과정입니다. 주로 변수 간의 값의 크기 차이가 클 때 발생하는 불균형을 해결하기 위해 사용되며, 대표적인 방법으로 표준화(Standardization)와 정규화(Normalization)가 있습니다. 스케일링을 통해 학습 속도를 높이고, 기울기 소실(Gradient Vanishing) 문제를 완화하며, 특정 변수에 모델이 과도하게 의존하는 것을 방지할 수 있습니다.

 

※ 표준화

표준화(Standardization)는 데이터의 평균을 0으로, 표준편차를 1로 변환하여 모든 변수가 동일한 척도를 갖도록 만드는 데이터 전처리 기법입니다. 주로 데이터의 분포가 정규 분포를 따를 때 효과적이며, 값의 크기나 단위가 서로 다른 변수를 비교하거나 머신러닝 알고리즘(예: 로지스틱 회귀, SVM)에서 최적의 성능을 내기 위해 사용됩니다.

 

※ 정규화

정규화(Normalization)는 데이터의 값을 특정 범위(주로 0과 1 사이)로 변환하여 변수 간의 스케일 차이를 줄이는 데이터 전처리 기법입니다. 이는 주로 최소값과 최대값을 사용해 데이터를 조정하며, 대표적인 방법으로 Min-Max Scaling이 있습니다.

from sklearn.metrics import accuracy_score

 

accuracy_score(y_test, pred)

 

hotel_df['is_canceled'].value_counts()

 

 

4. 혼돈 행렬

혼돈 행렬(Confusion Matrix)은 분류 모델의 성능을 평가하기 위해 사용되는 도구로, 예측 결과와 실제 레이블 간의 관계를 요약하여 나타낸 행렬입니다. 이 행렬은 이진 분류 문제에서 네 가지 값으로 구성됩니다. True Positive (TP), True Negative (TN), False Positive (FP), False Negative (FN). TP와 TN은 모델이 올바르게 예측한 경우를 나타내며, FP와 FN은 모델이 잘못 예측한 경우를 나타냅니다. 이를 통해 분류 모델의 정확도(Accuracy), 정밀도(Precision), 재현율(Recall), F1 점수와 같은 다양한 성능 지표를 계산할 수 있습니다. 혼돈 행렬은 특히 클래스 간 불균형이 있는 데이터에서 모델의 예측 성능을 구체적으로 분석할 때 유용합니다.

 

 

  • True Positive (TP)
    • 실제값이 양성이고, 모델도 양성으로 올바르게 예측한 경우
    • 예: 실제로 스팸 메일이고, 모델이 스팸 메일로 예측
  • True Negative (TN)
    • 실제값이 음성이고, 모델도 음성으로 올바르게 예측한 경우
    • 예: 실제로 정상 메일이고, 모델이 정상 메일로 예측
  • False Positive (FP)
    • 실제값은 음성이지만, 모델이 양성으로 잘못 예측한 경우
    • 예: 정상 메일을 스팸으로 잘못 예측
  • False Negative (FN)
    • 실제값은 양성이지만, 모델이 음성으로 잘못 예측한 경우
    • 예: 스팸 메일을 정상 메일로 잘못 예측

 

※ 혼돈 행렬로 계산할 수 있는 지표

 

from sklearn.metrics import confusion_matrix

confusion_matrix(y_test, pred)

 

from sklearn.metrics import precision_score, recall_score, f1_score

print(precision_score(y_test, pred))
print(recall_score(y_test, pred))
print(f1_score(y_test, pred))

 

# 기울기
model.coef_

 

# +b
model.intercept_

 

# 확률 계산 : predict_proba
proba = model.predict_proba(x_test_scaled)
# 취소를 안할 확률 , 취소 할 확률
proba

 

# 취소를 할 확률만 뽑기
proba = model.predict_proba(x_test_scaled)[:, 1]
proba

 

# 임계값 설정 -> 중앙값 설정, 이건 내 맘!
threshold = 0.5
pred = (proba >= threshold).astype(int)
pred

 

 

5. 분류 문제에서의 랜덤 포레스트

랜덤 포레스트는 결정 트리(Decision Trees)를 여러 개 만들어서 결합(앙상블)하여 예측 성능을 향상시키는 앙상블 학습(Ensemble Learning) 기법입니다. 분류 문제에서 랜덤 포레스트는 각 트리의 예측값을 모아서 다수결(Majority Voting)을 통해 최종 클래스를 결정합니다.

  • 각 트리의 노드 분할(Split) 단계에서, 전체 특성이 아닌 무작위로 선택된 일부 특성만을 사용합니다.
  • 이를 통해 트리 간의 상관관계를 줄이고, 과적합을 방지합니다.
  • 각 트리에 들어가는 데이터의 개수는 원본 데이터셋 크기와 동일합니다.
  • 그러나 중복을 허용하여 샘플링하므로, 일부 데이터는 여러 번 샘플링되고, 일부 데이터는 선택되지 않을 수 있습니다.
  • 부트스트래핑된 데이터와 랜덤하게 선택된 특성을 사용하여 결정 트리를 학습합니다.
  • 사이킷런(Sklearn)에서 랜덤 포레스트의 기본 트리 개수는 100개입니다.
  • 다수결(Majority Voting): 분류 문제에서 가장 많이 예측된 클래스를 선택합니다.
X_train, X_test, y_train, y_test = train_test_split(hotel_df.drop('is_canceled', axis=1), hotel_df['is_canceled'], test_size=0.3, random_state=2025)

 

from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(random_state=2025)
rf.fit(X_train, y_train)
pred1 = rf.predict(X_test)
pred1

 

proba1 = rf.predict_proba(X_test)
proba1

 

# 첫번째 테스트 데이터에 대한 예측 결과
proba1[0]

 

# 모든 테스트 데이터에 대한 호텔 예약을 취소할 확률만 출력
proba1[:, 1]

 

accuracy_score(y_test, pred1)

 

confusion_matrix(y_test, pred1)

 

from sklearn.metrics import classification_report, roc_auc_score

print(classification_report(y_test, pred1))

 

※ ROC AUC Score

ROC AUC Score(Receiver Operating Characteristic - Area Under the Curve)는 이진 분류 모델의 성능을 평가하는 지표로, 분류기의 예측 능력을 직관적으로 나타냅니다. ROC 곡선은 FPR(거짓 양성 비율)과 TPR(참 양성 비율)을 축으로 하여 다양한 임계값에서 모델의 성능을 시각화한 곡선입니다. AUC(Area Under the Curve)는 이 곡선 아래의 면적을 나타내며, 값이 1에 가까울수록 완벽한 분류 성능을 의미하고, 0.5에 가까울수록 랜덤 추측에 가까운 성능을 나타냅니다. 따라서 ROC AUC Score는 모델의 분류 성능이 얼마나 좋은지를 평가하는 데 중요한 역할을 합니다.

 

※ ROC Curve

ROC 곡선은 이진 분류 모델의 성능을 평가하기 위해 사용하는 곡선으로, 모델의 민감도(참 양성 비율, TPR)와 특이도(참 음성 비율, TNR)의 반대인 거짓 양성 비율(FPR)의 관계를 시각화한 그래프입니다.

 

※ AUC (Area Under the Curve)

AUC는 ROC 곡선 아래의 면적을 나타내며, 이진 분류기의 성능을 하나의 숫자로 나타내는 지표입니다. AUC는 다음을 의미합니다:

  • AUC = 1: 완벽한 분류기
  • AUC = 0.5: 랜덤 추측 수준
  • AUC < 0.5: 모델 성능이 무작위 추측보다 나쁨

수학적으로 AUC는 양성 클래스와 음성 클래스의 예측 점수를 비교해 양성 클래스가 더 높은 점수를 받을 확률을 나타냅니다.

roc_auc_score(y_test, proba1[:, 1])

 

import matplotlib.pyplot as plt
from sklearn.metrics._plot.roc_curve import roc_curve

fpr, tpr, thr = roc_curve(y_test, proba1[:, 1])
print(fpr, tpr, thr)

plt.plot(fpr, tpr, label='ROC Curve')
plt.plot([0, 1], [0, 1])
plt.show()

 

6. 교차 검증

교차 검증 (Cross Validation)은 모델의 성능을 더 정확히 평가하기 위해 데이터를 반복적으로 학습용 데이터와 검증용 데이터로 나누어 사용하는 기법입니다. 가장 일반적인 방식인 k-겹 교차 검증(k-fold Cross Validation)은 데이터를 k개의 동일한 크기로 나누고, 각 부분을 한 번씩 검증 데이터로 사용하며 나머지 부분을 학습 데이터로 사용하여 모델을 훈련하고 평가합니다. 이를 통해 데이터 분할에 따른 편향을 줄이고, 모델의 일반화 성능(새로운 데이터에 대한 예측 능력)을 신뢰성 있게 측정할 수 있습니다. 크로스 밸리데이션은 특히 데이터셋이 작거나 편향된 경우에 유용하며, 과적합(overfitting)을 방지하는 데 도움을 줍니다.

k-겹 교차 검증

# k-겹 교차 검증
from sklearn.model_selection import KFold

kf = KFold(n_splits=5)
kf

# KFold(n_splits=5, random_state=None, shuffle=False) -> 하이퍼 파라미터로 설정해줘야함!

 

hotel_df

 

# 하이퍼 파라미터 설정 전
for train_index, test_index in kf.split(range(len(hotel_df))):
    print(train_index, test_index, len(train_index), len(test_index))
    
# [ 23242  23243  23244 ... 116203 116204 116205] [    0     1     2 ... 23239 23240 23241] 92964 23242
# [     0      1      2 ... 116203 116204 116205] [23242 23243 23244 ... 46480 46481 46482] 92965 23241
# [     0      1      2 ... 116203 116204 116205] [46483 46484 46485 ... 69721 69722 69723] 92965 23241
# [     0      1      2 ... 116203 116204 116205] [69724 69725 69726 ... 92962 92963 92964] 92965 23241
# [    0     1     2 ... 92962 92963 92964] [ 92965  92966  92967 ... 116203 116204 116205] 92965 23241

 

kf = KFold(n_splits=5, random_state=2025, shuffle=True)
kf

 

# 하이퍼 파라미터 설정 후
for train_index, test_index in kf.split(range(len(hotel_df))):
    print(train_index, test_index, len(train_index), len(test_index))
    
# [     0      1      2 ... 116201 116202 116205] [    17     18     26 ... 116198 116203 116204] 92964 23242
# [     1      2      3 ... 116203 116204 116205] [     0      7     13 ... 116199 116200 116202] 92965 23241
# [     0      3      4 ... 116203 116204 116205] [     1      2      8 ... 116174 116184 116196] 92965 23241
# [     0      1      2 ... 116202 116203 116204] [     3      5      6 ... 116188 116193 116205] 92965 23241
# [     0      1      2 ... 116203 116204 116205] [     4     16     20 ... 116191 116194 116201] 92965 23241

 

acc_list = []

for train_index, test_index in kf.split(range(len(hotel_df))):
    X = hotel_df.drop('is_canceled', axis=1)
    y = hotel_df['is_canceled']

    # iloc : train_index에 있는 것만! 뽑아서 넣기
    X_train = X.iloc[train_index]
    X_test = X.iloc[test_index]
    y_train = y.iloc[train_index]
    y_test = y.iloc[test_index]

    rf = RandomForestClassifier()
    rf.fit(X_train, y_train)
    pred = rf.predict(X_test)
    acc_list.append(accuracy_score(y_test, pred))

 

acc_list
# [1.0, 1.0, 1.0, 1.0, 1.0] 완벽한 학습모델🔥

 

np.array(acc_list).mean()
# np.float64(1.0)

 

'AI > ML' 카테고리의 다른 글

슈퍼스토어 마케팅 캠페인 데이터셋  (0) 2025.07.24
서울 자전거 공유 수요 예측 데이터셋  (3) 2025.07.23
주택 임대료 예측 데이터셋  (1) 2025.07.23
Scikit-Learn  (2) 2025.07.23
머신러닝 이론  (0) 2025.07.22

1. 서울 자전거 공유 수요 데이터셋

서울시의 공공자전거 대여 서비스인 따릉이 대여 수요를 예측하는 문제에 사용되는 데이터셋입니다. 특정 시간대와 날씨, 요일, 공휴일 여부, 기온, 습도  다양한 데이터를 활용하여 자전거 대여 수요를 예측합니다.

 

2. 데이터셋 컬럼

  • Date : 연월일
  • Rented Bike count - 매 시간마다 대여한 자전거 수
  • Hour - 하루 중 시간
  • Temperature - 온도
  • Humidity - 습도 %
  • Windspeed - 풍속 m/s
  • Visibility - 가시거리 m
  • Dew point temperature - 이슬점 온도
  • Solar radiation - 태양 복사 MJ/m2
  • Rainfall - 강우량 mm
  • Snowfall - 적설량 cm
  • Seasons - 겨울, 봄, 여름, 가을
  • Holiday - 휴일/휴일 없음
  • Functional Day - 운영되지 않았던 , 정상적으로 운영된 

3. 데이터 전처리 및 탐색적 데이터 분석 (EDA)

데이터를 분석하거나 모델링하기 전에 전반적인 특징을 파악하고 이상치나 패턴, 분포 등을 시각화나 통계로 살펴보는 과정

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

bike_df = pd.read_csv('/본인의 구글드라이브 경로/SeoulBikeData.csv', encoding='CP949')
bike_df

 

※ CP949

  • Microsoft Windows의 한국어 문자 인코딩입니다.
  • EUC-KR을 확장한 형태로, 더 많은 한국어 문자(한자, 확장 문자 등)를 지원합니다.
  • 주로 Windows 환경에서 저장된 한글 파일에서 사용됩니다.
bike_df.info()
bike_df.describe()
bike_df.columns

# 시계열 데이터를 가지고 미래의 데이터를 삽입 후 얼만큼 대여될 것인지 예측해보기
bike_df.columns = ['Date', 'Rented Bike Count', 'Hour', 'Temperature', 'Humidity',
       'Wind speed', 'Visibility', 'Dew point temperature',
       'Solar Radiation', 'Rainfall', 'Snowfall', 'Seasons',
       'Holiday', 'Functioning Day']

bike_df.head()
sns.scatterplot(x='Temperature', y='Rented Bike Count', data=bike_df, alpha=0.3)

sns.scatterplot(x='Wind speed', y='Rented Bike Count', data=bike_df, alpha=0.3)

sns.scatterplot(x='Visibility', y='Rented Bike Count', data=bike_df, alpha=0.3)

sns.scatterplot(x='Hour', y='Rented Bike Count', data=bike_df, alpha=0.3)

bike_df.isna().sum()

 

bike_df.info()

# 날짜가 종속변수에 영향을 미칠 가능성이 있어서 데이터 타입을 바꿈
# 일/월/년도
bike_df['Date'] = pd.to_datetime(bike_df['Date'], format='%d/%m/%Y')
bike_df.info()

# 파생변수 년/월/일 별로 뽑기
bike_df['year'] = bike_df['Date'].dt.year
bike_df['month'] = bike_df['Date'].dt.month
bike_df['day'] = bike_df['Date'].dt.day
bike_df.head()
plt.figure(figsize=(14, 4))
sns.lineplot(x='Date', y='Rented Bike Count', data=bike_df)
plt.xticks(rotation=45)
plt.show()

# 년도별로 월로 groupby해서 묶기
bike_df[bike_df['year'] == 2017].groupby('month')['Rented Bike Count'].mean()

bike_df[bike_df['year'] == 2018].groupby('month')['Rented Bike Count'].mean()

# 하루 시간대별로 나눠서 대여수 뽑아보기
bike_df['TimeOfDay'] = pd.cut(bike_df['Hour'], 
                            bins=[0, 5, 11, 17, 23], 
                            labels=['Dawn', 'Morning', 'Afternoon', 'Evening'],
                            # 제일 처음 시작값은 포함 따라서 0시 포함
                            include_lowest=True)

 

※ pd.cut()

pd.cut()은 숫자 데이터를 구간(bins)으로 나누어 범주형 데이터로 변환하는 데 사용됩니다. 주로 연속형 데이터를 특정 범주로 분류할 때 활용됩니다.

  • bins: 숫자 데이터를 나눌 경계값(구간)입니다.
0 ≤ Hour ≤ 5 Dawn (새벽)
5 < Hour ≤ 11 Morning (아침)
11 < Hour ≤ 17 Afternoon (오후)
17 < Hour ≤ 23 Evening (저녁)
  • 주의: bins의 경계값은 오른쪽 경계값(])을 포함합니다.
bike_df.head()
sns.barplot(x='Functioning Day', y='Rented Bike Count', data=bike_df)

# 검정색 바 : 신뢰구간
# 평균값이 얼만큼 예상되는지 예측하는 신뢰구간

※ barplot의 bar의 역할

 

  • 신뢰구간(CI): 평균값이 속할 것으로 예상되는 값의 범위입니다.
  • 바 그래프에서 신뢰구간: 검은색 심지(Error Bar)로 나타납니다.
  • 신뢰구간이 좁다: 평균값에 대한 확신이 높다.
  • 신뢰구간이 넓다: 평균값에 대한 확신이 낮고 데이터가 흩어져 있다.

 

# 그래프로 비교하기 어려울 때, counts해서 비교하기
bike_df['Functioning Day'].value_counts()
bike_df[bike_df['Functioning Day'] == 'Yes']
# Yes 부분
# 8465 rows × 18 columns
bike_df[bike_df['Functioning Day'] == 'No']
# No 부분
# 295 rows × 18 columns
bike_df.info()

bike_df = bike_df.drop('Date', axis=1)
bike_df.head()

 

bike_df.select_dtypes(exclude=['number']).columns.tolist()
# ['Seasons', 'Holiday', 'Functioning Day', 'TimeOfDay']

 

for i in bike_df.select_dtypes(exclude=['number']).columns.tolist():
    print(i, bike_df[i].nunique())

# Seasons 4
# Holiday 2
# Functioning Day 2
# TimeOfDay 4

 

bike_df = pd.get_dummies(bike_df, columns=bike_df.select_dtypes(exclude=['number']).columns.tolist(),
                         # 컬럼을 하나 아낄 수 있음
                         # ex. RGB : Red Green Blue 을 세 개의 컬럼으로 들어갈 것임
                         # 근데 만약 drop_first = True를 하게되면 Red 컬럼을 삭제해도 두 컬럼으로 충분히 구분지을 수 있다.
                         drop_first=True)
bike_df.head()

 

# 모든 컬럼 간 상관관계 분석
correlation_matrix = bike_df.corr()

# 목표 변수와의 상관관계만 확인
target_corr = correlation_matrix['Rented Bike Count'].sort_values(ascending=False)
print(target_corr)

종속변수와 독립변수간의 상관관

 

※ corr() 함수

corr() 함수는 데이터프레임의 숫자형 열 간의 상관관계를 계산하는 데 사용됩니다. 상관관계는 두 변수 간의 선형 관계를 나타내며, 주로 -1에서 1 사이의 값으로 표현됩니다.

  • corr()는 Pearson 상관계수를 기본으로 사용합니다.
  • 숫자형 열만 상관관계 분석에 포함됩니다.
  • 높은 상관관계(>|0.5|): 강한 관계
  • 낮은 상관관계(<|0.2|): 약한 관계

corr()를 사용하여 높은 상관관계를 가진 컬럼을 식별하고 제거할지 여부를 판단할 수 있습니다. 특히, 다중공선성(multicollinearity) 문제가 발생할 경우 머신러닝 모델의 성능이 저하될 수 있으므로, 상관관계가 높은 컬럼을 적절히 제거하는 것이 중요합니다.

 

※ 다중공선성

다중공선성(Multicollinearity)은 회귀 분석에서 독립 변수들(설명 변수) 간에 강한 상관관계가 존재하는 현상을 의미합니다. 이러한 상관관계가 높으면 각 독립 변수가 종속 변수에 미치는 개별적인 영향을 정확하게 추정하기 어려워지며, 회귀 계수의 추정치가 불안정해져 작은 데이터 변화에도 크게 변할 수 있습니다. 이는 모델의 예측 성능 저하와 해석의 신뢰성 감소로 이어질 수 있으므로, 다중공선성이 높은 변수를 식별하고 제거하거나 조정하는 것이 중요합니다.

plt.figure(figsize=(16, 12))
sns.heatmap(correlation_matrix, annot=True, fmt='.2f', cmap='coolwarm')
plt.title('Feature Correlation Heatmap')
plt.show()

# 온도와 이슬점이 높은 다중공선성을 띄고있기 때문에, 이슬점 독립변수 하나 제거
bike_df = bike_df.drop(['Dew point temperature'], axis=1)
bike_df.head()
bike_df.info()

 

모델학습

# 모델 학습
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(bike_df.drop('Rented Bike Count', axis=1), bike_df['Rented Bike Count'], test_size=0.3, random_state=2025)

 

X_train.shape, y_train.shape
# ((6132, 19), (6132,))
X_test.shape, y_test.shape
# ((2628, 19), (2628,))

 

 

4. 결정 트리

결정 트리(Decision Tree)는 데이터를 기반으로 의사결정을 수행하는 트리 구조의 예측 모델입니다. 루트 노드(root node)에서 시작해 각 노드는 특정 특성(feature)의 조건에 따라 가지(branch)로 분기되며, 최종적으로 리프 노드(leaf node)에 도달해 예측 결과(클래스나 값)를 도출합니다. 주로 분류(Classification)와 회귀(Regression) 문제에 사용되며, 데이터의 패턴을 직관적으로 시각화할 수 있어 해석이 용이합니다. 하지만 트리가 너무 깊어지면 과적합(overfitting) 문제가 발생할 수 있으므로 가지치기(pruning)나 최대 깊이 설정 등으로 제어해야 합니다.

  • 전체 데이터셋을 하나의 노드로 시작합니다.
  • 최적의 특성(feature)과 분할 기준(threshold)을 찾아 첫 번째 분할을 수행합니다.
  • 분류 (Classification):
    • Gini 불순도(Gini Impurity)
    • 엔트로피(Entropy)
  • 회귀 (Regression):
    • 평균 제곱 오차(Mean Squared Error, MSE)
    • 절대 평균 오차(Mean Absolute Error, MAE)
  • 각 하위 노드에 대해 위 단계를 반복합니다.
  • 이 과정을 통해 트리는 여러 깊이로 성장합니다.
  • 모든 노드가 더 이상 나눌 수 없거나 특정 조건(max_depth, min_samples_split)을 만족할 때까지 반복됩니다.
  • 더 이상 분할이 불가능할 때 리프 노드가 생성됩니다.
  • 분류 문제: 가장 많은 클래스가 있는 클래스를 예측값으로 사용
  • 회귀 문제: 평균값을 예측값으로 사용

※ Gini 불순도 (Gini Impurity)

  • Gini 불순도는 한 노드에 있는 데이터의 순수도(Purity)를 측정하는 지표입니다.
  • 한 노드에 있는 샘플들이 동일한 클래스에 속할 확률이 높을수록 Gini 불순도는 낮아집니다.
  • 즉, 노드가 "얼마나 섞여 있는지"를 나타냅니다.

 엔트로피 (Entropy)

  • 엔트로피는 정보의 불확실성(혼란도, Uncertainty)을 측정합니다.
  • 엔트로피가 높을수록 해당 노드에 있는 데이터는 더 섞여 있으며, 예측하기 어렵습니다.
  • 엔트로피는 데이터가 균등하게 분포될 때 최대값을 가집니다.
from sklearn.tree import DecisionTreeRegressor

dtr = DecisionTreeRegressor(random_state=2025)
dtr.fit(X_train, y_train)
pred1 = dtr.predict(X_test)

sns.scatterplot(x=y_test, y=pred1)

 

 

※ DecisionTreeRegressor

DecisionTreeRegressor는 주어진 데이터를 반복적으로 분할하여 예측을 수행합니다. 각 분할은 데이터의 목표 변수 값을 예측하는 데 가장 적합한 값을 찾기 위해 이루어집니다. 이를 통해 데이터를 점차 더 작은 부분으로 나누고, 각 부분에서 평균값을 예측값으로 사용하는 방식입니다. DecisionTreeRegressor  데이터를 두 가지 그룹으로 분할합니다. 각 분할에서 목표는 두 그룹의 MSE가 가능한 한 낮도록 만드는 것입니다. 즉, 각 분할에서의 MSE가 최소화되도록 분할점을 찾습니다.

# DecisionTree에 대한 RMSE
from sklearn.metrics import root_mean_squared_error

root_mean_squared_error(y_test, pred1)
# 313.7826116872321
# 선형회귀로 다시 한번 풀어보기
from sklearn.linear_model import LinearRegression

lr = LinearRegression()
lr.fit(X_train, y_train)
pred2 = lr.predict(X_test)

sns.scatterplot(x=y_test, y=pred2)
# 선형 모델 버전
root_mean_squared_error(y_test, pred2)
# 420.7921510115953

 

# 하이퍼 파라미터 적용
dtr = DecisionTreeRegressor(random_state=2025, max_depth=50, min_samples_leaf=30)
dtr.fit(X_train, y_train)
pred3 = dtr.predict(X_test)

root_mean_squared_error(y_test, pred3)
# 293.44393572577195
# 결정 나무 : 313.7826116872321
# 선형 회귀 : 420.7921510115953
# 하이퍼 파라미터 튜닝 : 293.44393572577195
from sklearn.tree import plot_tree

plt.figure(figsize=(24, 12))
plot_tree(dtr, max_depth=5, fontsize=10, feature_names=X_train.columns)
plt.show()

 

 

from sklearn.ensemble import RandomForestRegressor

rf = RandomForestRegressor(random_state=2025)
rf.fit(X_train, y_train)
pred4 = rf.predict(X_test)
root_mean_squared_error(y_test, pred4)

# 랜덤 포레스트 모델 적용 : 234.43573060707698
rf.feature_importances_
feature_imp = pd.DataFrame({
    'features': X_train.columns,
    'importances': rf.feature_importances_
})

feature_imp
top10 = feature_imp.sort_values('importances', ascending=False).head(10)
top10

plt.figure(figsize=(5, 10))
sns.barplot(x='importances', y='features', data=top10)

'AI > ML' 카테고리의 다른 글

슈퍼스토어 마케팅 캠페인 데이터셋  (0) 2025.07.24
호텔 예약 수요 데이터셋  (1) 2025.07.24
주택 임대료 예측 데이터셋  (1) 2025.07.23
Scikit-Learn  (2) 2025.07.23
머신러닝 이론  (0) 2025.07.22

1. 주택 임대료 예측 데이터셋

House Rent Prediction Dataset은 주택 임대료를 예측하기 위한 목적으로 사용되는 데이터셋입니다. 이 데이터셋은 주로 머신러닝 및 데이터 분석 프로젝트에서 사용되며, 주택의 다양한 특성과 위치 정보를 기반으로 임대료를 예측하는 모델을 학습하는 데 활용됩니다.

 

2. 데이터셋 컬럼

  • BHK: 주택에 포함된 침실, 거실, 주방의 총 개수를 의미합니다.
  • Rent: 주택(아파트/플랫)의 월 임대료를 나타냅니다.
  • Size: 주택(아파트/플랫)의 면적을 평방피트(Square Feet)로 나타냅니다.
  • Floor: 주택이 위치한 층수와 건물의 총 층수를 나타냅니다. (예: 2층 중 1층, 5층 중 3층 등)
  • Area Type: 주택의 면적이 어떤 방식으로 계산되었는지를 나타냅니다. (예: 전체 면적, 실사용 면적, 건축 면적 등)
  • Area Locality: 주택(아파트/플랫)이 위치한 구체적인 지역이나 동네 정보를 나타냅니다.
  • City: 주택(아파트/플랫)이 위치한 도시를 나타냅니다.
  • Furnishing Status: 주택이 가구가 완비되었는지(Furnished), 부분적으로 갖추어졌는지(Semi-Furnished), 아니면 비어 있는지(Unfurnished)를 나타냅니다.
  • Tenant Preferred: 집주인 또는 중개인이 선호하는 임차인 유형을 나타냅니다. (예: 가족, 싱글, 직장인 등)
  • Bathroom: 주택에 있는 욕실의 개수를 나타냅니다.
  • Point of Contact: 주택(아파트/플랫)에 대한 추가 정보를 얻기 위해 연락해야 할 담당자나 중개인의 정보를 나타냅니다.

 

3. 데이터셋 전처리

import numpy as np
import pandas as pd
import seaborn as sns

rent_df = pd.read_csv('/본인의 드라이브 경로/House_Rent_Dataset.csv')
rent_df

 

rent_df.info()
rent_df.describe()
4.746000e+03
# 소수점 없이 데이터 개수 보기
round(rent_df.describe(), 2)
# 방의 개수
rent_df['BHK']
sns.displot(rent_df['BHK'])

sns.displot(rent_df['Rent'])

# 얇다 ? = 데이터가 개별적으로 나눠져있다. = 편차가 크다

rent_df['Rent'].sort_values()
sns.displot(rent_df['Size'])

 

boxplot

Boxplot은 데이터의 중앙값, 사분위수, 이상치 등을 시각적으로 표현하는 통계 그래프입니다. 주로 데이터 분포와 이상치를 빠르게 파악하기 위해 사용됩니다.

1. 중앙값 (Median, Q2): 데이터를 크기 순으로 정렬했을 때 중간에 위치한 값

2. Q1 (제1사분위수, 25%): 하위 25%에 해당하는 값

3. Q3 (제3사분위수, 75%): 상위 25%에 해당하는 값

4. IQR (Interquartile Range, 사분위 범위): Q3 - Q1, IQR은 데이터의 중간 50% 범위를 의미합니다.

5. Minimum: Q1 − 1.5 × IQR 이하에 속하지 않는 가장 작은 값

6. Maximum: Q3 + 1.5 × IQR 이하에 속하지 않는 가장 큰 값

7. 이상치: 일반적인 데이터 분포를 벗어난 값(Lower Bound=Q11.5×IQR, Upper Bound=Q3+1.5×IQR)

( IQR 기준으로 이상치를 정의하기 때문에 모든 상황에 완벽하지 않을 수 있습니다)

sns.boxplot(rent_df['Rent'])

sns.boxplot(rent_df['Size'])
# 현실적으로 범위 밖에 많이 벗어나고 띄엄띄엄 있는 경우, 이상치로 볼 확률이 높음

sns.boxplot(rent_df['BHK'])

rent_df.isna().sum()
rent_df.isna().mean()
rent_df.info()
# ex. 성별, 주민번호  --> 원-핫 인코딩
# 문자를 숫자화 시키는 것 --> 라벨 인코딩
rent_dfrent_df['Area Type'].unique()
# 카테고리 종류
# array(['Super Area', 'Carpet Area', 'Built Area'], dtype=object)

 

rent_df['Area Type'].nunique()
# 카테고리 종류 개수

 

# 데이터 타입이 object인 것을 반복문 돌려 카테고리 개수 알아보기
for i in ['Floor', 'Area Type', 'Area Locality', 'City', 'Furnishing Status', 'Tenant Preferred', 'Point of Contact']:
    print(i, rent_df[i].nunique())
# 개수가 너무 많은건 drop 시키기
rent_df.drop(['Floor', 'Area Locality', 'Posted On'], axis=1, inplace=True)
# 원-핫 인코딩
rent_df = pd.get_dummies(rent_df, columns=['Area Type', 'City', 'Furnishing Status', 'Tenant Preferred', 'Point of Contact'])
rent_df.head()

원-핫 인코딩

X = rent_df.drop('Rent', axis=1) # 독립변수
y = rent_df['Rent'] # 종속변수
X.head()
y

 

학습시작

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=2025)
X_train.shape, X_test.shape
# ((3322, 21), (1424, 21))
y_train.shape, y_test.shape
# ((3322,), (1424,))

 

 

4. 알고리즘으로 모델링

※ 사이킷런의 선형 회귀 학습 방법

사이킷런의 LinearRegression은 최소 제곱법(Ordinary Least Squares, OLS)을 기반으로 학습하며, 입력 데이터와 실제 목표값 사이의 잔차(Residual)의 제곱합을 최소화하는 방식으로 최적의 가중치(Weight)와 절편(Bias)를 구합니다. 내부적으로는 수치적으로 더 안정적인 특이값 분해(Singular Value Decomposition, SVD)를 사용하여 계산됩니다. 이 방식은 데이터셋이 비교적 작고 특성 수가 적당할 때 효율적입니다.

 

※ 최소 제곱법

최소 제곱법(Least Squares Method)은 주어진 데이터 포인트들과 예측 모델(주로 직선) 사이의 오차(Residuals)의 제곱합(Sum of Squared Errors, SSE)을 최소화하여 최적의 예측 모델을 찾아내는 통계적 방법입니다. 이 방법은 선형 회귀 분석에서 가장 널리 사용되며, 데이터 포인트들이 회귀선(Regression Line)에 최대한 가깝도록 조정합니다. 수학적으로는 오차의 제곱합을 최소화하는 기울기(w)와 절편(b)을 계산하여 모델을 최적화합니다.

 

※ 닫힌 해(Closed-form Solution)

 

from sklearn.linear_model import LinearRegression

lr = LinearRegression()
lr.fit(X_train, y_train)
pred = lr.predict(X_test)
pred

# array([168427.98865322,  37550.57051365,  46227.94809703, ...,
#         5359.0119441 ,  55103.27974897, -13749.95956338])
# 예측은 정확도로 낼 수 없음.
# MSE , RMSE 로 평가지표 사용한다.
from sklearn.metrics import mean_squared_error, root_mean_squared_error

# 실제값과 예측값의 잔차 제곱의 평균
print(mean_squared_error(y_test, pred))
# 1845945611.7086728

# 실제값과 예측값의 잔차 제곱의 평균의 제곱근
print(root_mean_squared_error(y_test, pred))
# 42964.46917755034
# 렌트비의 가장 큰 값  --> 이상치로 판단해서 지워보기
X_train.loc[1837]
y_train.loc[1837]
# np.int64(3500000)
# 아웃라이어로 생각되는 데이터를 삭제
X_train.drop(1837, inplace=True)
y_train.drop(1837, inplace=True)
lr = LinearRegression()
lr.fit(X_train, y_train)
new_pred = lr.predict(X_test)
root_mean_squared_error(y_test, new_pred)
# 42987.37959096641

# 이상치를 지우지 않았을 때
# 실제값과 예측값의 잔차 제곱의 평균의 제곱근
# print(root_mean_squared_error(y_test, pred))
# 42964.46917755034

# 따라서 1837를 삭제하기 전이 더 좋다.

 

 

5. 로그 변환으로 RMSE 개선

주택 임대료 데이터셋은 오른쪽으로 치우친 분포를 가지고 있습니다. 값이 큰 임대료(Outliers)가 평균과 모델 예측 결과에 큰 영향을 미치기 때문에 로그 변환을 통해 값의 범위를 축소하고, 분포를 정규 분포(Normal Distribution)에 가깝게 만듭니다. 로그 변환은 극단적으로 높은 값의 영향을 줄여주기 때문에 모델이 이상치에 덜 민감하게 반응하고 RMSE가 감소할 수 있습니다.

 

※ 정규 분포

정규 분포(Normal Distribution)는 데이터가 평균을 중심으로 좌우 대칭을 이루며 종 모양(Bell Curve)으로 퍼져 있는 통계적 분포입니다. 대부분의 값은 평균 근처에 몰려 있고, 평균에서 멀어질수록 값의 빈도가 급격히 감소합니다. 이는 자연현상, 시험 점수, 사람들의 키와 같은 많은 실제 데이터에서 흔하게 나타납니다.

 

※ 데이터 변환의 개념

원본 데이터: 실제 관측된 값 그대로입니다. (예: 임대료 1,000원, 10,000원, 100,000원)

로그 변환된 데이터: 데이터의 **비율(비율적 차이)**에 초점을 맞추어 변환된 값입니다. (예: log(1,000) → 3, log(10,000) →  4, log(100,000)  5)

  • 데이터의 '값'은 변하지만, '관계'는 변하지 않습니다.
  • 모델 학습은 변환된 데이터로 진행하지만, 최종 예측값은 원래 스케일로 되돌립니다.
  • 변환된 데이터는 이상치를 줄이고, 정규 분포에 가깝게 만들어 모델 성능을 개선합니다.
y_train = np.log1p(y_train)
y_test = np.log1p(y_test)

lr = LinearRegression()
lr.fit(X_train, y_train)
y_pred_log = lr.predict(X_test)

# 로그 예측값을 원래 값으로 변환
log_pred = np.expm1(y_pred_log)
y_test_original = np.expm1(y_test)
root_mean_squared_error(y_test_original, log_pred)
# 33187.45360971534

# log값 적용 전 RMSE : 42964.46917755034
# log값 적용 후 RMSE : 33187.45360971534
42964.46917755034 - 33187.45360971534
# 9777.015567834998

 

 

6. 앙상블 모델 적용

앙상블 모델(Ensemble Model)은 여러 개의 머신러닝 모델을 조합하여 하나의 강력한 예측 모델을 만드는 방법입니다. 각 개별 모델(약한 학습기, Weak Learner)이 가진 장점을 결합하고 약점을 보완함으로써 예측 정확도와 안정성을 향상시킵니다. 대표적인 앙상블 기법으로는 배깅(Bagging), 부스팅(Boosting), 스태킹(Stacking)이 있으며, 랜덤 포레스트(Random Forest)와 XGBoost는 각각 배깅과 부스팅을 대표하는 알고리즘입니다. 앙상블 모델은 특히 복잡한 문제나 다양한 패턴이 존재하는 데이터셋에서 뛰어난 성능을 발휘합니다.

 

※ 랜덤 포레스트

랜덤 포레스트(Random Forest)는 다수의 결정 트리(Decision Tree)를 결합해 예측을 수행하는 앙상블 학습 방법입니다. 각각의 트리는 무작위로 선택된 데이터 샘플과 특성(feature)을 사용해 학습되며, 분류 문제에서는 다수결 투표, 회귀 문제에서는 평균을 통해 최종 예측값을 도출합니다. 이 방식은 과적합(overfitting) 위험을 줄이고 안정적인 성능을 보장하며, 비선형 관계를 잘 포착하고 이상치(outlier)에 강인한 특성을 가지고 있습니다. 또한, 변수 중요도(Feature Importance)를 제공해 어떤 특성이 예측에 중요한 역할을 하는지 이해할 수 있습니다.

 

※ XGBoost

XGBoost (eXtreme Gradient Boosting)는 그레디언트 부스팅(Gradient Boosting) 알고리즘을 기반으로 한 강력한 머신러닝 앙상블 모델입니다. 여러 개의 약한 학습기(Weak Learner), 주로 결정 트리(Decision Tree)를 순차적으로 학습시키며, 이전 트리의 오차를 보정해 예측 성능을 점진적으로 개선합니다. 정확도, 속도, 과적합 방지 측면에서 뛰어난 성능을 자랑하며, 결측치 처리, 과적합 제어, 병렬 학습 등의 기능을 지원합니다. 주로 복잡한 패턴을 학습해야 하는 대규모 데이터셋이나 비선형 데이터 문제에서 뛰어난 성능을 보입니다.

from sklearn.ensemble import RandomForestRegressor
from xgboost import XGBRegressor

models = {
    # 모델에 넣는 괄호안에 넣는 파라미터는 하이퍼파라미터라 부른다.
    # 하이퍼파라미터 : 모델의 성능을 튜닝하기 위해 넣는 파라미터
    'Linear Regression': LinearRegression(),
    'Random Forest': RandomForestRegressor(n_estimators=100, random_state=2025),
    'XGBoost': XGBRegressor(n_estimators=100, random_state=2025)
}

# 모델 학습 및 평가
results = {}
for model_name, model in models.items():
    model.fit(X_train, y_train)
    y_pred_log = model.predict(X_test)
    
    # 로그 변환을 원래 값으로 복구
    y_pred = np.expm1(y_pred_log)
    y_test_original = np.expm1(y_test)
    
    # RMSE 계산
    rmse = np.sqrt(mean_squared_error(y_test_original, y_pred))
    results[model_name] = rmse
    print(f'{model_name} RMSE: {rmse:.2f}')
    
# Linear Regression RMSE: 42964.47
# Random Forest RMSE: 39874.69
# XGBoost RMSE: 35807.66

# 최적 모델 확인
best_model = min(results, key=results.get)
print(f'Best Model: {best_model} RMSE: {results[best_model]:.2f}')

# Best Model: XGBoost RMSE: 35807.66

 

'AI > ML' 카테고리의 다른 글

슈퍼스토어 마케팅 캠페인 데이터셋  (0) 2025.07.24
호텔 예약 수요 데이터셋  (1) 2025.07.24
서울 자전거 공유 수요 예측 데이터셋  (3) 2025.07.23
Scikit-Learn  (2) 2025.07.23
머신러닝 이론  (0) 2025.07.22

1. 사이킷런

사이킷런(scikit-learn)은 파이썬(Python)으로 작성된 오픈소스 머신러닝 라이브러리로, 데이터 분석과 예측 모델 구축을 위해 널리 사용됩니다. 간단하고 일관된 인터페이스를 제공하며, 지도 학습(Supervised Learning)과 비지도 학습(Unsupervised Learning) 알고리즘을 모두 지원합니다. 주로 분류(Classification), 회귀(Regression), 클러스터링(Clustering), 차원 축소(Dimensionality Reduction), 모델 선택(Model Selection), 전처리(Preprocessing)와 같은 다양한 작업을 수행할 수 있습니다. 사이킷런은 효율적인 수치 계산이 가능하며, 다양한 머신러닝 알고리즘을 손쉽게 사용할 수 있는 API를 제공합니다. 따라서 사이킷런은 데이터 과학과 인공지능 프로젝트에서 가장 많이 사용되는 라이브러리 중 하나입니다.

https://scikit-learn.org/stable/

 

2. Iris 데이터셋

아이리스(Iris) 데이터셋은 머신러닝과 통계학에서 가장 널리 사용되는 대표적인 샘플 데이터셋입니다. 이 데이터셋은 붓꽃(Iris)의 세 가지 품종(Setosa, Versicolor, Virginica)에 대한 정보를 포함하고 있습니다. 각 품종별로 꽃받침(Sepal)의 길이와 너비, 꽃잎(Petal)의 길이와 너비로 이루어진 4개의 특성(Features)이 제공되며, 총 150개의 샘플 데이터가 있습니다. 각 품종당 50개의 샘플이 균등하게 분포되어 있어 다중 클래스 분류 문제를 연습하기에 적합합니다.

 

데이터셋

데이터셋(Dataset)은 머신러닝과 데이터 과학에서 모델을 학습, 검증, 테스트하기 위해 사용되는 데이터의 집합입니다. 데이터셋은 일반적으로 입력 데이터(Features)와 정답 레이블(Labels)로 구성되며, 학습용 데이터셋(Training Dataset), 검증용 데이터셋(Validation Dataset), 테스트용 데이터셋(Test Dataset)으로 나누어 사용합니다. 또한 모델을 학습시키고, 하이퍼파라미터를 조정하며, 최종 성능을 평가하는 데 사용됩니다. 데이터셋의 품질과 크기는 모델의 성능에 큰 영향을 미치기 때문에, 적절한 전처리(Preprocessing)와 특성 엔지니어링(Feature Engineering)이 중요합니다.

from sklearn.datasets import load_iris

iris = load_iris()
iris
# sepal length in cm: 꽃받침의 길이
# sepal width in cm: 꽃받침의 너비
# petal length in cm: 꽃잎의 길이
# petal width in cm: 꽃잎의 너비
print(iris['DESCR'])
data = iris['data']
data
feature_names = iris['feature_names']
feature_names
import pandas as pd

df_iris = pd.DataFrame(data, columns=feature_names)
df_iris
target = iris['target']
target
target.shape
df_iris['target']  = target
df_iris

# 지도 학습

from sklearn.model_selection import train_test_split

# 순서 지켜서 리턴해야함
# 문제를 독립변수 , 정답을 종속변수
# X_train : 독립변수 / X_test : 독립변수이면서 test용
# y_train : 종속변수이면서 학습용 / y_train : 종속변수이면서 답안지
# 벡터가 하나짜리면 소문자 , 그 이상은 대문자를 쓰는게 관례임

# 첫번째는 독립변수, 두번째는 종속변수
# 세번째는 테스트 사이즈(20%) , 마지막은 데이터 섞임을 고정시켜주는 값
X_train, X_test, y_train, y_test = train_test_split(df_iris.drop('target',axis=1),
                                                    df_iris['target'],
                                                    test_size=0.2,
                                                    random_state=2025, shuffle=True)
# 원래 shuffle = True 가 기본값
X_train.shape, X_test.shape
# ((120, 4), (30, 4))
y_train.shape, y_test.shape
# ((120,), (30,))
X_train

y_train

from sklearn.svm import SVC     # 모델 선정 -> 서포트 벡터 머신
from sklearn.metrics import accuracy_score      # 정확도 측정

 

3. 모델 선정

SVC

SVC(Support Vector Classifier)는 서포트 벡터 머신(SVM, Support Vector Machine)을 사용한 분류(Classification) 알고리즘입니다. 사이킷런(sklearn.svm.SVC)에서 제공되며, 이진 분류(Binary Classification)와 다중 클래스 분류(Multi-Class Classification) 문제를 해결할 수 있습니다.

 

서포트 벡터 머신(Support Vector Machine, SVM)

서포트 벡터 머신(SVM)은 두 개 이상의 클래스(Class)를 구분하는 지도 학습(Supervised Learning) 알고리즘입니다. 주로 분류(Classification) 문제를 해결하는 데 사용되며, 일부 경우 회귀(Regression) 문제에도 사용됩니다. SVM의 목표는 두 클래스 간의 경계를 가장 잘 구분하는 최적의 초평면(Hyperplane)을 찾는 것입니다.

 

# 객체 생성
svc = SVC()
# fit : 학습 메소드 안에 문제와 정답을 넣음
svc.fit(X_train, y_train) # 전체 배치 학습을 사용
y_pred = svc.predict(X_test)
y_pred

# array([0, 2, 2, 2, 0, 2, 0, 1, 2, 0, 2, 2, 0, 2, 0, 0, 0, 0, 1, 2, 0, 1,
#       0, 0, 0, 1, 0, 2, 2, 2])

print('정답률', accuracy_score(y_test, y_pred))

# 정답률 0.9666666666666667

 

accuracy_score

accuracy_score는 사이킷런(sklearn)의 metrics 모듈에서 제공하는 성능 평가 지표로, 분류(Classification) 모델의 예측 정확도(Accuracy)를 측정하는 함수입니다. 이 함수는 모델이 예측한 값과 실제 정답이 얼마나 일치하는지를 백분율로 나타내며, 전체 샘플 중 올바르게 예측된 샘플의 비율을 계산합니다.

 

Accuracy

정확도(Accuracy)는 머신러닝과 통계학에서 모델의 성능을 평가하는 가장 기본적인 지표 중 하나로, 전체 예측 중에서 얼마나 많은 예측이 실제 정답과 일치했는지를 나타내는 비율입니다.

 

 

y_pred = svc.predict(pd.DataFrame([[6.2, 2.1, 4.1, 1.5]], columns=['sepal length (cm)',	'sepal width (cm)',	'petal length (cm)', 'petal width (cm)']))
y_pred

'AI > ML' 카테고리의 다른 글

슈퍼스토어 마케팅 캠페인 데이터셋  (0) 2025.07.24
호텔 예약 수요 데이터셋  (1) 2025.07.24
서울 자전거 공유 수요 예측 데이터셋  (3) 2025.07.23
주택 임대료 예측 데이터셋  (1) 2025.07.23
머신러닝 이론  (0) 2025.07.22

1. 인공지능

인공지능(AI, Artificial Intelligence)은 컴퓨터나 기계가 인간처럼 생각하고 학습하며 문제를 해결하는 능력을 갖추도록 만드는 기술입니다. AI는 컴퓨터 과학의 한 분야로, 데이터를 활용해 의사결정을 내리거나 예측하는 시스템을 개발하는 것을 목표로 합니다.

 

1. 규칙 기반 알고리즘

Rule-based algorithms(규칙 기반 알고리즘)은 명시적으로 정의된 규칙(If-Then-Else 문법 등)을 사용하여 특정 문제를 해결하거나 작업을 수행하는 알고리즘입니다. 이러한 알고리즘은 사람이 직접 작성한 논리와 조건에 따라 작동하며, 데이터를 학습하지 않고도 결과를 도출할 수 있습니다.

 

2. 머신러닝

머신러닝(Machine Learning)은 인공지능(AI)의 한 분야로, 컴퓨터가 명시적으로 프로그래밍되지 않아도 데이터에서 패턴을 학습하고, 이를 기반으로 새로운 데이터를 예측하거나 결정을 내리는 기술입니다. 머신러닝은 AI의 핵심 기술로, 우리가 사용하는 많은 기술과 서비스의 기초가 됩니다.

 

3. 딥러닝

딥러닝(Deep Learning)은 머신러닝의 한 분야로, 사람의 뇌에서 영감을 받은 인공신경망(Artificial Neural Networks)을 사용하여 데이터를 학습하고 복잡한 문제를 해결하는 기술입니다. 특히, 딥러닝은 대량의 데이터와 고성능 컴퓨팅 자원을 활용하여 뛰어난 성능을 발휘하며, 이미지, 음성, 자연어 처리 등에서 주로 사용됩니다.

 

 

 

2. 머신러닝을 먼저 공부해야 하는 이유

1. 기초 개념 없이 딥러닝은 어렵다

딥러닝은 머신러닝의 하위 분야로, 기본적인 개념(예: 과적합, 분산과 편향, 학습/검증/테스트 분리, 평가 지표 등)을 머신러닝에서 먼저 익히지 않으면 딥러닝 모델의 작동 원리나 결과를 해석하기 어렵습니다.

 

2. 작고 단순한 문제에는 머신러닝이 더 효과적

모든 문제에 딥러닝이 필요한 것은 아닙니다. 예를 들어, 고객 이탈 예측이나 단순한 이진 분류 문제에서는 로지스틱 회귀나 결정 트리 같은 머신러닝 모델이 빠르고 정확하며, 데이터도 적게 필요합니다.

 

 

3. 머신러닝으로 할 수 있는 일

분류 (Classification) - 스팸 메일 분류
- 암 진단 (양성/악성)
- 고객 이탈 예측- 고장 여부 판단
회귀 (Regression) - 주택 가격 예측
- 주가 예측
- 광고 클릭률 예측- 날씨 온도 예측
군집화 (Clustering) - 고객 세그먼트 분류
- 상품 자동 그룹화
- 이상 거래 탐지
- 문서 주제 군집화
추천 시스템 - 영화, 음악, 상품 추천
- 사용자 맞춤 콘텐츠 제공
자연어 처리 (NLP) - 문장 감정 분석
- 뉴스 기사 분류
- 챗봇 응답 생성
- 기계 번역
이미지 처리 (Computer Vision) - 얼굴 인식
- 객체 탐지
- 자율주행 자동차 인식
- X-ray 진단 보조
이상 탐지 (Anomaly Detection) - 금융 사기 탐지
- 네트워크 이상 징후 감지
- 공정 불량 탐지 (crack 탐지)
강화 학습 (Reinforcement Learning) - 게임 AI (알파고 등)
- 로봇 제어
- 스마트 팩토리 자동 제어
시계열 분석 - 수요 예측
- 재고 관리
- 에너지 사용량 예측
음성 인식 및 합성 - 음성 명령 인식
- AI 스피커
- 텍스트 음성 변환 (TTS)

AI 프로젝트 구성원

  • AI 프로젝트 매니저 (AI PM)
    프로젝트 일정, 인력, 예산 등 총괄 관리
  • AI 기획자 / 서비스 기획자
    고객 요구사항 분석, AI 활용 시나리오 설계
  • 데이터 분석가 (Data Analyst)
    데이터를 수집·가공하여 통계 분석, 시각화, 인사이트 도출 등 문제 해결에 필요한 분석 수행
  • 데이터 엔지니어 (Data Engineer)
    대규모 데이터 수집, 정제, 저장, 파이프라인 구축
  • 웹 크롤러 개발자
    웹 데이터 수집 자동화 (스크래핑 등)
  • 머신러닝 엔지니어 (ML Engineer)
    머신러닝 모델 설계, 학습, 최적화 및 배포
  • 딥러닝 엔지니어 (Deep Learning Engineer)
    인공신경망, CNN, RNN, Transformer 등 고도화된 모델 설계
  • AI 리서처 (AI Researcher)
    논문 기반의 신기술 연구 및 고도 알고리즘 개발
  • 데이터 사이언티스트 (Data Scientist)
    데이터 분석, 모델링, 통계 기반 인사이트 도출
  • MLOps 엔지니어
    머신러닝 모델의 배포, 모니터링, 자동화 운영 (DevOps + ML)
  • 백엔드 개발자
    AI 모델과 연동되는 서버 API 개발
  • 프론트엔드 개발자
    사용자와 상호작용하는 웹/모바일 UI 개발
  • AI 플랫폼 개발자
    모델 학습/관리용 플랫폼 구축 (예: AutoML, 파이프라인 툴)
  • 클라우드 엔지니어
    AWS, GCP, Azure 기반 AI 인프라 구축 및 운영
  • DevOps 엔지니어
    시스템 통합, 배포 자동화, 안정적 운영 지원
  • GPU/고성능 컴퓨팅 엔지니어
    대용량 연산을 위한 하드웨어/서버 환경 구성
  • QA 엔지니어 (테스터)
    AI 기능의 테스트 및 품질 보증
  • 보안 전문가
    개인정보 보호 및 AI 보안 이슈 대응

 

 

4. 머신러닝의 학습 방법

1. 지도학습(Supervised Learning)

- 입력 데이터와 해당 데이터의 정답(레이블)이 제공되는 학습 방식입니다.

- 주어진 입력에 대해 올바른 출력(레이블)을 예측하는 모델을 학습합니다.

 

2. 비지도학습(Unsupervised Learning)

- 입력 데이터에는 레이블(정답)이 없으며, 데이터 자체의 구조나 패턴을 학습합니다.

- 데이터 내에서 숨겨진 구조를 찾거나 그룹화를 수행합니다.

 

3. 클러스터링(Clustering)

- 데이터를 비슷한 그룹으로 묶습니다.

- 데이터를 더 작은 차원으로 변환하여 시각화하거나 연산 효율성을 높입니다.

 

4. 강화학습(Reinforcement Learning)

- 에이전트(Agent)가 환경(Environment)과 상호작용하며 보상(Reward)을 최대화하는 행동을 학습합니다.

 

5. 반지도학습(Semi-Supervised Learning)

- 데이터의 일부에만 레이블이 있고, 나머지는 레이블이 없는 상태에서 학습합니다.

- 레이블링된 데이터가 적을 때 유용합니다.

 

6. 자기 지도 학습(Self-Supervised Learning)

- 데이터에서 레이블 없이 일부 정보를 예측하도록 학습합니다.

- 데이터를 활용하여 자체적으로 레이블 생성합니다.

 

7. 온라인 학습(Online Learning)

- 데이터를 순차적으로 제공하며, 실시간으로 학습하는 방식입니다.

- 데이터가 점진적으로 들어오는 환경에 적합합니다.

 

8. 트랜스퍼 러닝(Transfer Learning)

- 사전 학습된 모델의 지식을 새로운 문제에 적용합니다.

- 학습 시간이 단축되며, 적은 데이터로 성능 향상을 할 수 있습니다.

 

※ 모델

AI에서 "모델"은 주어진 데이터를 학습하여 패턴과 규칙을 찾아내고, 새로운 데이터에 대해 예측이나 결정을 내리는 수학적 구조 또는 알고리즘입니다. 예를 들어, 사진 속 동물이 강아지인지 고양이인지 구분하거나, 다음에 올 단어를 예측하는 것이 AI 모델의 역할입니다. 모델은 주로 데이터와 수학적 함수의 조합으로 구성되며, 학습(Training) 과정을 통해 최적의 매개변수(Weights, Biases)를 찾아갑니다. 즉, 모델은 데이터를 보고 문제를 해결하는 AI의 "두뇌" 역할을 합니다.

 

※ 학습

AI에서 "학습"은 주어진 데이터로부터 패턴과 규칙을 찾아내어, 모델의 매개변수(가중치, 편향 등)를 최적화하는 과정입니다. 이 과정에서 모델은 입력 데이터와 정답(레이블)을 비교하여 오류(오차)를 계산하고, 이를 최소화하기 위해 역전파(Backpropagation)와 최적화 알고리즘을 사용해 매개변수를 반복적으로 조정합니다. 즉, 학습은 모델이 더 정확한 예측이나 결정을 내릴 수 있도록 스스로 개선하는 과정입니다.

 

 

5. 머신러닝 프로세스

1. 문제 정의

문제 정의 단계는 머신러닝 프로젝트의 방향을 결정짓는 핵심 과정입니다. 이 단계에서는 해결하고자 하는 문제의 유형을 분류, 회귀, 군집화 등으로 구체화하고, 예측할 대상(타깃)과 입력할 변수(피처)를 정의합니다. 또한, 비즈니스 목적에 따라 성과 지표(KPI)를 설정하고, 데이터의 확보 가능성과 도메인 특성, 제약사항 등을 함께 고려하여 전체적인 목표와 전략을 설계합니다. 이 과정이 명확해야 이후 단계에서도 일관성 있고 효과적인 모델을 개발할 수 있습니다.


2. 데이터 전처리

데이터 전처리는 수집된 원시 데이터를 머신러닝 모델이 학습할 수 있도록 정제하고 가공하는 과정입니다. 이 단계에서는 결측치 처리, 이상치 제거, 범주형 데이터 인코딩, 정규화 또는 표준화, 불필요한 피처 제거 등 다양한 작업이 이루어집니다. 데이터의 품질이 모델의 성능에 큰 영향을 미치기 때문에, 이 과정은 전체 머신러닝 프로세스에서 매우 중요한 단계입니다. 또한, 학습용과 검증용 데이터를 적절히 분리하여 모델이 과적합되지 않도록 준비합니다.


3. 학습

학습 단계에서는 전처리된 데이터를 기반으로 머신러닝 알고리즘을 적용하여 모델을 훈련시킵니다. 이 과정에서는 지도학습(예: 회귀, 분류) 또는 비지도학습(예: 군집화) 등의 방식으로 알고리즘을 선택하고, 하이퍼파라미터를 조정하면서 모델이 주어진 데이터를 잘 학습하도록 만듭니다. 반복적인 학습을 통해 모델은 입력과 출력 사이의 패턴을 파악하며, 이를 통해 새로운 데이터를 예측하거나 분류할 수 있는 능력을 갖추게 됩니다.


4. 모델 평가

모델 평가 단계에서는 학습된 모델의 성능을 검증용 데이터를 통해 측정하고, 실질적인 효과를 확인합니다. 이때 정확도, 정밀도, 재현율, F1 점수, RMSE 등 문제 유형에 맞는 평가 지표를 사용하며, 과적합 여부도 확인합니다. 평가 결과를 통해 모델이 실제 환경에서 얼마나 잘 작동할 수 있을지를 판단하며, 필요에 따라 다시 데이터 전처리나 학습 과정을 반복할 수 있습니다. 이 단계는 모델을 실제로 활용 가능한 수준으로 개선하는 데 중요한 역할을 합니다.

 

 

6. 머신러닝을 공부하기 위해 필요한 것들

  • 기초 수학
    • 선형대수: 벡터, 행렬
    • 통계·확률: 평균, 분산, 확률분포
    • 미분: 경사 하강법 이해에 필요
  • 프로그래밍 (Python)
    • 필수 라이브러리: NumPy, Pandas, Matplotlib, Scikit-learn
    • 실습은 주로 Jupyter Notebook 또는 Colab 사용
  • 데이터 전처리 능력
    • 결측치/이상치 처리
    • 범주형 인코딩, 정규화
    • 시각화를 통한 데이터 이해
  • 머신러닝 알고리즘 이해
    • 지도학습: 선형회귀, 로지스틱 회귀, 결정트리, 랜덤포레스트
    • 비지도학습: K-means, PCA 등
  • 실습 경험
    • Kaggle/Dacon 대회 참가
    • 오픈데이터 프로젝트 수행
    • 모델 성능 평가 및 개선 연습
  • 도메인 지식
    • 데이터를 해석하고 모델을 잘 적용하려면 산업별 배경지식이 중요
    • 예: 의료 AI는 의학 지식, 금융 모델은 회계·경제 지식 필요
  • 윤리와 법률
    • 개인정보 보호법, AI 윤리, 알고리즘 편향 등 고려 필수
    • 예: 얼굴 인식 시스템은 사생활 침해 이슈 발생 가능
  • AI 프로젝트 실무 경험
    • 데이터 수집~배포까지의 전체 흐름 이해 필요
    • 협업, 버전관리(Git), 모델 배포(Flask, FastAPI 등) 등 실전 역량
  • 클라우드 & 환경 세팅
    • Google Colab, AWS, GCP 등에서 실습 및 배포 경험이 도움이 됨
    • 대규모 학습이나 GPU 자원이 필요할 때 필수

'AI > ML' 카테고리의 다른 글

슈퍼스토어 마케팅 캠페인 데이터셋  (0) 2025.07.24
호텔 예약 수요 데이터셋  (1) 2025.07.24
서울 자전거 공유 수요 예측 데이터셋  (3) 2025.07.23
주택 임대료 예측 데이터셋  (1) 2025.07.23
Scikit-Learn  (2) 2025.07.23

+ Recent posts