Time_Series

 

064. 데이터를 로드하고 각 열의 데이터 타입을 파악하라.

DataUrl = 'https://raw.githubusercontent.com/Datamanim/pandas/main/timeTest.csv'
df = pd.read_csv(DataUrl)
df.info()
[output]

 

065. Yr_Mo_Dy을 판다스에서 인식할 수 있는 datetime64타입으로 변경하라.

df['Yr_Mo_Dy'] = pd.to_datetime(df['Yr_Mo_Dy'])
df['Yr_Mo_Dy'].dtype
[output]
dtype('<M8[ns]')

 

066. Yr_Mo_Dy에 존재하는 년도의 유일값을 모두 출력하라.

print(df['Yr_Mo_Dy'].dt.year.unique())
[output]
[2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 1971 1972 1973 1974 1975 1976 1977 1978]

 

067. Yr_Mo_Dy에 년도가 2061년 이상의 경우에는 모두 잘못된 데이터이다. 해당경우의 값은 100을 빼서 새롭게 날짜를 Yr_Mo_Dy 컬럼에 정의하라.

def new_date(x):
    import datetime
    if x.year >= 2061:
        return pd.to_datetime(datetime.date(x.year - 100, x.month, x.day))
    else:
        return x

df['Yr_Mo_Dy'] = df['Yr_Mo_Dy'].apply(new_date)
df.head()
[output]

 

068. 년도별 각컬럼의 평균값을 구하라.

df.groupby(df.Yr_Mo_Dy.dt.year).mean()
[output]

 

069. weekday컬럼을 만들고 요일별로 매핑하라. ( 월요일: 0 ~ 일요일: 6)

df['weekday'] = df.Yr_Mo_Dy.dt.weekday
df['weekday'].to_frame()
[output]

 

070. weekday컬럼을 기준으로 주말이면 1 평일이면 0의 값을 가지는 WeekCheck 컬럼을 만들어라.

df['WeekCheck'] = df['weekday'].apply(lambda x: 1 if x in [5, 6] else 0)
df['WeekCheck'].to_frame()
[output]

 

071. 년도, 일자 상관없이 모든 컬럼의 각 달의 평균을 구하라.

df.groupby(df.Yr_Mo_Dy.dt.month).mean()
[output]

 

072. 모든 결측치는 컬럼기준 직전의 값으로 대체하고 첫번째 행에 결측치가 있을경우 뒤에있는 값으로 대체하라.

df.fillna(method = 'ffill').fillna(method = 'bfill')
[output]

 

073. 년도 - 월을 기준으로 모든 컬럼의 평균값을 구하라.

df.groupby([df.Yr_Mo_Dy.dt.to_period('M')]).mean()
[output]

 

074. RPT 컬럼의 값을 일자별 기준으로 1차차분하라.

df['RPT'].diff()
[output]

 

075. RPT와 VAL의 컬럼을 일주일 간격으로 각각 이동평균한값을 구하라.

df[['RPT', 'VAL']].rolling(7).mean()
[output]

 

076. 년-월-일:시 컬럼을 pandas에서 인식할 수 있는 datetime 형태로 변경하라. 서울시의 제공데이터의 경우 0시가 24시로 표현된다.

def new_date(x):
    import datetime
    date = x.split(':')[0]
    hour = x.split(':')[1]
    if hour == '24':
        newDate = pd.to_datetime(date + ' 00:00:00') + datetime.timedelta(days = 1)
    else:
        newDate = pd.to_datetime(date + ' ' + hour + ':00:00')
    return newDate

df['(년-월-일:시)'] = df['(년-월-일:시)'].apply(new_date)
df['(년-월-일:시)']
[output]

 

077. 일자별 영어요일 이름을 dayName 컬럼에 저장하라.

df['dayName'] = df['(년-월-일:시)'].dt.day_name()
df['dayName']
[output]

 

078. 요일별 각 PM10등급의 빈도수를 파악하라.

df.head()
df.groupby(df.dayName).PM10등급.value_counts().sort_index().unstack()
[output]

 

079. 시간이 연속적으로 존재하며 결측치가 없는지 확인하라.

# 시간을 차분했을 경우 첫 값은 nan, 이후 모든 차분값이 동일하면 연속이라 판단
if len(df['(년-월-일:시)'].diff().unique()) == 2:
    answer = True
else:
    answer = False

answer
[output]
True

 

