본문 바로가기
개발 공부/빅데이터분석기사

[빅데이터 분석 기사] tip, 제 1유형, 제 2유형, 제 3유형 통합 요약

by momo'sdad 2024. 6. 22.

빅데이터 분석기사 실기 Tip

 

행 모두 보기:

pd.set_option('display.max_rows', None)

열(컬럼) 모두 보기:

pd.set_option('display.max_columns', None)

 

.__all__  /  dir  /  help:

 

import sklearn

print(sklearn.__all__)

 

from sklearn import preprocessing

print(dir(preprocessing)

 

from sklearn.preprocessing import LabelEncoding

print(help(LabelEncoding)

 

결측

결측치가 너무 많으면 그냥 제거나 0으로 하고,

데이터의 10% 정도면 수치형은 중앙값, 범주형은 최빈값으로 대체

 

or 결측치가 적으면 제거, 많으면 평균채우기

 

하이퍼파라미터 튜닝

# 디폴트값
 . n_estimators 100
 . min_sample_leaf 1   작으면 과적합 위험
 . min_sample_split 2  작으면 과적합 위험
# max_depth             너무 크면 과적합 위험)

=> train / validation set을 나눈 후

n_estimators와 max_depth만 조정해 가면서(나머지는 그냥 디폴트로 사용) 과적합 피라기

 

하이퍼 파라미터 튜닝 시 이런식으로 조절

n_estimators=100
max_depth=3,5,7,9,10...
min_samples_leaf=1,2,3,4,5 
rf_hp = {
   'max_depth' : [6, 8, 12],
   'min_samples_leaf' : [6, 8, 12],
   'min_samples_split' : [6, 8, 10]
}

 

정확도 확인

model = RandomForestClassifier(n_estimators=10)

훈련 세트 정확도 : model.score(X_train, y_train)

테스트 세트 정확도 : model.score(X_test, y_test)

 

 

sklearn.metric에서 문제에서 제시하는 평가방식을 import 해서 사용  
평가방식의 y_test, predict형식에 대해서는 일부 차이가 있을 수 있음  
지표마다 help함수를 이용해서 parameter의 형식을 확인하고 코딩해야함  
  
주로 쓰는 평가방식 
- accuracy_score(정확도)
- f1_score (f1,score)
- mean_absolute_error (mae)
- mean_squared_error (mse)

from sklearn.metrics import roc_auc_score
# help(roc_auc_score)
roc_auc_score(y_test, predict_proba_value[:,1])

 

예측

특정 클래스로 분류될 "확률" 예측할 때 사용
a클래스(첫번째)로 분류될 확률을 구하라 하면
y = model.predict_proba(x_test)
print(y[:, 0]) -> 첫번째 클래스로 분류될 확률

 

predict() 메소드는 범주를 예측하여 반환하고,
predict_praba() 메소드는 확률(probability)을 반환

 

제 1유형

(체험) 제1유형 (풀이용)
제공된 데이터(data/mtcars.csv)의 qsec 칼럼을 최소-최대 척도(Min-Max Scale)로 변환한 후 0.5보다 큰 값을 가지는 레코드 수를 【제출 형식】에 맞춰 답안 작성 페이지에 입력하시오.

 

【제출 형식】
  ㉠ 정수(integer)로 입력
      (단, 소수점을 포함한 경우 소수점 첫째 자리에서 반올림하여 계산)
  ㉡ 정수 답안만 입력 

 

import pandas as pd

df = pd.read_csv("data/mtcars.csv")

pd.set_option('display.max_columns', None)
# print(df.head())

from sklearn.preprocessing import MinMaxScaler
mm = MinMaxScaler()

df[['qsec']] = mm.fit_transform(df[['qsec']])

print(len(df[df['qsec'] > 0.5]))

 

# select_dtypes(include = 포함한 데이터, exclude = 제외한 데이터)
df.select_dtypes(include = ['int', 'float'])
df.select_dtypes(exclude = 'object')
 
- 사분위 범위: 3사분위수 - 1사분위수
- 이상값 판별 : (1사분위수 - 1.5*사분위범위)보다 작거나 (3사분위수 + 1.5사분위범위)보다 큰 수
IQR = df['평균 속도'].quantile(0.75) - df['평균 속도'].quantile(0.25)
IQR.round(3)
round(IQR, 3)
 
df[df['item_name'].str.contains('Chips', na=False)]
df.sort_values('new_price', ascending=False).reset_index(drop=True)
df[(df['item_name']== 'Steak Salad') | (df['item_name']== 'Bowl')].drop_duplicates('item_name', keep='last')
 
# 특정 조건 필터로 걸어서 데이터를 변경, 수정 하기
df.loc[df['item_name']=='Izze', 'item_name'] = 'Fizzy Lizzy'  # ★★
 
# 'Vegetavles'를 포함하지 않는 데이터
~df['choice_description'].str.contains('Vegetables')
 
# startswith 사용
df[df['item_name'].str.startswith('N')]
 
# 포함된 요소 확인, 일치하는 요소 확인 ★★ (isin())
df.loc[df['new_price'].isin(lst)]
 
# 인덱스를 아스키코드 값으로 정렬
df['host_name'].value_counts().sort_index().head()
 
# groupby().size() : NaN값도 포함하여 크기 or 길이를 반환 / 데이터프레임의 속성 / Series 반환
# groupby().count() : NaN값을 무시하고 개수를 반환 / 함수 / DataFrame 반환
df.groupby('host_name').size()
 
# 데이터 프레임으로 변환 ★★ to_frame()
# count, size(as_index=False시 데이터프레임으로 출력됨)
 df.groupby(['neighbourhood_group', 'neighbourhood'], as_index=False).neighbourhood.size()
 
# neighbourhood_group의 값에 따른 neighbourhood컬럼 값 중 neighbourhood_group그룹의 최댓값들을 출력하라
data.sort_values(['neighbourhood_group', 'size'], ascending=[True,False]).drop_duplicates('neighbourhood_group', keep='first')
df.groupby(['neighbourhood_group','neighbourhood'], as_index=False).size().groupby('neighbourhood_group', as_index=False).max()
 
# price값의 평균, 분산, 최대, 최소 값을 구하여라
df.groupby('neighbourhood_group').agg({'price':['mean', 'var', 'max', 'min']})
 
 # map(dic이용)
dic = {
    'Unknown': 'N',
    '$60K - $80K':'c',
    'Less than $40K':'a',
    '$80K - $120K':'d',
    '$40K - $60K': 'b',
    '$120K +': 'e'
}
df['Income_Category'].map(dic)
 
# apply
# def에서 기본값 설정x
def changeCategory(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(changeCategory)
 
# lamda사용
df['Education_Level'].map(lambda x : 1 if 'Graduate' in x else 0)
df['Credit_Limit'].map(lambda x : 1 if x >= 4500 else 0)
 
# Marital_Status 컬럼값이 Married 이고 Card_Category 컬럼의 값이 Platinum인 경우 1 그외의 경우에는 모두 0으로 하는 newState컬럼을 정의하라. newState의 각 값들의 빈도수를 출력하라
#### - 일반적으로 axis = 0  (행방향), axis = 1 (열방향)

#### - mean(), rank(), apply() 의 경우 axis = 0 (열의 평균 -> 행방향, 함수 실행), axis = 1 (행의 평균 -> 열방향, 함수 실행)
def check(x):
    if x['Marital_Status'] == 'Married' and x['Card_Category'] == 'Platinum':
        return 1
    else:
        return 0
df['newState'] = df.apply(check, axis= 1)
df['newState'].value_counts()
 
# datetime으로 변경
df['Yr_Mo_Dy'] =  pd.to_datetime(df['Yr_Mo_Dy'])
 
df['Yr_Mo_Dy'].astype('str').map(lambda x : str(int(x[:4])-100) + x[4:] if x[:4]>='2061' else x)
 
df['year'] =  df['Yr_Mo_Dy'].dt.year
df.groupby('year').mean()
 
df['weekday'] = df['Yr_Mo_Dy'].dt.day_of_week
 
def check2(x):
    if x in [5,6]:
        return 1
    else:
        return 0

df['weekday'].apply(check2).value_counts()
 
# 년도 - 월을 기준으로 모든 컬럼의 평균값을 구하여라
# case 1
df.groupby(df['Yr_Mo_Dy'].dt.strftime('%Y-%m')).mean()
# case 2
df.groupby(df['Yr_Mo_Dy'].dt.to_period('M')).mean()
 
# RPT 컬럼의 값을 일자별 기준으로 1차차분하라
df['diff'] = df['RPT'].diff()
 
# 이동평균 rolling RPT와 VAL의 컬럼을 일주일 간격으로 각각 이동평균한값을 구하여라 
df[['RPT_roll', 'VAL_roll']]=df[['RPT', 'VAL']].rolling(7).mean()
 
 
# 년-월-일:시 컬럼을 pandas에서 인식할 수 있는 datetime 형태로 변경하라. 서울시의 제공데이터의 경우 0시가 24시로 표현된다
# case 1
def date_ft(x):
    if x[-2:] != '24':
        x = x.replace(':', ' ')
        return pd.to_datetime(x)
    else:
        date = pd.to_datetime(x.split(':')[0]) + datetime.timedelta(days=1)
        return date

df['date'].apply(date_ft)
 
# case 2
def change_date(x):
    import datetime
    hour = x.split(':')[1]
    date = x.split(":")[0]
   
    if hour =='24':
        hour ='00:00:00'
       
        FinalDate = pd.to_datetime(date +" "+hour) +datetime.timedelta(days=1)
       
    else:
        hour = hour +':00:00'
        FinalDate = pd.to_datetime(date +" "+hour)
   
    return FinalDate

df['date'] = df['date'].apply(change_date)
 
# 요일 이름
df['date'].dt.day_name()
 
 # 빈도수
df[['date', 'PM10등급']].groupby([df['date'].dt.date, 'PM10등급']).size().unstack().fillna(0).astype('int')
 
# 시간이 연속적으로 존재하며 결측치가 없는지 확인하라
# case1
df['date'].diff().dropna().unique()  
# 첫행 nan값을 제외하고 1일씩 차분한 값이 1개 뿐이므로 결측치가 존재하지 않음
# case2
check = len(df['date'].diff().unique())
if check ==2:
    Ans =True
else:
    Ans = False
# dropna를 하지 않았으므로 첫행의 nan값이 존재하므로 2개 일 경우 결측치가 존재하지 않음
 
# 10, 22시 평균값
df.groupby(df['date'].dt.hour)['PM10'].mean()[10]
df.groupby(df['date'].dt.hour)['PM10'].mean()[22]
 
# 인덱스가 datetime index형일 경우  resample 사용
# 숫자형 열만 포함된 데이터 프레임 생성
numeric_df = df.select_dtypes(include='number')
numeric_df = df.select_dtypes(exclude='object')
numeric_df.resample('W').mean()
 
# pivot
df_new.pivot(index= 'Location', columns='Period', values='First Tooltip')
df.pivot_table(index='Dim1', columns='Period', values='First Tooltip', aggfunc = 'mean')
 
# merge, concat
pd.concat([df1, df2])
pd.merge(df5,df6,on='Algeria',how='inner')
 
# fillna()
o으로 채우기 fillna(0)
평균으로 채우기 fillna(df['col'].mean())
최빈값으로 채우기 fillna(df['col'].value_counts().idxmax())
 

 

제 2유형

 

제공된 데이터는 백화점 고객이 1년간 상품을 구매한 속성 데이터이다. 제공된 학습용 데이터(data/customer_train.csv)를 이용하여 백화점 구매 고객의 성별을 예측하는 모델을 개발하고, 개발한 모델에 기반하여 평가용 데이터(data/customer_test.csv)에 적용하여 얻은 성별 예측 결과를 아래 【제출 형식】에 따라 CSV 파일로 생성하여 제출하시오.

* 예측 결과는 ROC-AUC 평가지표에 따라 평가함

* 성능이 우수한 예측 모델을 구축하기 위해서는 데이터 정제, Feature Engineering, 하이퍼 파라미터(hyper parameter) 최적화, 모델 비교 등이 필요할 수 있음. 다만, 과적합에 유의하여야 함.

【제출 형식】

  ㉠ CSV 파일명 : result.csv (파일명에 디렉토리·폴더 지정불가)
  ㉡ 예측 성별 칼럼명 : pred
  ㉢ 제출 칼럼 개수 : pred 칼럼 1개 

 


import pandas as pd

train = pd.read_csv("data/customer_train.csv")
test = pd.read_csv("data/customer_test.csv")


# 모든 컬럼 보기
pd.set_option('display.max_columns', None)

# 결측치 확인
# print(train.info())
# print(test.info())

# 결측치 대체
train['환불금액'] = train['환불금액'].fillna(0)
test['환불금액'] = test['환불금액'].fillna(0)


# 데이터 범주형 있는지 확인
# print(train.head())
# print(test.head())

# # 라벨 인코딩(범주형)
from sklearn.preprocessing import LabelEncoder

lb = LabelEncoder()
train['주구매상품'] = lb.fit_transform(train['주구매상품'])
test['주구매상품'] = lb.transform(test['주구매상품'])
train['주구매지점'] = lb.fit_transform(train['주구매지점'])
test['주구매지점'] = lb.transform(test['주구매지점'])

# print(train)
# print(test)

X_train = train.iloc[:, 1:10]
y_train = train.iloc[:, -1]
X_test = test.iloc[:, 1:]

# print(X_train) 
# print(y_train)
# print(X_test)


# RF 모델링
from sklearn.ensemble import RandomForestClassifier

# help(RandomForestClassifier)
rf = RandomForestClassifier(n_estimators = 100, max_depth = 3, min_samples_leaf = 6, min_samples_split = 6)
rf.fit(X_train, y_train)
pred = rf.predict(X_test)
# print(pred)

# 파일 저장 및 결과 확인
result = pd.DataFrame({'pred': pred})
result.to_csv('result.csv', index=False)
print(pd.read_csv('result.csv'))

# 점수 확인 및 파라미터 튜닝
print("훈련세트 점수:", rf.score(X_train, y_train))
print("테스트세트 점수:", rf.score(X_test, pred))

 

 

제 3유형

【제출 형식】

  ㉠ 소수 넷째 자리에서 반올림하여 소수 셋째 자리까지만 계산

 

코드 답

① Gender와 Survived 변수 간의 독립성 검정을 실시하였을 때, 카이제곱 통계량은? (반올림하여 소수 셋째 자리까지 계산)

# 1. 독립성 검정 : chi2_contingency

from scipy.stats import chi2_contingency

df1 = pd.crosstab(df['Gender'], df['Survived'])

chi2, p, dof, expected = chi2_contingency(df1) # 귀무가설 기각

print(round(chi2, 3))

답: 260.717

 

 

② Gender, SibSp, Parch, Fare를 독립변수로 사용하여 로지스틱 회귀모형을 실시하였을 때, Parch 변수의 계수값은? (반올림하여 소수 셋째 자리까지 계산)

# 2. 로지스틱 회귀모형 : statsmodels.formula.api import logit

from statsmodels.formula.api import logit

formula = 'Survived ~ Gender + SibSp + Parch + Fare'

model = logit(formula, data=df).fit()

print(round(model.params['Parch'], 3))

# model.params 대신 model.summary()로 확인해도 답 나옴

답:  -0.201

 

③ 위 ②번 문제에서 추정된 로지스틱 회귀모형에서 SibSp 변수가 한 단위 증가할 때 생존할 오즈비(Odds ratio) 값은? (반올림하여 소수 셋째 자리까지 계산)

# 3. SibSp 변수가 한 단위 증가할 때 생존할 오즈비 : np.exp

result = np.exp(model.params)

print(round(result['SibSp'], 3))

답: 0.702

 

 

- 전체 코드 -

import pandas as pd

df = pd.read_csv("data/Titanic.csv")
#print(df.info())
#print(df.head())

#1번 문제
from scipy.stats import chi2_contingency
table = pd.crosstab(df.Gender, df.Survived)
chi2, p_val, dof, exp = chi2_contingency(table)
#print(round(chi2,3)) #260.717
#print(p_val) #귀무 가설 기각 

#2번 문제
from statsmodels.formula.api import logit
result1 = logit('Survived ~ Gender+SibSp+Parch+Fare', data=df).fit().summary()
#print(result1) #-0.201

#3번 문제
import numpy as np
result2=logit('Survived ~ Gender+SibSp+Parch+Fare', data=df).fit().params
print(result2)
print(np.exp(result2)) #0.702

 

-검정통계량-

from scipy import stats

변경 후: stats.ttest_rel(a['bp_after'], a['bp_before'], alternative='less') 결과: Ttest_relResult(statistic=-3.3371870510833657, pvalue=0.0005648957322420411)

 
반응형