In [ ]:
# 주석 처리된 부분에 채워 넣어야하는 코드의 설명이 담겨있으니 잘 확인해주세요!
#### 이런 식으로 되어있는 부분은 코드를 채워 넣어햐 하는 부분이니 꼭 꼼꼼히 살펴봐주세요!!
In [11]:
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings('ignore')

# DecisionTree Classifier 생성
dt_clf = ####################(random_state=156)

# 붓꽃 데이터를 로드하세요.
# train과 test 데이터의 비율을 8대 2로 나누고 randonm_state는 11로 고정해주세요.

# DecisionTreeClassifer에 train 데이터를 학습시키세요.
Out[11]:
DecisionTreeClassifier(random_state=156)
In [4]:
from sklearn.tree import export_graphviz

# export_graphviz()의 호출 결과로 out_file로 지정된 tree.dot 파일을 생성함.
export_graphviz(dt_clf, out_file="tree.dot", class_names=iris_data.target_names, \
                feature_names = iris_data.feature_names, impurity=True, filled=True)
In [6]:
import graphviz

# 위에서 생성된 tree.dot 파일을 Graphviz가 읽어서 주피터 노트북상에서 시각화
# ####이라고 표시된 부분에 알맞는 코드로 바꿔주세요.

#### ####("tree.dot") as f:
    dot_graph = f.read()
graphviz.Source(dot_graph)
Out[6]:
Tree 0 petal length (cm) <= 2.45 gini = 0.667 samples = 120 value = [41, 40, 39] class = setosa 1 gini = 0.0 samples = 41 value = [41, 0, 0] class = setosa 0->1 True 2 petal width (cm) <= 1.55 gini = 0.5 samples = 79 value = [0, 40, 39] class = versicolor 0->2 False 3 petal length (cm) <= 5.25 gini = 0.051 samples = 38 value = [0, 37, 1] class = versicolor 2->3 6 petal width (cm) <= 1.75 gini = 0.136 samples = 41 value = [0, 3, 38] class = virginica 2->6 4 gini = 0.0 samples = 37 value = [0, 37, 0] class = versicolor 3->4 5 gini = 0.0 samples = 1 value = [0, 0, 1] class = virginica 3->5 7 sepal length (cm) <= 5.45 gini = 0.5 samples = 4 value = [0, 2, 2] class = versicolor 6->7 12 petal length (cm) <= 4.85 gini = 0.053 samples = 37 value = [0, 1, 36] class = virginica 6->12 8 gini = 0.0 samples = 1 value = [0, 0, 1] class = virginica 7->8 9 petal length (cm) <= 5.45 gini = 0.444 samples = 3 value = [0, 2, 1] class = versicolor 7->9 10 gini = 0.0 samples = 2 value = [0, 2, 0] class = versicolor 9->10 11 gini = 0.0 samples = 1 value = [0, 0, 1] class = virginica 9->11 13 sepal length (cm) <= 5.95 gini = 0.444 samples = 3 value = [0, 1, 2] class = virginica 12->13 16 gini = 0.0 samples = 34 value = [0, 0, 34] class = virginica 12->16 14 gini = 0.0 samples = 1 value = [0, 1, 0] class = versicolor 13->14 15 gini = 0.0 samples = 2 value = [0, 0, 2] class = virginica 13->15
In [16]:
import seaborn as sns
import numpy as np
%matplotlib inline

# feature importance 추출
print("Feature importances:\n{0}".format(np.round(dt_clf.feature_importances_, 3)))

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

# barplot으로 feature importance를 시각화 하세요.
Feature importances:
[0.025 0.    0.555 0.42 ]
sepal length (cm) : 0.025
sepal width (cm) : 0.000
petal length (cm) : 0.555
petal width (cm) : 0.420
Out[16]:
<AxesSubplot:>
In [27]:
from sklearn.datasets import make_classification
import matplotlib.pyplot as plt
%matplotlib inline

# 그래프 제목을 '3 Class values with 2 Features Sample data creation'로 생성해주세요.

# 2차원 시각화를 위해서 피처는 2개, 클래스는 3가지 유형의 분류 샘플 데이터 생성.
X_features, y_labels = make_classification(n_features=2, n_redundant=0, n_informative=2, n_classes=3, n_clusters_per_class=1, random_state=0)