080. 오전 10시와 오후 10시(22시)의 PM10의 평균값을 각각 구하라.

print(df[df['(년-월-일:시)'].dt.hour == 10].PM10.mean())
print(df[df['(년-월-일:시)'].dt.hour == 22].PM10.mean())
[output]
70.38461538461539
69.94117647058823

 

081. 날짜 컬럼을 index로 만들어라.

df.set_index('(년-월-일:시)', inplace = True, drop = True)
df.head()
[output]

 

082. 데이터를 주단위로 뽑아서 최소,최대 평균, 표준표차를 구하여라.

df.resample('W')['PM10', 'PM2.5', '오존', '이산화질소'].agg(['min','max','mean','std'])
[output]

 


출처 : https://www.datamanim.com/dataset/99_pandas/pandasMain.html

Apply, Map

 

056. 데이터를 로드하고 데이터 행과 열의 개수를  출력하라.

DataUrl = 'https://raw.githubusercontent.com/Datamanim/pandas/main/BankChurnersUp.csv'
df = pd.read_csv(DataUrl)
print(df.shape)
print('행의 수:', df.shape[0])
print('열의 수:', df.shape[1])
[output]
(10127, 19)
행의 수: 10127
열의 수: 19

 

057. Income_Category의 카테고리를 map 함수를 이용하여 다음과 같이 변경하여 newIncome 컬럼에 매핑하라.     

dic = {'Unknown'        :'N',
       'Less than $40K' : 'a',
       '$40K - $60K'    : 'b',
       '$60K - $80K'    : 'c',
       '$80K - $120K'   : 'd',
       '$120K +'        : 'e'}
       
df['newIncome'] = df['Income_Category'].map(lambda x: dic[x])
df['newIncome']
[output]

 

058. Income_Category의 카테고리를 apply 함수를 이용하여 다음과 같이 변경하여 newIncome 컬럼에 매핑하라.

def cat_income(x):
    if x == 'Unknown':
        return 'N'
    elif x =='Less than $40K':
        return 'a'
    elif x == '$40K - $60K':   
        return 'b'
    elif x == '$60K - $80K':    
        return 'c'
    elif x == '$80K - $120K':   
        return 'd'
    elif x == '$120K +':     
        return 'e'
        
df['newIncome'] = df['Income_Category'].apply(cat_income)
df['newIncome']
[output]

 

