1. Hotel 데이터셋
주제: 이 손님은 예약을 취소할까?
이번 데이터셋의 출처는 kaggle이다.
1-1. 데이터 분석
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
hotel_df = pd.read_csv('/content/drive/MyDrive/KDT/머신러닝과 딥러닝/data/hotel.csv')
# 요약 정보
hotel_df.info()
output>>
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 119390 entries, 0 to 119389
Data columns (total 32 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 hotel 119390 non-null object
1 is_canceled 119390 non-null int64
2 lead_time 119390 non-null int64
3 arrival_date_year 119390 non-null int64
4 arrival_date_month 119390 non-null object
5 arrival_date_week_number 119390 non-null int64
6 arrival_date_day_of_month 119390 non-null int64
7 stays_in_weekend_nights 119390 non-null int64
8 stays_in_week_nights 119390 non-null int64
9 adults 119390 non-null int64
10 children 119386 non-null float64
11 babies 119390 non-null int64
12 meal 119390 non-null object
13 country 118902 non-null object
14 distribution_channel 119390 non-null object
15 is_repeated_guest 119390 non-null int64
16 previous_cancellations 119390 non-null int64
17 previous_bookings_not_canceled 119390 non-null int64
18 reserved_room_type 119390 non-null object
19 assigned_room_type 119390 non-null object
20 booking_changes 119390 non-null int64
21 deposit_type 119390 non-null object
22 days_in_waiting_list 119390 non-null int64
23 customer_type 119390 non-null object
24 adr 119390 non-null float64
25 required_car_parking_spaces 119390 non-null int64
26 total_of_special_requests 119390 non-null int64
27 reservation_status_date 119390 non-null object
28 name 119390 non-null object
29 email 119390 non-null object
30 phone-number 119390 non-null object
31 credit_card 119390 non-null object
dtypes: float64(2), int64(16), object(14)
memory usage: 29.1+ MB
특정 호텔의 숙박 관련 데이터인 것 같다.
10만개 이상의 row와 32개의 column을 가지고 있다.
- hotel: 호텔 종류
- is_canceled: 취소 여부
- 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: 지역
- distribution_channel: 어떤 방식으로 예약했는지
- is_repeated_guest: 예약한적이 있는 고객인지
- previous_cancellations: 몇번 예약을 취소했었는지
- previous_bookings_not_canceled: 예약을 취소하지 않고 정상 숙박한 횟수
- reserved_room_type: 희망한 룸타입
- assigned_room_type: 실제 배정된 룸타입
- booking_changes: 예약 후 서비스가 몇번 변경되었는지
- deposit_type: 요금 납부 방식
- days_in_waiting_list: 예약을 위해 기다린 날짜
- customer_type: 고객 타입
- adr: 특정일에 높아지거나 낮아지는 가격
- required_car_parking_spaces: 주차공간을 요구했는지
- total_of_special_requests: 특별한 별도의 요청사항이 있는지
- reservation_status_date: 예약한 날짜
- name: 이름
- email: 이메일
- phone-number: 전화번호
- credit_card: 카드번호
column이 많은만큼 필요 없는 데이터도 있을 것이다.
reservation_status_date의 경우 숙박 예정일이 아니라 예약을 접수한 날짜이다.
lead_time과 arrival데이터가 reservation_status_date에 대한 정보를 포함하고 있기 때문에 지우도록 한다.
이름, 이메일, 휴대폰번호, 신용카드정보는 예약 취소 여부와 관련이 없기 때문에 지운다.
# 필요없는 column 제거
hotel_df.drop(['reservation_status_date', 'name', 'email', 'phone-number', 'credit_card'], axis=1, inplace=True)
# 수치 정보
hotel_df.describe()
output>>
lead_time의 max가 737이다. 737일 전에 예약을 했다는 의미이다. 이상치인지 의심되기 때문에 확인을 해봐야한다.
1-2. lead_time
# 데이터 시각화
sns.displot(hotel_df['lead_time'])
output>>
# 데이터 시각화
sns.boxplot(hotel_df['lead_time'])
output>>
600일 까지도 굉장히 연속적으로 값이 존재하기 때문에 737정도면.. 충분히 가능성 있다고 판단해도 될 것 같다.
1-3. distribution_channel
예약한 방식에 따라 취소율이 다를 수 있으니 확인해보자.
# 데이터 시각화
sns.barplot(x=hotel_df['distribution_channel'], y=hotel_df['is_canceled'])
output>>
직접 예약보다는 대행사(TA/TO) 예약의 취소율이 더 높다고 보여진다.
1-4. hotel
호텔 종류도 취소율과 연관이 있는지 확인해본다.
# 데이터 시각화
sns.barplot(x=hotel_df['hotel'], y=hotel_df['is_canceled'])
output>>
휴양지 호텔보다 도시 호텔이 취소율이 더 높다.
1-5. arrival_date_month
휴양지의 경우 성수기 비성수기에 따라 취소율이 다를 것으로 예상된다.
plt.figure(figsize=(15, 5))
sns.barplot(x=hotel_df['arrival_date_month'], y=hotel_df['is_canceled'])
output>>
만약 월별 데이터를 순서대로 보고 싶다면 calendar 모듈과 옵션을 통해 정렬할 수 있다.
import calendar
months = []
for i in range(1, 13):
months.append(calendar.month_name[i])
plt.figure(figsize=(15, 5))
sns.barplot(x=hotel_df['arrival_date_month'], y=hotel_df['is_canceled'], order=months)
output>>
1-6. is_repeated_guest
재방문인지 아닌지에 대한 데이터이다.
# 데이터 시각화
sns.barplot(x=hotel_df['is_repeated_guest'], y=hotel_df['is_canceled'])
output>>
첫 방문인 손님의 취소율이 훨씬 높다.
1-7. deposit_type
요금 납부 방식에 대한 데이터이다.
# 데이터 시각화
sns.barplot(x=hotel_df['deposit_type'], y=hotel_df['is_canceled'])
output>>
취소율과 많은 관계가 있는 것으로 보인다.
1-8. corr()
지금까지는 종속변수와 독립변수간의 관계를 그래프로 하나하나 확인하였다.
상관관계를 보는 방법중 하나인 heatmap을 사용해보자.
# corr(): 열들 간의 상관관계를 계산하는 함수. 피어슨 상관계수
# -1 ~ 1 의 범위를 가지며 0에 가까울수록 두 변수의 상관관계가 없거나 매우 약함.
plt.figure(figsize=(15, 15))
sns.heatmap(hotel_df.corr(), cmap='coolwarm', vmax=1, vmin=-1, annot=True)
output>>
2. 결측치 처리
# 결측치 평균
hotel_df.isna().mean()
output>>
hotel 0.000000
is_canceled 0.000000
lead_time 0.000000
arrival_date_year 0.000000
arrival_date_month 0.000000
arrival_date_week_number 0.000000
arrival_date_day_of_month 0.000000
stays_in_weekend_nights 0.000000
stays_in_week_nights 0.000000
adults 0.000000
children 0.000034
babies 0.000000
meal 0.000000
country 0.004087
distribution_channel 0.000000
is_repeated_guest 0.000000
previous_cancellations 0.000000
previous_bookings_not_canceled 0.000000
reserved_room_type 0.000000
assigned_room_type 0.000000
booking_changes 0.000000
deposit_type 0.000000
days_in_waiting_list 0.000000
customer_type 0.000000
adr 0.000000
required_car_parking_spaces 0.000000
total_of_special_requests 0.000000
dtype: float64
children, country에 na가 존재한다.
2-1. country
country의 na는 특정 데이터로 대체하기가 힘들기 때문에 삭제한다.
hotel_df['country'].unique()
output>>
array(['PRT', 'GBR', 'USA', 'ESP', 'IRL', 'FRA', nan, 'ROU', 'NOR', 'OMN',
'ARG', 'POL', 'DEU', 'BEL', 'CHE', 'CN', 'GRC', 'ITA', 'NLD',
'DNK', 'RUS', 'SWE', 'AUS', 'EST', 'CZE', 'BRA', 'FIN', 'MOZ',
'BWA', 'LUX', 'SVN', 'ALB', 'IND', 'CHN', 'MEX', 'MAR', 'UKR',
'SMR', 'LVA', 'PRI', 'SRB', 'CHL', 'AUT', 'BLR', 'LTU', 'TUR',
'ZAF', 'AGO', 'ISR', 'CYM', 'ZMB', 'CPV', 'ZWE', 'DZA', 'KOR',
'CRI', 'HUN', 'ARE', 'TUN', 'JAM', 'HRV', 'HKG', 'IRN', 'GEO',
'AND', 'GIB', 'URY', 'JEY', 'CAF', 'CYP', 'COL', 'GGY', 'KWT',
'NGA', 'MDV', 'VEN', 'SVK', 'FJI', 'KAZ', 'PAK', 'IDN', 'LBN',
'PHL', 'SEN', 'SYC', 'AZE', 'BHR', 'NZL', 'THA', 'DOM', 'MKD',
'MYS', 'ARM', 'JPN', 'LKA', 'CUB', 'CMR', 'BIH', 'MUS', 'COM',
'SUR', 'UGA', 'BGR', 'CIV', 'JOR', 'SYR', 'SGP', 'BDI', 'SAU',
'VNM', 'PLW', 'QAT', 'EGY', 'PER', 'MLT', 'MWI', 'ECU', 'MDG',
'ISL', 'UZB', 'NPL', 'BHS', 'MAC', 'TGO', 'TWN', 'DJI', 'STP',
'KNA', 'ETH', 'IRQ', 'HND', 'RWA', 'KHM', 'MCO', 'BGD', 'IMN',
'TJK', 'NIC', 'BEN', 'VGB', 'TZA', 'GAB', 'GHA', 'TMP', 'GLP',
'KEN', 'LIE', 'GNB', 'MNE', 'UMI', 'MYT', 'FRO', 'MMR', 'PAN',
'BFA', 'LBY', 'MLI', 'NAM', 'BOL', 'PRY', 'BRB', 'ABW', 'AIA',
'SLV', 'DMA', 'PYF', 'GUY', 'LCA', 'ATA', 'GTM', 'ASM', 'MRT',
'NCL', 'KIR', 'SDN', 'ATF', 'SLE', 'LAO'], dtype=object)
2-2. dropna()
# 결측치 제거
hotel_df = hotel_df.dropna()
3. column 합치기(파생변수)
데이터 전처리에는 여러가지 방법이 있다.
합쳐도 되는 column을 합치는 방법을 사용한다.
3-1. people
# 데이터 개수
len(hotel_df[(hotel_df['adults'] == 0) & (hotel_df['children'] == 0) & (hotel_df['babies'] == 0)])
호텔에 숙박하는 사람에 해당하는 column으로 'adults', 'children', 'babies'가 있다. 모두 0인 데이터가 170개 존재하기 때문에 세 컬럼을 합치고 0인 데이터는 지우도록 한다.
# 새 컬럼 생성
hotel_df['people'] = hotel_df['adults'] + hotel_df['children'] + hotel_df['babies']
# people이 0인 데이터를 제외하고 다시 저장
hotel_df = hotel_df[hotel_df['people'] != 0]
len(hotel_df[hotel_df['people'] == 0])
output>>
0
3-2. total_nights
people과 마찬가지로 총 숙박 일수 column을 (주중 숙박일 + 주말 숙박일)로 하여 생성한다.
# total_nights
hotel_df['total_nights'] = hotel_df['stays_in_week_nights'] + hotel_df['stays_in_weekend_nights']
# 숙박일이 0일인 데이터
len(hotel_df[hotel_df['total_nights'] == 0])
output>>
640
숙박일이 0일인 경우를 가능한 경우로 볼 수 있다고 판단하여 지우지 않고 넘어간다.
3-3. season
아까전에 확인한 arrival_date_month를 계절별 데이터로 바꿔서 저장해보자.
# apply, lambda 사용
hotel_df['season'] = hotel_df['arrival_date_month'].apply(lambda data: 'winter' if data in ['December', 'January', 'February'] else 'spring' if data in ['March', 'April', 'May'] else 'summer' if data in ['June', 'July', 'August'] else 'fall' if data in ['September', 'October', 'November'] else 'winter')
단순하게 apply와 lambda함수를 사용해서 파생변수를 만들 수 있다.
# calendar, map() 사용
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
hotel_df['season'] = hotel_df['arrival_date_month'].map(new_season_dic)
calendar 모듈과 map()함수를 사용해서 파생변수를 만들 수 있다.
# 요약 정보
hotel_df.info()
output>>
<class 'pandas.core.frame.DataFrame'>
Int64Index: 118728 entries, 0 to 119389
Data columns (total 30 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 hotel 118728 non-null object
1 is_canceled 118728 non-null int64
2 lead_time 118728 non-null int64
3 arrival_date_year 118728 non-null int64
4 arrival_date_month 118728 non-null object
5 arrival_date_week_number 118728 non-null int64
6 arrival_date_day_of_month 118728 non-null int64
7 stays_in_weekend_nights 118728 non-null int64
8 stays_in_week_nights 118728 non-null int64
9 adults 118728 non-null int64
10 children 118728 non-null float64
11 babies 118728 non-null int64
12 meal 118728 non-null object
13 country 118728 non-null object
14 distribution_channel 118728 non-null object
15 is_repeated_guest 118728 non-null int64
16 previous_cancellations 118728 non-null int64
17 previous_bookings_not_canceled 118728 non-null int64
18 reserved_room_type 118728 non-null object
19 assigned_room_type 118728 non-null object
20 booking_changes 118728 non-null int64
21 deposit_type 118728 non-null object
22 days_in_waiting_list 118728 non-null int64
23 customer_type 118728 non-null object
24 adr 118728 non-null float64
25 required_car_parking_spaces 118728 non-null int64
26 total_of_special_requests 118728 non-null int64
27 people 118728 non-null float64
28 total_nights 118728 non-null int64
29 season 118728 non-null object
dtypes: float64(3), int64(17), object(10)
memory usage: 28.1+ MB
3-4. expected_room_type
희망한 방과 실제 예약된 방이 다른 경우 예약 취소를 할 가능성이 있다.
희망한 방과 예약된 방의 일치 여부를 파생컬럼으로 만들어보자.
# 방 일치 여부
hotel_df['expected_room_type'] = (hotel_df['reserved_room_type'] == hotel_df['assigned_room_type']).astype(int)
output>>
일치하면 1 다르면 0
3-5. cancel_rate
예약을 취소한 횟수와 정상 숙박한 횟수를 합하면 예약을 시도한 총 횟수가 된다.
예약을 한 횟수에 대한 예약 취소 비율을 계산하면 이 고객이 취소할 확률과 비슷한 데이터를 얻을 수 있다.
# 예약 취소 확률
hotel_df['cancel_rate'] = hotel_df['previous_cancellations'] / (hotel_df['previous_cancellations'] + hotel_df['previous_bookings_not_canceled'])
output>>
생성된 컬럼의 값을 보면 NaN이 많은걸 확인할 수 있다.
첫 방문이거나 예약을 취소한 데이터가 NaN이면 해당 계산 값이 NaN이 된다.
NaN을 머신러닝에서 사용하려면 값을 어떠한 의미도 되지 않는 값으로 대체해야한다.
여기선 -1이 적당할 것 같다.
# na 대체
hotel_df['cancel_rate'] = hotel_df['cancel_rate'].fillna(-1)
4. One Hot Encoding
# 요약 정보
hotel_df.info()
output>>
<class 'pandas.core.frame.DataFrame'>
Int64Index: 118728 entries, 0 to 119389
Data columns (total 32 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 hotel 118728 non-null object
1 is_canceled 118728 non-null int64
2 lead_time 118728 non-null int64
3 arrival_date_year 118728 non-null int64
4 arrival_date_month 118728 non-null object
5 arrival_date_week_number 118728 non-null int64
6 arrival_date_day_of_month 118728 non-null int64
7 stays_in_weekend_nights 118728 non-null int64
8 stays_in_week_nights 118728 non-null int64
9 adults 118728 non-null int64
10 children 118728 non-null float64
11 babies 118728 non-null int64
12 meal 118728 non-null object
13 country 118728 non-null object
14 distribution_channel 118728 non-null object
15 is_repeated_guest 118728 non-null int64
16 previous_cancellations 118728 non-null int64
17 previous_bookings_not_canceled 118728 non-null int64
18 reserved_room_type 118728 non-null object
19 assigned_room_type 118728 non-null object
20 booking_changes 118728 non-null int64
21 deposit_type 118728 non-null object
22 days_in_waiting_list 118728 non-null int64
23 customer_type 118728 non-null object
24 adr 118728 non-null float64
25 required_car_parking_spaces 118728 non-null int64
26 total_of_special_requests 118728 non-null int64
27 people 118728 non-null float64
28 total_nights 118728 non-null int64
29 season 118728 non-null object
30 expected_room_type 118728 non-null int64
31 cancel_rate 118728 non-null float64
dtypes: float64(4), int64(18), object(10)
memory usage: 29.9+ MB
One Hot Encoding을 진행하기 전 object 타입의 컬럼들을 확인해보자.
obj_list = []
for i in hotel_df.columns:
if hotel_df[i].dtype == 'O':
obj_list.append(i)
obj_list
for i in obj_list:
print(i, hotel_df[i].nunique())
output>>
['hotel',
'arrival_date_month',
'meal',
'country',
'distribution_channel',
'reserved_room_type',
'assigned_room_type',
'deposit_type',
'customer_type',
'season']
hotel 2
arrival_date_month 12
meal 5
country 177
distribution_channel 5
reserved_room_type 9
assigned_room_type 11
deposit_type 3
customer_type 4
season 4
hotel은 앞에서 확인했듯이 resort, city로 나뉜다.
arrival_date_month의 경우 1월부터 12월까지를 영어로 나타낸 것이다. season이라는 파생컬럼을 만들었기 때문에 지워도 상관없을 것 같다.
meal은 식사 정보이다. 식사정보가 취소여부에 영향을 줄 것 같지 않기 때문에 지우도록 한다.
country는 177개로 다소 많은 데이터를 가지고 있기 때문에 One Hot Encoding을 하게 되면 column이 너무 많아진다. 그리고 나라 데이터 또한 취소여부와 큰 관련이 없을 것으로 판단하여 지우도록 한다.
나머지 데이터들은 크기가 적당하니 모두 One Hot Encoding을 진행한다.
hotel_df.drop(['country', 'meal'], axis=1, inplace=True)
obj_list.remove('country')
obj_list.remove('meal')
hotel_df = pd.get_dummies(hotel_df, columns=obj_list)
hotel_df.info()
output>>
<class 'pandas.core.frame.DataFrame'>
Int64Index: 118728 entries, 0 to 119389
Data columns (total 72 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 is_canceled 118728 non-null int64
1 lead_time 118728 non-null int64
2 arrival_date_year 118728 non-null int64
3 arrival_date_week_number 118728 non-null int64
4 arrival_date_day_of_month 118728 non-null int64
5 stays_in_weekend_nights 118728 non-null int64
6 stays_in_week_nights 118728 non-null int64
7 adults 118728 non-null int64
8 children 118728 non-null float64
9 babies 118728 non-null int64
10 is_repeated_guest 118728 non-null int64
11 previous_cancellations 118728 non-null int64
12 previous_bookings_not_canceled 118728 non-null int64
13 booking_changes 118728 non-null int64
14 days_in_waiting_list 118728 non-null int64
15 adr 118728 non-null float64
16 required_car_parking_spaces 118728 non-null int64
17 total_of_special_requests 118728 non-null int64
18 people 118728 non-null float64
19 total_nights 118728 non-null int64
20 expected_room_type 118728 non-null int64
21 cancel_rate 118728 non-null float64
22 hotel_City Hotel 118728 non-null uint8
23 hotel_Resort Hotel 118728 non-null uint8
24 arrival_date_month_April 118728 non-null uint8
25 arrival_date_month_August 118728 non-null uint8
26 arrival_date_month_December 118728 non-null uint8
27 arrival_date_month_February 118728 non-null uint8
28 arrival_date_month_January 118728 non-null uint8
29 arrival_date_month_July 118728 non-null uint8
30 arrival_date_month_June 118728 non-null uint8
31 arrival_date_month_March 118728 non-null uint8
32 arrival_date_month_May 118728 non-null uint8
33 arrival_date_month_November 118728 non-null uint8
34 arrival_date_month_October 118728 non-null uint8
35 arrival_date_month_September 118728 non-null uint8
36 distribution_channel_Corporate 118728 non-null uint8
37 distribution_channel_Direct 118728 non-null uint8
38 distribution_channel_GDS 118728 non-null uint8
39 distribution_channel_TA/TO 118728 non-null uint8
40 distribution_channel_Undefined 118728 non-null uint8
41 reserved_room_type_A 118728 non-null uint8
42 reserved_room_type_B 118728 non-null uint8
43 reserved_room_type_C 118728 non-null uint8
44 reserved_room_type_D 118728 non-null uint8
45 reserved_room_type_E 118728 non-null uint8
46 reserved_room_type_F 118728 non-null uint8
47 reserved_room_type_G 118728 non-null uint8
48 reserved_room_type_H 118728 non-null uint8
49 reserved_room_type_L 118728 non-null uint8
50 assigned_room_type_A 118728 non-null uint8
51 assigned_room_type_B 118728 non-null uint8
52 assigned_room_type_C 118728 non-null uint8
53 assigned_room_type_D 118728 non-null uint8
54 assigned_room_type_E 118728 non-null uint8
55 assigned_room_type_F 118728 non-null uint8
56 assigned_room_type_G 118728 non-null uint8
57 assigned_room_type_H 118728 non-null uint8
58 assigned_room_type_I 118728 non-null uint8
59 assigned_room_type_K 118728 non-null uint8
60 assigned_room_type_L 118728 non-null uint8
61 deposit_type_No Deposit 118728 non-null uint8
62 deposit_type_Non Refund 118728 non-null uint8
63 deposit_type_Refundable 118728 non-null uint8
64 customer_type_Contract 118728 non-null uint8
65 customer_type_Group 118728 non-null uint8
66 customer_type_Transient 118728 non-null uint8
67 customer_type_Transient-Party 118728 non-null uint8
68 season_fall 118728 non-null uint8
69 season_spring 118728 non-null uint8
70 season_summer 118728 non-null uint8
71 season_winter 118728 non-null uint8
dtypes: float64(4), int64(18), uint8(50)
memory usage: 26.5 MB
완성
5. train-test-split
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=2023)
print(X_train.shape, y_train.shape)
print(X_test.shape, y_test.shape)
output>>
(83109, 71) (83109,)
(35619, 71) (35619,)
6. 랜덤 포레스트(Random Forest)
from sklearn.ensemble import RandomForestClassifier
# 랜덤 포레스트 분류기
rf = RandomForestClassifier()
rf.fit(X_train, y_train)
pred1 = rf.predict(X_test)
proba1 = rf.predict_proba(X_test)
# 확률 확인
print(proba1)
output>>
[[0.99 0.01 ]
[0.91 0.09 ]
[0.98 0.02 ]
...
[0.295 0.705 ]
[0.9675 0.0325 ]
[0.24633892 0.75366108]]
7. 성능 평가
2023.12.27 - [AI/머신러닝] - [머신러닝] Confusion Matrix, AUC & ROC
[머신러닝] Confusion Matrix, AUC & ROC
혼돈행렬 선형 모델의 성능은 MSE, MAE, RMSE등으로 평가된다. 분류 모델은 Confusion Matrix(혼돈 행렬)를 사용하여 Perfomance Test를 한다. 혼돈 행렬을 사용하여 정밀도(Precision), 재현률(Recall), 정확도(Accur
caramelbottle.tistory.com
이진 분류 문제의 성능을 평가하기 위해선 ROC, AUC를 사용한다.
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report, roc_auc_score
print('accuracy_score: ', accuracy_score(y_test, pred1))
print('confusion_matrix: \n', confusion_matrix(y_test, pred1))
print(classification_report(y_test, pred1))
output>>
accuracy_score: 0.8589516830904854
confusion_matrix:
[[20824 1611]
[ 3413 9771]]
precision recall f1-score support
0 0.86 0.93 0.89 22435
1 0.86 0.74 0.80 13184
accuracy 0.86 35619
macro avg 0.86 0.83 0.84 35619
weighted avg 0.86 0.86 0.86 35619
7-1. roc_auc_score
roc_auc_score(y_test, proba1[:, 1])
output>>
0.9258522784132585
7-2. 하이퍼 파라미터 수정(max_depth=30)
# 하이퍼 파라미터 수정(max_depth=30)
rf2 = RandomForestClassifier(max_depth=30, random_state=2023)
rf2.fit(X_train, y_train)
proba2 = rf2.predict_proba(X_test)
roc_auc_score(y_test, proba2[:, 1])
output>>
0.9282014901868613
적용전과 적용후의 AUC Score 비교를 통해 성능 차이를 볼 수 있다.
적용 전 적용후
0.9268826941531199 - 0.9282014901868613
7-3. ROC-AUC 시각화
import matplotlib.pyplot as plt
from sklearn.metrics._plot.roc_curve import roc_curve
# fpr = False Positive Rate
# tpr = True Positive Rate
# thr = Threshold
fpr, tpr, thr = roc_curve(y_test, proba2[:, 1])
plt.plot(fpr, tpr, label='ROC Curve')
plt.plot([0, 1], [0, 1])
plt.show()
output>>
'AI > 머신러닝 - 예제' 카테고리의 다른 글
[머신러닝 - 예제] 손글씨 데이터셋 - 서포트 벡터머신(SVM) (0) | 2023.12.28 |
---|---|
[머신러닝 - 예제] Human Resource 데이터셋 - 로지스틱 회귀 (0) | 2023.12.27 |
[머신러닝 - 예제] Bike 데이터셋 - 의사 결정 나무 (1) | 2023.12.26 |
[머신러닝 - 예제] Rent 데이터셋 - 선형 회귀 (1) | 2023.12.25 |
[머신러닝 - 예제] 타이타닉 데이터셋 - 캐글 데이터셋 (0) | 2023.12.25 |
댓글