# 그래프 형태로 2개의 피처로 2차원 좌표 시각화, 각 클래스 값은 다른 색깔로 표시됨.
plt.scatter(X_features[:, 0], X_features[:,1], marker='o', c=y_labels, s=25, edgecolor='k')
Out[27]:
<matplotlib.collections.PathCollection at 0x2d499dcd3d0>
In [31]:
import numpy as np

# Classifier의 Decision Boundary를 시각화 하는 함수
def visualize_boundary(model, X, y):
    fig,ax = plt.subplots()
    
    # 학습 데이타 scatter plot으로 나타내기
    ax.scatter(X[:, 0], X[:, 1], c=y, s=25, cmap='rainbow', edgecolor='k',
               clim=(y.min(), y.max()), zorder=3)
    ax.axis('tight')
    ax.axis('off')
    xlim_start , xlim_end = ax.get_xlim()
    ylim_start , ylim_end = ax.get_ylim()
    
    # 호출 파라미터로 들어온 training 데이타로 model 학습 . 
    model.fit(X, y)
    # meshgrid 형태인 모든 좌표값으로 예측 수행. 
    xx, yy = np.meshgrid(np.linspace(xlim_start,xlim_end, num=200),np.linspace(ylim_start,ylim_end, num=200))
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
    
    # contourf() 를 이용하여 class boundary 를 visualization 수행. 
    n_classes = len(np.unique(y))
    contours = ax.contourf(xx, yy, Z, alpha=0.3,
                           levels=np.arange(n_classes + 1) - 0.5,
                           cmap='rainbow', clim=(y.min(), y.max()),
                           zorder=1)
In [32]:
from sklearn.tree import DecisionTreeClassifier

# 특정한 트리 생성 제약 없는 결정 트리의 학습과 결정 경계 시각화.
dt_clf = DecisionTreeClassifier(random_state=156).fit(X_features, y_labels)

# 위에 작성된 visualize_boundary 함수를 사용하여 그래프를 시각화하세요.
In [33]:
# 위에 코드를 참고하여 min_samples_leaf=6 으로 트리 생성 조건을 제약한 Decision Boundary 시각화하세요.
In [ ]:
# UCI에서 Human Activity Recognition Using Smartphones 데이터 파일을 다운로드 받은 뒤 다음 과정을 진행하세요!
# 데이터 셋을 자세히 살펴보시면 X_train 이런 식으로도 다 나눠져 있으므로 꼼꼼히 살펴보신 뒤 해당하는 데이터 셋을 불러오세요!
In [44]:
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

# features.txt 파일에는 피처 이름 index와 피처명이 공백으로 분리되어 있음. 이를 DataFrame으로 로드.
feature_name_df = pd.read_csv('features.txt',sep='\s+',
                        header=None,names=['column_index','column_name'])

# feature_name_df에서 index를 제거하고, 피처명만 리스트 객체로 생성해주세요.
# 생성한 리스트 객체의 10개만 추출해서 출력하세요.
feature_name_df.head(20)
전체 피처명에서 10개만 추출: ['tBodyAcc-mean()-X', 'tBodyAcc-mean()-Y', 'tBodyAcc-mean()-Z', 'tBodyAcc-std()-X', 'tBodyAcc-std()-Y', 'tBodyAcc-std()-Z', 'tBodyAcc-mad()-X', 'tBodyAcc-mad()-Y', 'tBodyAcc-mad()-Z', 'tBodyAcc-max()-X']
Out[44]:
column_index column_name
0 1 tBodyAcc-mean()-X
1 2 tBodyAcc-mean()-Y
2 3 tBodyAcc-mean()-Z
3 4 tBodyAcc-std()-X
4 5 tBodyAcc-std()-Y
5 6 tBodyAcc-std()-Z
6 7 tBodyAcc-mad()-X
7 8 tBodyAcc-mad()-Y
8 9 tBodyAcc-mad()-Z
9 10 tBodyAcc-max()-X
10 11 tBodyAcc-max()-Y
11 12 tBodyAcc-max()-Z
12 13 tBodyAcc-min()-X
13 14 tBodyAcc-min()-Y
14 15 tBodyAcc-min()-Z
15 16 tBodyAcc-sma()
16 17 tBodyAcc-energy()-X
17 18 tBodyAcc-energy()-Y
18 19 tBodyAcc-energy()-Z
19 20 tBodyAcc-iqr()-X
In [45]:
def get_new_feature_name_df(old_feature_name_df):
    feature_dup_df = pd.DataFrame(data=old_feature_name_df.groupby('column_name').cumcount(), columns=['dup_cnt'])
    feature_dup_df = feature_dup_df.reset_index()
    new_feature_name_df = pd.merge(old_feature_name_df.reset_index(), feature_dup_df, how='outer')
    new_feature_name_df['column_name'] = new_feature_name_df[['column_name', 'dup_cnt']].apply(lambda x : x[0]+'_'+str(x[1]) 
                                                                                           if x[1] >0 else x[0] ,  axis=1)
    new_feature_name_df = new_feature_name_df.drop(['index'], axis=1)
    return new_feature_name_df