059. Customer_Age의 값을 이용하여 나이 구간을 AgeState 컬럼으로 정의하라. (0\~9 : 0 , 10\~19 :10 , 20\~29 :20 … 각 구간의 빈도수를 출력하라.

df['AgeState'] = df['Customer_Age'] // 10 * 10
df['AgeState'].value_counts().sort_index()
[output]

 

060. Education_Level의 값 중 Graduate단어가 포함되는 값은 1 그렇지 않은 경우에는 0으로 변경하여 newEduLevel 컬럼을 정의하고 빈도수를 출력하라.

df['newEduLevel'] = df['Education_Level'].str.contains('Graduate').astype(int)
df['newEduLevel'].value_counts().sort_index()
[output]

 

061. Credit_Limit 컬럼값이 4500 이상인 경우 1 그외의 경우에는 모두 0으로 하는 newLimit 정의하라. newLimit 각 값들의 빈도수를 출력하라.

df['newLimit'] = df['Credit_Limit'].apply(lambda x: int(x >= 4500))
df['newLimit'].value_counts().sort_index()
[output]

 

062. Marital_Status 컬럼값이 Married 이고 Card_Category 컬럼의 값이 Platinum인 경우 1 그외의 경우에는 모두 0으로 하는 newState컬럼을 정의하라. newState의 각 값들의 빈도수를 출력하라.

df['newState'] = pd.Series(map(int, (df['Marital_Status'] == 'Married') & (df['Card_Category'] == 'Platinum')))
df['newState'].value_counts()
[output]

 

063. Gender 컬럼값 M인 경우 male, F인 경우 female로 값을 변경하여 Gender 컬럼에 새롭게 정의하라. 각 value의 빈도를 출력하라.

df['Gender'] = df['Gender'].apply(lambda x: 'male' if x == 'M' else 'female')
df['Gender'].value_counts()
[output]

 


출처 : https://www.datamanim.com/dataset/99_pandas/pandasMain.html

Grouping

 

044. 데이터를 로드하고 상위 5개 컬럼을 출력하라.

DataUrl = 'https://raw.githubusercontent.com/Datamanim/pandas/main/AB_NYC_2019.csv'
df = pd.read_csv(DataUrl)
df.head()
[output]

 

045. 데이터의 각 host_name의 빈도수를 구하고 host_name으로 정렬하여 상위 5개를 출력하라.

df.host_name.value_counts().sort_index().head()
[output]

 

046. 데이터의 각 host_name의 빈도수를 구하고 빈도수 기준 내림차순 정렬한 데이터 프레임을 만들어라. 빈도수 컬럼은 counts로 명명하라.

df.host_name.value_counts().to_frame().rename(columns = {'host_name':'counts'})
[output]

 

047. neighbourhood_group의 값에 따른 neighbourhood컬럼 값의 갯수를 구하여라.

df.groupby(['neighbourhood_group', 'neighbourhood']).size()
[output]

 

048. neighbourhood_group의 값에 따른 neighbourhood컬럼 값 중 neighbourhood_group그룹의 최댓값들을 출력하라.

df.groupby(['neighbourhood_group', 'neighbourhood']).size().groupby('neighbourhood_group').max()
[output]

 

049. neighbourhood_group 값에 따른 price값의 평균, 분산, 최대, 최소 값을 구하라.

df.groupby('neighbourhood_group')['price'].agg(['mean', 'var', 'max', 'min'])
[output]

 

050. neighbourhood_group 값에 따른 reviews_per_month 평균, 분산, 최대, 최소 값을 구하라.

df.groupby('neighbourhood_group')['reviews_per_month'].agg(['mean', 'var', 'max', 'min'])
[output]

 

051. neighbourhood 값과 neighbourhood_group 값에 따른 price의 평균을 구하라.

df.groupby(['neighbourhood', 'neighbourhood_group'])['price'].mean()
[output]

 

052. neighbourhood 값과 neighbourhood_group 값에 따른 price의 평균을 계층적 indexing 없이 구하라.

df.groupby(['neighbourhood', 'neighbourhood_group'])['price'].mean().unstack()
[output]

 

053. neighbourhood 값과 neighbourhood_group 값에 따른 price의 평균을 계층적 indexing 없이 구하고 nan 값은 -999값으로 채워라.

df.groupby(['neighbourhood', 'neighbourhood_group'])['price'].mean().unstack().fillna(-999)
[output]

 

054. 데이터중 neighbourhood_group 값이 Queens값을 가지는 데이터들 중 neighbourhood 그룹별로 price값의 평균, 분산, 최대, 최소값을 구하라.

df[df['neighbourhood_group'] == 'Queens'].groupby('neighbourhood').price.agg(['mean', 'var', 'max', 'min']).head()
[output]

 

055. 데이터중 neighbourhood_group 값에 따른 room_type 컬럼의 숫자를 구하고 neighbourhood_group 값을 기준으로 각 값의 비율을 구하라.

df_new = df.groupby(['neighbourhood_group', 'room_type']).size().unstack()
df_new.loc[:,:] = (df_new.values/df_new.sum(axis=1).values.reshape(-1,1))
df_new
[output]

 

 


출처 : https://www.datamanim.com/dataset/99_pandas/pandasMain.html

Filtering & Sorting

020. 데이터를 로드하라.

DataUrl = 'https://raw.githubusercontent.com/Datamanim/pandas/main/chipo.csv'
df = pd.read_csv(DataUrl)
type(df)
[output]
pandas.core.frame.DataFrame

 

021. quantity 컬럼 값이 3인 데이터를 추출하여 첫 5행을 출력하라.

df[df['quantity'] == 3].head(5)
[output]

 

022. quantity 컬럼 값이 3인 데이터를 추출하여 index를 0부터 정렬하고 첫 5행을  출력하라.

df[df['quantity'] == 3].reset_index(drop = True).head()
[output]

 

023. quantity , item_price 두개의 컬럼으로 구성된 새로운 데이터 프레임을 정의하라.

df_new = df[['quantity', 'item_price']]
df_new
[output]

 

024. item_price 컬럼의 달러표시 문자를 제거하고 float 타입으로 저장하여 new_price 컬럼에 저장하라.

df['new_price'] = df['item_price'].apply(lambda x: x.replace('$', '')).astype(float)
df['new_price']
[output]

 

025. new_price 컬럼이 5이하의 값을 가지는 데이터프레임을 추출하고, 전체 개수를 구하라.

df[df['new_price'] <= 5].shape[0]
[output]
1652

 

026. item_name명이 Chicken Salad Bowl 인 데이터 프레임을 추출하고 index 값을 초기화 하라.

df[df['item_name'] == 'Chicken Salad Bowl'].reset_index(drop = True)
[output]

 

027. new_price값이 9 이하이고 item_name 값이 Chicken Salad Bowl 인 데이터 프레임을 추출하라.

df[(df['new_price'] <= 9) & (df['item_name'] == 'Chicken Salad Bowl')].head()
[output]

 

028. df의 new_price 컬럼 값에 따라 오름차순으로 정리하고 index를 초기화 하라.

df.sort_values(by = 'new_price').reset_index(drop = True)
[output]

 

029. df의 item_name 컬럼 값중 Chips 포함하는 경우의 데이터를  출력하라.

df[df['item_name'].str.contains('Chips')]
[output]

 

030. df의 짝수번째 컬럼만을 포함하는 데이터프레임을 출력하라.

df.iloc[:,::2]
[output]

 

031. df의 new_price 컬럼 값에 따라 내림차순으로 정리하고 index를 초기화 하라.

df.sort_values('new_price', ascending = False).reset_index(drop = True)
[output]

 

032. df의 item_name 컬럼 값이 Steak Salad 또는 Bowl 인 데이터를 인덱싱하라.

df[(df['item_name'] == 'Steak Salad') | (df['item_name'] == 'Bowl')]
[output]

 

033. df의 item_name 컬럼 값이 Steak Salad 또는 Bowl 인 데이터를 데이터 프레임화 한 후, item_name를 기준으로 중복행이 있으면 제거하되 첫번째 케이스만 남겨라.

df_new = df[(df['item_name'] == 'Steak Salad') | (df['item_name'] == 'Bowl')]
df_new.drop_duplicates('item_name')
[output]

 

034. df의 item_name 컬럼 값이 Steak Salad 또는 Bowl 인 데이터를 데이터 프레임화 한 후, item_name를 기준으로 중복행이 있으면 제거하되 마지막 케이스만 남겨라.

df_new = df[(df['item_name'] == 'Steak Salad') | (df['item_name'] == 'Bowl')]
df_new.drop_duplicates('item_name', keep = 'last')
[output]

 

035. df의 데이터 중 new_price값이 new_price값의 평균값 이상을 가지는 데이터들을 인덱싱하라.

df[df['new_price'] >= df['new_price'].mean()]
[output]

 

036. df의 데이터 중 item_name의 값이 Izze인 데이터를 Fizzy Lizzy로 수정하라.

df[df['item_name'] == 'lzze']['item_name'] = 'Fizzy Lizzy'
df.head()
[output]

 

037. df의 데이터 중 choice_description 값이 NaN 인 데이터의 개수를 구하라.

df['choice_description'].isnull().sum()
[output]
1246

 

038. df의 데이터 중 choice_description 값이 NaN 인 데이터를 NoData 값으로 대체하라.(loc 이용)

df.loc[df['choice_description'].isnull(), 'choice_description'] = 'NoData'
df
[output]

 

039. df의 데이터 중 choice_description 값에 Black이 들어가는 경우를 인덱싱하라.

df[df['choice_description'].str.contains('Black')]
[output]

 

040. df의 데이터 중 choice_description 값에 Vegetables이 들어가지 않는 경우의 개수를  출력하라.

len(df[~df.choice_description.str.contains('Vegetables')])
[output]
3900

 

041. df의 데이터 중 item_name 값이 N으로 시작하는 데이터를 모두 추출하라.

df[df.item_name.str.startswith('N')].head()
[output]

 

042. df의 데이터 중 item_name 값의 단어갯수가 15개 이상인 데이터를 인덱싱하라.

df[df.item_name.str.len() >= 15]
[output]

 

043. df의 데이터 중 new_price값이 lst에 해당하는 경우의 데이터 프레임을 구하고 그 개수를  출력하라.

lst = [1.69, 2.39, 3.39, 4.45, 9.25, 10.98, 11.75, 16.98]
df[df.new_price.isin(lst)].shape[0]
[output]
1393

출처 : https://www.datamanim.com/dataset/99_pandas/pandasMain.html

Getting & Knowing Data

001. 데이터를 로드하라. 데이터는 \t을 기준으로 구분되어있다.

import pandas as pd
DataUrl = 'https://raw.githubusercontent.com/Datamanim/pandas/main/lol.csv'
df = pd.read_csv(DataUrl, sep = '\t')
type(df)
[output]
pandas.core.frame.DataFrame

 

002. 데이터의 상위 5개 행을 출력하라.

df.head(5)
[output]

 

003. 데이터의 행과 열의 개수를 파악하라.

print(df.shape)
print(f'행의 수 : {df.shape[0]}')
print(f'열의 수 : {df.shape[1]}')
[output]
(51490, 61)
행의 수 : 51490
열의 수 : 61

 

004. 전체 컬럼을 출력하라.

df.columns
[output]
Index(['gameId', 'creationTime', 'gameDuration', 'seasonId', 'winner', 'firstBlood', 'firstTower', 'firstInhibitor', 'firstBaron', 'firstDragon', 'firstRiftHerald', 't1_champ1id', 't1_champ1_sum1', 't1_champ1_sum2', 't1_champ2id', 't1_champ2_sum1', 't1_champ2_sum2', 't1_champ3id', 't1_champ3_sum1', 't1_champ3_sum2', 't1_champ4id', 't1_champ4_sum1', 't1_champ4_sum2', 't1_champ5id', 't1_champ5_sum1', 't1_champ5_sum2', 't1_towerKills', 't1_inhibitorKills', 't1_baronKills', 't1_dragonKills', 't1_riftHeraldKills', 't1_ban1', 't1_ban2', 't1_ban3', 't1_ban4', 't1_ban5', 't2_champ1id', 't2_champ1_sum1', 't2_champ1_sum2', 't2_champ2id', 't2_champ2_sum1', 't2_champ2_sum2', 't2_champ3id', 't2_champ3_sum1', 't2_champ3_sum2', 't2_champ4id', 't2_champ4_sum1', 't2_champ4_sum2', 't2_champ5id', 't2_champ5_sum1', 't2_champ5_sum2', 't2_towerKills', 't2_inhibitorKills', 't2_baronKills', 't2_dragonKills', 't2_riftHeraldKills', 't2_ban1', 't2_ban2', 't2_ban3', 't2_ban4', 't2_ban5'], dtype='object')

 

005. 6번재 컬럼명을 출력하라.

df.columns[5]
[output]
'firstBlood'

 

006. 6번째 컬럼의 데이터 타입을 확인하라.

df.iloc[:, 5].dtype
[output]
dtype('int64')

 

007. 데이터셋의 인덱스 구성은 어떤가.

df.index
[output]
RangeIndex(start=0, stop=51490, step=1)

 

008. 6번째 컬럼의 3번째 값은 무엇인가?

df.iat[2, 5]
[output]
2

 

009. 데이터를 로드하라. 컬럼이 한글이므로 적절한 처리 필요.

DataUrl = 'https://raw.githubusercontent.com/Datamanim/pandas/main/Jeju.csv'
df = pd.read_csv(DataUrl, encoding = 'euc-kr')
type(df)
[output]
pandas.core.frame.DataFrame

 

010. 데이터 마지막 3개 행을 출력하라.

df.tail(3)

[output]

 

011. 수치형 변수를 가진 컬럼을 출력하라.

df.select_dtypes(exclude = object).columns
[output]
Index(['id', '거주인구', '근무인구', '방문인구', '총 유동인구', '평균 속도', '평균 소요 시간', '평균 기온', '일강수량', '평균 풍속'], dtype='object')

 

012. 범주형 변수를 가진 컬럼을 출력하라.

df.select_dtypes(include = object).columns
[output]
Index(['일자', '시도명', '읍면동명'], dtype='object')

 

013. 각 컬럼의 결측치 숫자를 파악하라.

df.isna().sum()
[output]
id          0
일자          0
시도명         0
읍면동명        0
거주인구        0
근무인구        0
방문인구        0
총 유동인구      0
평균 속도       0
평균 소요 시간    0
평균 기온       0
일강수량        0
평균 풍속       0
dtype: int64

 

014. 각 컬럼의 데이터 수, 데이터 타입을 한번에 확인하라.

df.info()
[output]

 

015. 각 수치형 변수의 분포(사분위, 평균, 표준편차, 최대 , 최소)를 확인하라.

df.describe()
[output]

 

016. 거주인구 컬럼의 값들을 출력하라.

df['거주인구']
[output]

 

017. 평균 속도 컬럼의 4분위 범위(IQR) 값을 구하라.

df['평균 속도'].quantile(0.75) - df['평균 속도'].quantile(0.25)
[output]
14.854999999999997

 

018. 읍면동명 컬럼의 유일한 값의 수를 출력하라.

df['읍면동명'].nunique()
[output]
41

 

019. 읍면동명 컬럼의 유일한 값을 모두 출력하라.

df['읍면동명'].unique()
[output]
array(['도두동', '외도동', '이도2동', '일도1동', '대천동', '서홍동', '한경면', '송산동', '조천읍', '일도2동', '영천동', '예래동', '대륜동', '삼도1동', '이호동', '건입동', '중앙동', '삼양동', '삼도2동', '이도1동', '남원읍', '대정읍', '정방동', '효돈동', '아라동', '한림읍', '구좌읍', '용담1동', '오라동', '화북동', '연동', '표선면', '중문동', '성산읍', '안덕면', '천지동', '노형동', '동홍동', '용담2동', '봉개동', '애월읍'], dtype=object)

 


출처 : https://www.datamanim.com/dataset/99_pandas/pandasMain.html

결정 트리(Decision Tree)란?

  • 학습을 통해 데이터에 있는 규칙을 찾고 트리 기반의 분류 규칙을 만드는 직관적인 알고리즘
  • 장점 : 알고리즘이 쉽고 직관적임, 피처의 스케일링이나 정규화 등의 사전 가공 영향도가 크지 않음.
  • 단점 : 과적합으로 알고리즘 성능이 떨어짐. 이를 극복하기 위해 트리의 크기를 사전에 제한하는 튜닝 필요

 

사이킷런을 이용한 결정 트리 알고리즘 구현

  • 분류를 위한 DecisionTreeClassifier, 회귀를 위한 DecisionTreeRegressor 를 제공
  • CART(Classification And Regression Trees) 알고리즘을 기반으로 함.

 

결정 트리 파라미터

파라미터 명 설명
min_samples_split - 노드를 분할하기 위한 최소한의 샘플 데이터 수
- 디폴트는 2, 작게 설정할수록 분할되는 노드가 많아져서 과적합 가능성 증가
min_samples_leaf - 분할이 될 경우 왼쪽과 오른쪽 브랜치 노드에서 가져야 할 최소한의 샘플 데이터 수
- 큰 값으로 설정될수록 노드 분할을 덜 수행함.
- 비대칭적 데이터의 경우 작게 설정 필요.
max_features - 최적의 분할을 위해 고려할 최대 피처 개수
- 디폴트는 None으로 모든 피처를 사용해 분할 수행
- int 형으로 지정하면 대상 피처의 수, float 형으로 지정하면 대상 피처의 퍼센트
- 'squrt', 'auto', 'log' 등
max_depth - 트리의 최대 깊이를 규정
- 디폴트는 None으로 다른 과적합 규제 장치가 없으면 완벽하게 클래스 결정 값이 될 때까지 분할
max_leaf_nodes - 말단 노드(Leaf)의 최대 개수

 

구현

# 필요한 모듈 다운로드
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings('ignore')

# 붓꽃 데이터 로드
iris_data = load_iris()

# train/test set 분리
x_train, x_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size = 0.2, random_state = 12)

# DecisionTree 분류기 생성
dt_clf = DecisionTreeClassifier(random_state = 123)

# 분류기 학습
dt_clf.fit(x_train, y_train)

 

피처별 중요도 확인

import seaborn as sns
import numpy as np
%matplotlib inline

# feature importance 추출
print('Feature importances: ', dt_clf.feature_importances_)

# feature별 importance 매핑
for name, value in zip(iris_data.feature_names, dt_clf.feature_importances_):
    print(f'{name} : {value}')

# feature importance를 column별로 시각화
sns.barplot(x = dt_clf.feature_importances_, y = iris_data.feature_names)

 

[OUTPUT]

Feature importances: [0.01250782 0.03001876 0.90481856 0.05265486]
sepal length (cm) : 0.012507817385866166
sepal width (cm) : 0.030018761726078806
petal length (cm) : 0.9048185603807258
petal width (cm) : 0.05265486050732925


분류의 성능 평가 지표

출처: medium.com/@danyal.wainstein1/understanding-the-confusion-matrix

  • 오차행렬(Confusion Matrix)
    • 이진 분류의 예측 오류가 얼마인지, 어떠한 유형의 예측 오류가 발생하고 있는지를 함께 나타내는 지표
  • 정확도(Accuracy)
    • 실제 데이터에서 예측 데이터가 얼마나 같은지를 판단하는 지표
    • Accuracy = (TN + TP) / (TN + FP + FN + TP)
    • 이진 분류의 경우 정확도 수치만으로 성능을 평가하면 성능이 왜곡될 수 있음.
    • 데이터가 불균형한(imbalanced) 레이블 값 분포를 가진 경우 부적합
  • 정밀도(Precision)
    • 예측을 Positive로 한 대상 중에 실제 값이 Positive로 일치한 데이터의 비율
    • Precision = TP / (FP + TP)
    • 정밀도가 상대적으로 더 중요한 지표는 실제 음성(Negative)인 데이터를 양성(Positive)으로 잘못 판단하게 되면 업무상 큰 영향이 발생하는 경우
  • 재현율(Recall)
    • 실제값이 Positive인 대상 중에 예측과 실제 값이 Positive로 일치한 데이터의 비율
    • Recall = TP / (FN + TP)
    • 민감도(Sensitivity) 또는 TPR(True Positive Rate)라고도 불림.
    • 재현율이 상대적으로 더 중요한 지표는 실제 양성(Positive)인 데이터를 음성(Negative)으로 잘못 판단하게 되면 업무상 큰 영향이 발생하는 경우
