ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [결정 트리 분석] 센서 데이터로 움직임 분류하기
    DataAnalysis/모델 분석 2022. 6. 2. 12:02

    <개념>

    1. 결정 트리

    -다중 분류에 많이 사용

    -데이터 안에서 if/else기반으로 규칙을 찾아 학습하여 트리 구조의 분류 구칙을 만듦

    -결정 트리의 구조는 규칙 조건(if)을 나타내는 규칙노드, 분류가 결정된 클래스 값이 표시된 리프 노드로 구성

    -데이터의 균일도를 계산하는 대표적인 방법으로 정보 이득 지수, 지니 계수가 있음

     

    2. 정보 이득 지수

    -정보 이득은 엔트로피 개념을 기반으로함

    -엔트로피: 데이터 집합의 혼잡도

    -데이터 집합에 다른 데이터= 균일도가 떨어짐-> 혼잡도 높아짐 -> 엔트로피 높아짐

    -데이터 집합에 같은 데이터= 균일도가 높아짐-> 혼잡도 떨어짐 -> 엔트로피 낮아짐

    -정보 이득 지수: 혼잡도가 줄어들며 얻게 되는 이득, 1-엔트로피

    -결정 트리: 정보 이득 지수가 높은 피처를 분할 기준으로 사용

     

    3.지니 계수

    -소득의 불균형 정도를 나타내는 것, 머신러닝에서 지니 계수는 데이터의 순도를 나타내기 위해 사용

    -결정 트리에서는 지니 계수가 높을수록 순도가 낮은 데이터 집합을 의미

    -지니 계수가 0이면 완전 순수한 데이터 집합

     

    4.DecisionTreeClassife: 사이킷런에서 제공하는 결정 트리 분류 모델

    5.Graphivz: 패키지 결정 트리 시각화에서 사용하는 패키지

     

    <프로젝트>

    목표: 스마트폰에서 수집한 센서 데이터를 분석하여 사람의 움직임을 분류 하는 모델을 생성하고 새로운 데이터에 대해 움직임 유형을 예측해서 분류

    ■ 데이터 탐색

    feature_name_df= pd.read_csv('./UCI_HAR_Dataset/features.txt', sep= '\s+',header = None, names = ['index',
    'feature_name'], engine = 'python')
    
    
    feature_name_list = feature_name_df.iloc[:, 1].values.tolist()
    
    feature_name = range(0, 561)

     

    X_train= pd.read_csv('./UCI_HAR_Dataset/train/X_train.txt', sep='\s+', names = feature_name, engine = 'python')
    X_test= pd.read_csv('./UCI_HAR_Dataset/test/X_test.txt', sep='\s+', names = feature_name, engine = 'python')
    Y_train= pd.read_csv('./UCI_HAR_Dataset/train/y_train.txt', sep='\s+', header = None,names = ['action'], engine = 'python')
    Y_test= pd.read_csv('./UCI_HAR_Dataset/test/y_test.txt' , sep= '\s+', header = None,names = ['action'], engine = 'python')
    label_name_df= pd.read_csv('./UCI_HAR_Dataset/activity_labels.txt',sep= '\s+', header = None, names = ['index', 'label'], engine = 'python')
    label_name= label_name_df.iloc[:, 1].values.tolist()
    label_name

    ■ 분석 모델 구축 및 결과 분석

    from sklearn.tree import DecisionTreeClassifier
    dt_HAR= DecisionTreeClassifier(random_state=156)
    dt_HAR.fit(X_train, Y_train)
    
    Y_predict = dt_HAR.predict(X_test)
    Y_train_predict = dt_HAR.predict(X_train)
    from sklearn.metrics import accuracy_score
    
    accuracy1 = accuracy_score( Y_train, Y_train_predict)
    accuracy = accuracy_score( Y_test, Y_predict)
    print('결정트리예측정확도: {0:.4f}'.format(accuracy1))
    print('결정트리예측정확도: {0:.4f}'.format(accuracy))

     

    파이퍼 매개변수 중에서 criterion='gini'는 분할 기준으로 지니 계수를 사용한다는 의미

    print('결정 트리의 현재 하이퍼 매개변수 : \n',dt_HAR.get_params())

     

    => 결정 트리 모델의 하이퍼 매개변수를 수정하면 정확도를 높일 수 있다.

     

     

    정확도를 검사하여 최적의 하이퍼 매개변수를 찾는 작업을 해주는 GridSerchCV모듈 사용

    1)max_depth 이용

    from sklearn.model_selection import GridSearchCV
    params= {
    'max_depth' : [6, 8, 10, 12, 16, 20, 24]
    }
    grid_cv= GridSearchCV(dt_HAR, param_grid= params, scoring =
    'accuracy', cv = 5, return_train_score= True)
    grid_cv.fit(X_train, Y_train)
    cv_results_df= pd.DataFrame(grid_cv.cv_results_)
    cv_results_df[['param_max_depth', 'mean_test_score', 'mean_train_score']]
    print('최고평균정확도: {0:.4f}, 최적하이퍼매개변수: {1}'.format(grid_cv.best_score_, grid_cv.best_params_))

    GridSearchCV를 사용하여 결정 트리의 하이퍼 매개변수 중에서 트리의 깊이를 6,8,10,12,16,20,24로 변경하면서 결정 트리 모델 7개를 생성하여 모델 학습

     

     

    2)max_depth와 함께 min_samples_splict을 조정하면서 최고의 평균 정확도를 확인

    params= {
    'max_depth' : [8, 16, 20],
    'min_samples_split' : [8, 16, 24]
    }
    grid_cv= GridSearchCV(dt_HAR, param_grid= params, scoring =
    'accuracy', cv = 5, return_train_score= True)
    grid_cv.fit(X_train, Y_train)
    
    cv_results_df= pd.DataFrame(grid_cv.cv_results_)
    cv_results_df[['param_max_depth', 'param_min_samples_split', 'mean_test_score', 'mean_train_score']]
    print('최고평균정확도: {0:.4f}, 최적하이퍼매개변수: {1}'.format(grid_cv.best_score_, grid_cv.best_params_))

    여기서 구한 최적 하이퍼 매개변수인 max_depth=8, min_split=16으로 학습된 모델은 grid_cv의 best_estimator_속성에 저장

     

     

     

    최적 모델 grid_cv.best_estimator_을 사용하여 테스트 데이터에 대한 예측 수행

    best_dt_HAR= grid_cv.best_estimator_
    best_Y_predict= best_dt_HAR.predict(X_test)
    best_accuracy= accuracy_score(Y_test, best_Y_predict)
    print('best 결정트리예측정확도: {0:.4f}'.format(best_accuracy))

    결과: 예측 정확도가 높아짐

    best 결정트리예측정확도: 0.8717

    +)

    #https://todayisbetterthanyesterday.tistory.com/51
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.metrics import accuracy_score # 정확도 함수
    
    clf = RandomForestClassifier(n_estimators=100, max_depth=8,random_state=0)
    clf.fit(X_train, Y_train)
    
    predict1 = clf.predict(X_test)
    print(accuracy_score(Y_test,predict1))

     

     

     

    feature_importances_ 속성을 사용하여 각 피처의 중요도 파악

    import seaborn as sns
    import matplotlib.pyplot as plt
    feature_importance_values= best_dt_HAR.feature_importances_
    feature_importance_values_s= pd.Series(feature_importance_values,index = X_train.columns)
    
    feature_top10 = feature_importance_values_s.sort_values(ascending = False)[:10]
    feature_name_string =[]
    for index in feature_top10.index: 
        feature_name_string.append(feature_name_list[index])
    
    feature_top10.index=feature_name_string
    plt.figure(figsize= (10, 5))
    plt.title('Feature Top 10')
    sns.barplot(x = feature_top10, y = feature_top10.index)
    plt.show()

     

     

    ■결정 트리 모델의 트리 구조를  시각화

    from sklearn.tree import export_graphviz
    #export_graphviz()의호출결과로out_file로지정된tree.dot 파일생성
    export_graphviz(best_dt_HAR, out_file= "tree.dot", class_names= label_name, feature_names= feature_name, impurity = True, filled = True)
    
    import graphviz
    #위에서생성된tree.dot 파일을Graphviz가읽어서시각화
    with open("tree.dot") as f:
        dot_graph = f.read()
    graphviz.Source(dot_graph)

     

     

     

    출처: 데이터 과학 기반의 파이썬 빅데이터 분석(이지은 지음)책을 공부하며 작성한 내용입니다.

Designed by Tistory.