pd.options.display.max_rows = 999

# 위에 함수를 사용하여 feature_name_df를 바꾼 것을 new_feature_name_df 라는 변수에 저장해 주세요.
# new_feature_name_df에서 dup_cut이 0보다 큰 경우 출력해주세요.
Out[45]:
column_index column_name dup_cnt
316 317 fBodyAcc-bandsEnergy()-1,8_1 1
317 318 fBodyAcc-bandsEnergy()-9,16_1 1
318 319 fBodyAcc-bandsEnergy()-17,24_1 1
319 320 fBodyAcc-bandsEnergy()-25,32_1 1
320 321 fBodyAcc-bandsEnergy()-33,40_1 1
321 322 fBodyAcc-bandsEnergy()-41,48_1 1
322 323 fBodyAcc-bandsEnergy()-49,56_1 1
323 324 fBodyAcc-bandsEnergy()-57,64_1 1
324 325 fBodyAcc-bandsEnergy()-1,16_1 1
325 326 fBodyAcc-bandsEnergy()-17,32_1 1
326 327 fBodyAcc-bandsEnergy()-33,48_1 1
327 328 fBodyAcc-bandsEnergy()-49,64_1 1
328 329 fBodyAcc-bandsEnergy()-1,24_1 1
329 330 fBodyAcc-bandsEnergy()-25,48_1 1
330 331 fBodyAcc-bandsEnergy()-1,8_2 2
331 332 fBodyAcc-bandsEnergy()-9,16_2 2
332 333 fBodyAcc-bandsEnergy()-17,24_2 2
333 334 fBodyAcc-bandsEnergy()-25,32_2 2
334 335 fBodyAcc-bandsEnergy()-33,40_2 2
335 336 fBodyAcc-bandsEnergy()-41,48_2 2
336 337 fBodyAcc-bandsEnergy()-49,56_2 2
337 338 fBodyAcc-bandsEnergy()-57,64_2 2
338 339 fBodyAcc-bandsEnergy()-1,16_2 2
339 340 fBodyAcc-bandsEnergy()-17,32_2 2
340 341 fBodyAcc-bandsEnergy()-33,48_2 2
341 342 fBodyAcc-bandsEnergy()-49,64_2 2
342 343 fBodyAcc-bandsEnergy()-1,24_2 2
343 344 fBodyAcc-bandsEnergy()-25,48_2 2
395 396 fBodyAccJerk-bandsEnergy()-1,8_1 1
396 397 fBodyAccJerk-bandsEnergy()-9,16_1 1
397 398 fBodyAccJerk-bandsEnergy()-17,24_1 1
398 399 fBodyAccJerk-bandsEnergy()-25,32_1 1
399 400 fBodyAccJerk-bandsEnergy()-33,40_1 1
400 401 fBodyAccJerk-bandsEnergy()-41,48_1 1
401 402 fBodyAccJerk-bandsEnergy()-49,56_1 1
402 403 fBodyAccJerk-bandsEnergy()-57,64_1 1
403 404 fBodyAccJerk-bandsEnergy()-1,16_1 1
404 405 fBodyAccJerk-bandsEnergy()-17,32_1 1
405 406 fBodyAccJerk-bandsEnergy()-33,48_1 1
406 407 fBodyAccJerk-bandsEnergy()-49,64_1 1
407 408 fBodyAccJerk-bandsEnergy()-1,24_1 1
408 409 fBodyAccJerk-bandsEnergy()-25,48_1 1
409 410 fBodyAccJerk-bandsEnergy()-1,8_2 2
410 411 fBodyAccJerk-bandsEnergy()-9,16_2 2
411 412 fBodyAccJerk-bandsEnergy()-17,24_2 2
412 413 fBodyAccJerk-bandsEnergy()-25,32_2 2
413 414 fBodyAccJerk-bandsEnergy()-33,40_2 2
414 415 fBodyAccJerk-bandsEnergy()-41,48_2 2
415 416 fBodyAccJerk-bandsEnergy()-49,56_2 2
416 417 fBodyAccJerk-bandsEnergy()-57,64_2 2
417 418 fBodyAccJerk-bandsEnergy()-1,16_2 2
418 419 fBodyAccJerk-bandsEnergy()-17,32_2 2
419 420 fBodyAccJerk-bandsEnergy()-33,48_2 2
420 421 fBodyAccJerk-bandsEnergy()-49,64_2 2
421 422 fBodyAccJerk-bandsEnergy()-1,24_2 2
422 423 fBodyAccJerk-bandsEnergy()-25,48_2 2
474 475 fBodyGyro-bandsEnergy()-1,8_1 1
475 476 fBodyGyro-bandsEnergy()-9,16_1 1
476 477 fBodyGyro-bandsEnergy()-17,24_1 1
477 478 fBodyGyro-bandsEnergy()-25,32_1 1
478 479 fBodyGyro-bandsEnergy()-33,40_1 1
479 480 fBodyGyro-bandsEnergy()-41,48_1 1
480 481 fBodyGyro-bandsEnergy()-49,56_1 1
481 482 fBodyGyro-bandsEnergy()-57,64_1 1
482 483 fBodyGyro-bandsEnergy()-1,16_1 1
483 484 fBodyGyro-bandsEnergy()-17,32_1 1
484 485 fBodyGyro-bandsEnergy()-33,48_1 1
485 486 fBodyGyro-bandsEnergy()-49,64_1 1
486 487 fBodyGyro-bandsEnergy()-1,24_1 1
487 488 fBodyGyro-bandsEnergy()-25,48_1 1
488 489 fBodyGyro-bandsEnergy()-1,8_2 2
489 490 fBodyGyro-bandsEnergy()-9,16_2 2
490 491 fBodyGyro-bandsEnergy()-17,24_2 2
491 492 fBodyGyro-bandsEnergy()-25,32_2 2
492 493 fBodyGyro-bandsEnergy()-33,40_2 2
493 494 fBodyGyro-bandsEnergy()-41,48_2 2
494 495 fBodyGyro-bandsEnergy()-49,56_2 2
495 496 fBodyGyro-bandsEnergy()-57,64_2 2
496 497 fBodyGyro-bandsEnergy()-1,16_2 2
497 498 fBodyGyro-bandsEnergy()-17,32_2 2
498 499 fBodyGyro-bandsEnergy()-33,48_2 2
499 500 fBodyGyro-bandsEnergy()-49,64_2 2
500 501 fBodyGyro-bandsEnergy()-1,24_2 2
501 502 fBodyGyro-bandsEnergy()-25,48_2 2
In [50]:
import pandas as pd

