티스토리 뷰
문제 : https://github.com/tjd229/DS/blob/main/Practice/6.ipynb
VberEats.csv 데이터 구조
import pandas as pd
import numpy as np
from sklearn.tree import DecisionTreeRegressor
from sklearn.preprocessing import MinMaxScaler
df =pd.read_csv("../Dataset/VberEats.csv")
print(df.dtypes)
print(df.shape)
df.head()
shape의 출력값으로 (18951, 8)이 나온다.
이번 문제에서는 공통 전처리가 있다.
#0-1 : 결제 총 금액(purchases)에 결측값(Null)이 포함된 데이터를 Test Set으로, 그 외 데이터는 Train Set으로 분할한다.
isna 함수와 notna 함수를 이용하여 쉽게 분할 할 수 있다.
tr = df[df['purchases'].notna()]
tet = df[df['purchases'].isna()]
분할 후, Test Set의 데이터 개수가 203개가 맞는지 확인하자.
#0-2 : 식별 번호(ids)와 결제 총 금액(purchases) 컬럼을 제외한 모든 컬럼에 대해 Train Set을 기준으로 MinMax 표준화(Standardization) 한다.
ids 컬럼과 purchases 컬럼을 제외한 6개의 컬럼은 아래와 같다.
['ages', 'orders', 'bookmarks', 'replies', 'ratings', 'period']
위 리스트를 cols에 저장하면 아래와 같이 간편하게 코드를 구현할 수 있다.
cols = ['ages','orders','bookmarks','replies','ratings','period']
tr_nor = tr.copy()
scaler = MinMaxScaler()
tr_nor[cols] = scaler.fit_transform(tr_nor[cols])
tet_nor = tet.copy()
tet_nor[cols]=scaler.transform(tet_nor[cols])
Train Set을 기준으로 scaler를 fitting하는 점을 잊지말자
#0-3 : Train Set으로 DecisionTreeRegressor 모델을 학습하고, Test Set에 적용하여 VberEats 데이터의 결측값을 모델의 예측값으로 대체한다.
아래와 같이 모델을 학습하고, 예측값을 구할 수 있다.
위에서 정의한 cols를 이용하여 컬럼 순서를 준수하면서 모델에 적용하자.
DecisionTree는 컬럼 순서가 다르면 다른 결과를 출력할 수 있다.
tree = DecisionTreeRegressor(random_state=229)
tree.fit(X=tr_nor[cols], y = tr_nor['purchases'])
pred = tree.predict(X=tet_nor[cols])
이 예측값을 Test Set에 넣는게 아니라, 처음 파일을 읽은 데이터인 df 결측값에 예측값을 넣어주면 된다.
df.loc[df['purchases'].isna(),'purchases'] = pred
결측값을 채운 후, df['purchases'].mean()으로 평균값을 확인하고, 최종 데이터셋을 customer 변수로 저장하자.
customer = df.copy()
Q1
from sklearn.preprocessing import MinMaxScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
q1 = customer.copy()
#1-1 : 데이터의 25%를 샘플링한다.
sample 함수를 이용하여 샘플링한다.
q1 = q1.sample(frac = 0.25,random_state=229)
#1-2 : 고객 데이터의 ages 컬럼을 이용하여 아래 규칙에 따라 age_cls 컬럼을 새로 생성한다.
문제 4처럼 아래와 같이 age_cls 컬럼을 정의할 수 있다.
q1['age_cls'] = "10s"
for age in [20,30,40,50]:
q1.loc[q1['ages']>=age,'age_cls'] = str(age)+'s'
#1-3 : 나이(ages), 주문 수(orders), 즐겨찾기 수(bookmarks), 답글 수(replies), 별점 수(ratings), 가입 기간(period) 컬럼을 MinMax 표준화(Standardization) 한다.
6개의 종속 변수를 cols 리스트에 저장하여, 아래와 같이 간편하게 정규화를 수행할 수 있다.
cols = ['ages','orders','bookmarks','replies','ratings','period']
q1_sub = q1[cols].copy()
q1_sub_nor = MinMaxScaler().fit_transform(q1_sub)
#1-4 : 독립 변수들에 대해 K-means 군집 분석을 수행한다. 이 때, 군집 수는 2~5개 중 K-means Silhouette 를 통해 구하고, 이 중 첫 번째로 높은 score를 최적의 K로 설정한다.
아래와 같이 루프문을 이용하여 최적의 K를 찾기 위한 Silhouette score를 계산할 수 있다.
for k in range(2,5+1):
model= KMeans(n_clusters=k, random_state=229)
pred = model.fit_predict(X=q1_sub_nor)
score = silhouette_score(X=q1_sub_nor,labels = pred)
print(k,":",score)
군집수가 2일 때, 스코어가 0.16X로 가장 크므로, 최적의 K는 2가 된다.
#1-5 : 최적의 K로 K-means 군집 분석 수행 후, age_cls별 가장 큰 군집 비율을 구한다. 그 중에서 최대값을 구하시오
아래와 같이 라벨 값을 q1 컬럼에 넣자
K=2
model= KMeans(n_clusters=K, random_state=229)
pred = model.fit_predict(X=q1_sub_nor)
q1['labels'] = model.labels_
age_cls별 가장 큰 군집 비율을 구해야한다.
groupby의 기준은 age_cls가 될 것이고, 그 중 labels컬럼에 대하여 value_counts 함수를 사용하면, age_cls별 라벨값이 0인 개수와 1인 개수가 출력될 것이다.
q1.groupby('age_cls')['labels'].value_counts()
문제는 군집 비율을 물어보기 때문에 normalize=True 매개변수로 비율을 출력하도록 해보자
q1.groupby('age_cls')['labels'].value_counts(normalize=True)
age_cls가 20s이면서 라벨값이 0인 군집 비율이 0.526X로 가장 크다.
혹은 .max()로 가장 큰 값을 바로 출력할 수도 있다.
q1.groupby('age_cls')['labels'].value_counts(normalize=True).max()
Q1 정답 : 0.53
Q2
from statsmodels.stats.outliers_influence import variance_inflation_factor
q2 = customer.copy()
5개의 변수 컬럼 리스트를 먼저 정의하자
cols = ['orders', 'bookmarks', 'replies', 'ratings', 'period']
단순히 다중공선성 값을 구하는 것 까지는 아래와 같이 간단히 구할 수 있다.
vif = [ variance_inflation_factor(df[cols].values,i) for i in range(len(cols))]
vif 리스트의 순서는 cols 리스트의 순서와 같다.
값이 7.53X인 replies가 정답이 된다.
만약, 위 결과를 DataFrame 형태로 보고 싶다면 아래와 같이, 새로운 DataFrame을 생성하고, 각 컬럼값과 vif 값을 삽입해주면 된다.
vif_df = pd.DataFrame()
vif_df['cols'] = cols
vif_df['factor'] = vif
vif_df
patsy 라이브러리의 dmatrices를 이용하는 경우 아래와 같이 구하면 된다.
이 때, dmatrices의 결과에는 절편이 포함되어 있으므로 vif계산 전, 절편 컬럼을 제거해주면 된다.
from patsy import dmatrices
y,X = dmatrices('purchases ~ '+(" + ".join(cols)), data = q2, return_type='dataframe')
X = X.drop(columns='Intercept')
vif = [ variance_inflation_factor(X.values,i) for i in range(X.shape[1])]
Q2 정답 : replies
Q3
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import recall_score
q3 = customer.copy()
단계 1 : 주문 수(orders) 컬럼을 이용하여 아래 규칙에 따라 regular 컬럼을 새로 생성한다.
np.where를 이용하여 regular 컬럼을 쉽게 생성할 수 있다.
avg = q3['orders'].mean()
q3['regular'] = np.where(df['orders']>avg,1,0)
단계 2 : Train Set과 Test Set을 2:8 비율로 나눈다.
train_size 매개변수에 0.2를 넣으면 된다.
Train Set의 데이터 개수는 3790, Test Set의 데이터 개수는 15161개가 된다.
tr,tet = train_test_split(q3,train_size =0.2, random_state = 229)
단계 3 : Train Set으로 나이브 베이즈 분류 모델을 학습한다.
종속 변수 6개를 cols 리스트에 저장하고, 아래와 같이 모델 정의 및 학습을 실시한다.
cols = ['ages','purchases', 'bookmarks', 'replies', 'ratings', 'period']
clf = GaussianNB()
clf.fit(X = tr[cols], y=tr['regular'])
단계 4 : 단계 3에서 학습한 모델을 Test Set에 적용한다. 모델의 예측 확률값이 threshold보다 큰 경우를 positive로 정의한다. threshold는 0.4, 0.5, 0.6 세 경우에 대하여 recall_score를 계산하고 그 중 최대값을 구하시오
predict_proba 함수가 각 클래스별 확률을 반환한다.
만약 0번 데이터가 0번 라벨일 확률은 [0,0]에 저장된다.
이 문제에서는 라벨 값이 1인 경우가 positive이므로 아래의 값에 대하여 threshold를 비교하면 된다.
clf.predict_proba(X=tet[cols])[:,1]
세 가지 threshold에 대하여 루프문을 이용하여 계산하자.
res = clf.predict_proba(X=tet[cols])
true = tet['regular']
for th in [0.4,0.5,0.6]:
pred = res[:,1]
pred = np.where(pred>th,1, 0)
score = recall_score(true,pred)
threshold가 0.4일 때, recall score가 0.63로 가장 크다.
Q3 정답 : 0.6
'Computer Science > Data Science' 카테고리의 다른 글
문제 5) Solution (0) | 2023.03.19 |
---|---|
문제 4) Solution (3) | 2023.03.19 |
문제 3) Solution (6) | 2023.03.19 |
문제 2) Solution (4) | 2023.03.19 |
문제 1) Solution (11) | 2023.03.19 |
- Total
- Today
- Yesterday
- Codeforces
- Joi
- 구간합
- yaml
- NERC
- 인터렉션
- ICPC
- Book
- 인터렉티브
- Math
- graph
- Sqrt Decomposition
- oj.uz
- Divide and conquer
- line sweeping
- greedy
- DataScience
- RMI
- boj
- Binary Search
- TensorFlow
- 함수컵
- pytorch
- ioi
- codejam
- 함수 구현
- LCA
- two pointer
- Decorator
- DeepLearning
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |