우엑 우우우엑 나는 과제 한 번도 안빠트렸는데 진짜 ㅠㅠ 결국 죄수의 딜레마 열등한 내쉬균형 달성
그래도 문제는 진짜 전범위 복습하기 좋게 구성한듯
3등안에 들어서 치킨 깊티 ㄹㅇ 개꿀이당
Q1. 수 범위를 전달받아 소수(prime number)만 반환하는 함수 만들기
def prime_number(number): # number를 입력 받아 소수인지 아닌지 구분하는 함수
# number가 1이 아니면, (1은 소수가 아님)
if number != 1:
# 2, 3, 4, ..., (number - 1)까지의 인수에 대해서
for f in range(2, number):
# number가 위의 인수 중의 하나로 나누어지면, (나머지가 0이면)
if number % f == 0:
return False # 소수가 아님
else: # number가 1이라면,
return False # 소수가 아님
# number가 1이 아니면서, 2부터 (number - 1)까지의 수로 나눠지지 않으므로
# 소수로 판별됨 (소수는 1과 자신만을 인수로 갖는 수)
return True
def prime(init, term):
integer_list = (x for x in range(init, term + 1))
prime_numbers = []
for num in integer_list:
if prime_number(num):
prime_numbers.append(num)
print(prime_numbers)
prime(10, 19)
[11, 13, 17, 19]
Q2. 영화의 컨텐츠 등급을 예측하는 모델 구축하고, 성능 평가하기
topic : 데이터전처리(결측치 처리 / 표준화 / 데이터프레임 병합), 시각화, 분류 모델, 앙상블 모델, 교차 검증
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
data = pd.read_csv(r'C:\Users\zhiyu\OneDrive - 한양대학교\[2020-2] BITAmin\정규 세션\12주차 - 기말고사/movie.csv')
data.head()
아직 표를 예쁘게 넣는 방법을 모르겠다 😕 html 로 넣으니까 데이터프레임 개못생김
- 데이터 프레임 전처리 과정 : 결측치(Null or NaN)는 평균값, 최빈값, 삭제 등의 과정을 거쳐서 정제하였음
import numpy as np
### column 날리기
data.drop(['actor_2_name','actor_2_facebook_likes', 'actor_3_name', 'actor_3_facebook_likes' ,'movie_imdb_link', 'plot_keywords'], axis = 1, inplace = True)
### 결측치 확인
print(data.isnull().sum())
### 확인 후 'color','gross'는 결측치 날리기
data.dropna(subset= ['color'], inplace= True)
data.dropna(subset= ['gross'], inplace= True)
### budget의 결측치는 평균값으로 대치
data['budget'] = data['budget'].fillna(data['budget'].mean())
color 19
director_name 102
num_critic_for_reviews 49
duration 15
director_facebook_likes 102
actor_1_facebook_likes 7
gross 862
genres 0
actor_1_name 7
movie_title 0
num_voted_users 0
cast_total_facebook_likes 0
facenumber_in_poster 13
num_user_for_reviews 21
language 12
country 5
content_rating 300
budget 484
title_year 106
imdb_score 0
aspect_ratio 326
movie_facebook_likes 0
dtype: int64
### content_rating 열에 대한 결측치 처리
sns.countplot(x = 'content_rating', data = data) ### 최빈값은 R임을 확인
data['content_rating'] = data['content_rating'].fillna('R')
### 최종 확인
print(data.isnull().sum())
color 0
director_name 2
num_critic_for_reviews 3
duration 2
director_facebook_likes 2
actor_1_facebook_likes 4
gross 0
genres 0
actor_1_name 4
movie_title 0
num_voted_users 0
cast_total_facebook_likes 0
facenumber_in_poster 6
num_user_for_reviews 1
language 3
country 0
content_rating 0
budget 0
title_year 2
imdb_score 0
aspect_ratio 104
movie_facebook_likes 0
dtype: int64
=> 그럼에도 아직 결측치가 남아있는 모습 ... 그래서 밑에서 계속 결측치와의 싸움을 하게 됨
- 정수형 데이터를 구간을 나누고 카테고리형 데이터로 변환하는 작업 (np.histogram, pd.cut 활용)
import numpy as np
#구간 나눌 bin_dividers 정하기
data2[data2['aspect_ratio'].isnull()] #NaN값이 있다
plt.xticks(rotation = - 45)
sns.countplot(x = 'aspect_ratio', data = data2) #그래프 그려보면 하한(1.18) ~ 1.85,1.85~ 2.35, 2.35 ~ 상한(2.76)
### 범주 나누기
bin_names= ['norrow','standard','wide']
bin_dividers = [1.18, 1.85, 2.35, 2.76] #countplot을 보고 임의로 정함
#print(bin_dividers)
###'aspect_ratio2' 열 만들기
data2['aspect_ratio2'] = pd.cut(x=data2['aspect_ratio'],
bins = bin_dividers,
labels=bin_names,
include_lowest=True)
features = pd.DataFrame(data2[['movie_title','director_name']])
#features
temp = pd.get_dummies(data2['aspect_ratio2'])
features = pd.concat([features, temp], axis = 1)
features
=> count, bin_dividers = np.histogram(~)의 과정으로 구간값을 뽑으려고 했는데 결측치가 있어서 안됐다.
똑같이 결측치 처리 과정을 거친 후에 돌리면 해결했을 문제이긴 한데, 의미없이 임의의 값 배정하는 것보단 그냥 countplot으로 구간값 내가 고르는게 낫겠다는 생각이 들어서 빈도그래프 보고 bin_dividers에 숫자는 임의로 정의함.
- 계속 전처리 중...
#code here..
director_mean_group = data2.groupby(['director_name']).mean()
df_g_by_name = director_mean_group[['gross','duration','budget','imdb_score']]
#감독별로 평균 구해진 데이터프레임
features = pd.merge(features, df_g_by_name, on='director_name', how='outer')
features.isnull().sum() #아직도 duration에 결측치가 있음.
features[features['duration'].isnull()] #2개의 결측치는 duration 평균값으로 채워줬음.
features['duration'] = features['duration'].fillna(features['duration'].mean())
features.rename(columns = {'gross': 'gross_mean', 'duration':'duration_mean',
'budget':'budget_mean','imdb_score':'imdb_score_mean'}, inplace=True)
features.isnull().sum()
전처리가 거의 다 끝났다 !!! 이제는 모델 구축 뿐이다.
번외 ) 상관계수 파악
correl = features.corr()
plt.figure(figsize=(8,7))
sns.heatmap(data = correl, annot=True, cmap='Reds')
plt.show()
- 전처리 방식에서 차이가 났기 때문인지 지문에서 제시된 히트맵과는 약간 다른 분포를 보였지만, 정답은 없으니.
- 데이터 표준화
temp = data2[['movie_title','content_rating']]
features = pd.merge(features, temp, on='movie_title', how='inner')
features
X = features[['norrow', 'standard', 'wide', 'duration_mean','gross_mean','budget_mean','imdb_score_mean']]
Y = features['content_rating']
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit_transform(X)
X.describe()
- 데이터 학습 및 평가 (1) 개별 모델
import warnings
warnings.filterwarnings("ignore")
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
sv_clf = SVC()
dt_clf = DecisionTreeClassifier()
rt_clf = RandomForestClassifier()
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size = 0.3, random_state = 10)
model_list = [rt_clf, sv_clf, dt_clf]
for model in model_list:
model.fit(X_train, y_train)
pred = model.predict(X_test)
print("test set {} 분류기 정확도 : {:.4f}".format(model, accuracy_score(pred, y_test)))
첫 번째 : 개별적으로 모델 학습 후의 테스트셋으로 성능 평가한 결과
test set RandomForestClassifier() 분류기 정확도 : 0.5845
test set SVC() 분류기 정확도 : 0.5261
test set DecisionTreeClassifier() 분류기 정확도 : 0.5261
- 데이터 학습 및 평가 (2) 앙상블 모델 - VotingClassifier
from sklearn.ensemble import VotingClassifier
vo_clf = VotingClassifier(estimators=[('DT', dt_clf),('SVM', sv_clf),('RT', rt_clf)])
vo_clf.fit(X_train, y_train)
pred = vo_clf.predict(X_test)
print('Voting 분류기 정확도: {0:.4f}'.format(accuracy_score(y_test, pred)))
Voting 분류기 정확도: 0.5706
- 교차검증 with cross_val_score() API
from sklearn.model_selection import cross_val_score, StratifiedKFold
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state = 777)
scores = cross_val_score(vo_clf, X, Y, scoring='accuracy', cv = skf)
print('교차 검증별 정확도 : ', np.round(scores, 4))
print('평균 검증 정확도 : ', np.round(np.mean(scores), 4))
출력 :
교차 검증별 정확도 : [0.5431 0.5725 0.5686 0.566 0.5817]
평균 검증 정확도 : 0.5664
데이터 분석의 80%이상은 데이터 전처리가 차지한다던데, 역시 시험 치는 당시에도 복습과제로 못한 부분 마무리하던 상황까지도 데이터전처리에서 시간 다 썼다. 더 꼼꼼하게 공부하기 ! 모델은 사실 정해진 키워드대로, 공식대로 써버리면 그만이지만 전처리야 말로 내가 생각한대로 모델이 씹을 수 있도록 다져주는 작업이니 확인할 부분이 참 많다.
'통계학 > BITAmin' 카테고리의 다른 글
unicodedecodeerror: 'utf-8' codec can't decode byte 0xc3 in position 9382: invalid continuation byte (오류해결?) (0) | 2021.07.18 |
---|---|
13주차 - (1) : 불균형데이터의 처리 (0) | 2021.01.21 |
11주차 : Bagging, Boosting - AdaBoost, GBM, XGBoost, LightGBM (0) | 2021.01.04 |
10주차 복습 : KNN, SVM, Ensemble (0) | 2020.12.11 |
댓글