def get_human_dataset( ):
    
    # feature name_df 라는 변수명으로 features.txt 파일을 데이터 프레임 형식으로 불러오세요.
    
    # get_new_feature_name_df()를 이용하여 중복된 feature명을 수정해주세요.
    
    # feature_name_df에서 index를 제거하고, 피처명만 리스트 객체로 생성해주세요.
    
    # X_train.txt와 X_test.txt 파일을 데이터 프레임 형식으로 불러오고 이때 컬럼명은 feature_name으로 해주세요.
    X_train = 
    X_test = 
    
    # y_train.txt, y_test.txt 파일을 데이터 프레임 형식으로 불러오고 이때 컬럼명은 action으로 해주세요.
    y_train = 
    y_test =
    
    # 로드된 학습/테스트용 DataFrame을 모두 반환 
    return X_train, X_test, y_train, y_test


X_train, X_test, y_train, y_test = ###################
In [51]:
# X_train 데이터의 정보를 출력하세요.
## 학습 피처 데이터셋 info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7352 entries, 0 to 7351
Columns: 561 entries, tBodyAcc-mean()-X to angle(Z,gravityMean)
dtypes: float64(561)
memory usage: 31.5 MB
None
In [52]:
# y_tarin의 action에 있는 값들과 빈도수를 함께 출력하세요.
6    1407
5    1374
4    1286
1    1226
2    1073
3     986
Name: action, dtype: int64
In [53]:
#X_train에 널값이 있는지 확인하세요.
Out[53]:
0
In [54]:
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