※  정밀도와 재현율은 상호 보완적인 평가 지표이므로 트레이드오프(Trade-off) 관계에 있음.
  • F1-score
    • 정밀도와 재현율의 조화 평균
    • 정밀도와 재현율이 어느 한쪽으로 치우치지 않는 수치를 나타낼 때 높은 값을 가짐.

 

  • ROC 곡선(Receiver Operation Characteristic Curve)과 AUC
    • ROC 곡선 : FPR(False Positive Rate)이 변할 때 TPR(True Positive Rate)이 어떻게 변하는지 나타내는 곡선
    • 민감도(TPR) : 실제 양성(Positive)인 값이 정확하게 예측 되어야 하는 수준
    • 특이성(TNR) : 실제 음성(Negative)인 값이 정확하게 예측 되어야 하는 수준
    • FPR = FP / (FP + TN) = 1 - TNR
    • AUC (Area Under Curve) : ROC 곡선 밑의 면적을 구한 것으로서 1에 가까울수록 좋은 수

ROC curve

본 포스팅은 고려대학교 산업경영공학부 김성범 교수님의 유튜브 강의를 정리한 내용입니다.

유튜브 - 김성범[ 교수 / 산업경영공학부 ]

 

변수 사이의 관계

  • 확정적 관계 : X 변수만으로 Y를 100% 표현 가능(오차항 없음)

       예) 힘 = f(질량, 가속도), 주행거리 = f(속도, 시간)

  • 확률적 관계 : X 변수와 오차항이 Y를 표현(오차항 있음)

        예) 반도체 수율 = f(설비 파라미터들의 상태, 온도, 습도) + ε

              포도주 가격 = f(강우량, 온도, 포도품종) + ε

              위조카드 여부 = f(사용시간, 사용액, 사용장소) + ε

 

선형회귀모델

선형회귀모델 : 출력변수 Y를 입력변수 X들의 선형결합으로 표현한 모델

선형결합 : 변수들을 (상수배와) 덧셈, 뺼셈 연산을 통해 결합

 

선형회귀모델링의 목적

  • X 변수와 Y 변수 사이의 관계를 수치로 설명
  • 미래의 반응변수(Y) 값을 예측

 

선형회귀모델의 분류

  • X 변수의 수에 따라 : 단순회귀모델, 다중회귀모델
  • X 변수와 Y변수의 선형성 여부에 따라 : 선형회귀모델, 비선형회귀모델

 

선형회귀모델 가정

(i= 1,…,n)

모든 i에 대해서 오차항은 평균이 0, 분산이 σ^2 인 정규분포를 따름.

 

선형회귀모델이란?

입력변수(X)와 출력변수(Y) 평균과의 관계를 설명하는 선형식을 찾는 것

  • 위 선형식에서 β 를 파라미터 (parameter)라 하고 파라미터를 찾는 것을 통계적으로 추정이라고 함.

+ Recent posts