# 예제 반복 시 마다 동일한 예측 결과 도출을 위해 random_state를 156으로 설정하세요.
dt_clf = DecisionTreeClassifier(###############)

# train 데이터를 학습시키세요.
# prea라는 변수에 X_test를 예측한 결과 값을 저장하세요.
accuracy = #############(y_test , pred)
print('결정 트리 예측 정확도: {0:.4f}'.format(########))

# DecisionTreeClassifier의 하이퍼 파라미터 출력하세요.
print('DecisionTreeClassifier 기본 하이퍼 파라미터:\n', dt_clf.##########())
결정 트리 예측 정확도: 0.8548
DecisionTreeClassifier 기본 하이퍼 파라미터:
 {'ccp_alpha': 0.0, 'class_weight': None, 'criterion': 'gini', 'max_depth': None, 'max_features': None, 'max_leaf_nodes': None, 'min_impurity_decrease': 0.0, 'min_samples_leaf': 1, 'min_samples_split': 2, 'min_weight_fraction_leaf': 0.0, 'random_state': 156, 'splitter': 'best'}
In [55]:
from sklearn.model_selection import GridSearchCV

params = {
    'max_depth' : [ 6, 8 ,10, 12, 16 ,20, 24]
}

grid_cv = GridSearchCV(dt_clf, param_grid=params, scoring='accuracy', cv=5, verbose=1 )
grid_cv.fit(X_train , y_train)
print('GridSearchCV 최고 평균 정확도 수치:{0:.4f}'.format(grid_cv.best_score_))
print('GridSearchCV 최적 하이퍼 파라미터:', grid_cv.best_params_)
Fitting 5 folds for each of 7 candidates, totalling 35 fits
GridSearchCV 최고 평균 정확도 수치:0.8513
GridSearchCV 최적 하이퍼 파라미터: {'max_depth': 16}
In [57]:
max_depths = [ 6, 8 ,10, 12, 16 ,20, 24]

# max_depth 값을 변화 시키면서 그때마다 학습과 테스트 셋에서의 예측 성능 측정하세요.
for depth in ##########:
    dt_clf = DecisionTreeClassifier(max_depth=#####, random_state=156)
    # 모델에 train 데이터를 학습시키세요.
    # pred라는 변수에 예측한 값을 저장하세요.
    # 정확도를 구하세요.
    print('max_depth = {0} 정확도: {1:.4f}'.format(##### , ########))
max_depth = 6 정확도: 0.8558
max_depth = 8 정확도: 0.8707
max_depth = 10 정확도: 0.8673
max_depth = 12 정확도: 0.8646
max_depth = 16 정확도: 0.8575
max_depth = 20 정확도: 0.8548
max_depth = 24 정확도: 0.8548
In [58]:
params = {
    'max_depth' : [ 8, 12, 16 ,20], 
    'min_samples_split' : [16,24],
}

# 위에 코드를 참고해 최고 평균 정확도 수치와 최적 하이퍼 파라미터를 구하세요.
#
#
print('GridSearchCV 최고 평균 정확도 수치: {0:.4f}'########################)
print('GridSearchCV 최적 하이퍼 파라미터:', ######################)
Fitting 5 folds for each of 8 candidates, totalling 40 fits
GridSearchCV 최고 평균 정확도 수치: 0.8549
GridSearchCV 최적 하이퍼 파라미터: {'max_depth': 8, 'min_samples_split': 16}
In [59]:
best_df_clf = grid_cv.best_estimator_

# 가장 최적 하이퍼 파라미터 일때 X_test를 예측한 값을 pred1로 저장하세요.
# 정확도를 구하세요.
print('결정 트리 예측 정확도:{0:.4f}'############)
결정 트리 예측 정확도:0.8717
In [60]:
import seaborn as sns

ftr_importances_values = best_df_clf.feature_importances_

# Top 중요도로 정렬을 쉽게 하고, 시본(Seaborn)의 막대그래프로 쉽게 표현하기 위해 Series변환
ftr_importances = pd.Series(ftr_importances_values, index=X_train.columns  )

# 중요도값 순으로 Series를 정렬하세요.
ftr_top20 = ftr_importances.###########(ascending=#####)[:20]
# Feature importances Top 20 제목으로 그래프를 시각화하세요.
In [ ]: