머신러닝/machine learning

classification, decision tree, entropy, 지니계수, information gain

Olivia-BlackCherry 2023. 5. 17. 23:07

목차

    decision tree

    결정 트리라고 부른다. 

    수많은 데이터셋을 일정한 기준으로 계속하여 분류해 나가서, 최종적으로 가장 pure한 분류값을 얻는 게 목표이다.

     

    어떻게 분류하는가?

    이 말은 어떤 속성을 기준으로 분류하는가?와 같은 질문이다.

     

    여러 개의 속성 attribute 중, 하나를 골라서 분류한다.

    그 속성을 고르는 기준은 아래와 같다.

    less impurity(불순물), lower entropy, more predictiveness(예측)

     

    entropy

    measure of randomness(무작위성) or uncertainty(불확실성)

    무작위성과 불확실성을 측정하여, 그 집단이 얼마나 동질성(균일성)을 갖는지 계산한다.

    ex)aaaaaab동질성(균일성) 높음, aabbaab동질성(균일성) 낮음

     

    즉, 분류 후 집단이 우연적으로 구성된 것이 아니라 특정 근거를 바탕으로 구성된 것을 의미하며

    이를 엔트로피가 낮다고 표현한다. 

    decision tree에서 적절한 attribute는 entropy가 낮은 것을 의미한다.

    예) decision tree모델로 여러 sample들을 '학교'를 기준으로 categorize했을 때 

    5 남, 5 여로 나뉘었다면 entropy는 1이 된다. 균일성이 낮다.

    1 남, 9 여로 나뉘었다면 entropy는 낮다. 균일성이 높다.

    0 남, 10 여로 나뉘었다면 entropy는 0이다. 균일성이 없다.

     

    엔트로피가 낮은 attribute로 데이터를 쪼개고, 자식 트리로 내려가며 또 엔트로피가 낮은 attribute로 데이터를 쪼개며 최종 데이터 값을 예측한다. 

     

    information gain

    엔트로피가 다른 노드로 결합된 여러 종류의 decision tree가 있다. 어떤 모델을 골라야할까?

    이 경우 분할 후 information gain(정보 이득)이 많은 트리를 선택한다. 

    information gain이란 분할 후, 확신도가 증가하는 정보이다. 

    분할 전 총 entropy에서 분할 후 엔트로피(각 노드마다 가중치곱)를 뺀 것이다. 

    아래의 경우 sex가 분류 기준이 되는 decision tree가 정보이득이 많으므로, 더 좋은 모델이 된다.

     

     

     

    지니계수

    정보이득 대신 지니계수를 사용하기도 한다. 

    지니계수란 원래 경제학에서 불평등 지수를 나타낼 때 사용하는 계수이다. 0이 가장 평등하고, 1로 갈수록 불평등하다. 

    지니 계수가 낮을 수록 평등하니, 균일도가 높고 엔트로피가 낮다고 해석해서, 지니 계수가 낮은 attribute를 기준으로 분할해나간다.

     

     

    장점과 단점

    장점 : 쉽고, 직관적이며, preprocessing 작업을 크게 하지 않아도 된다.

     

    단점 : 완벽하게 데이터셋을 분류하지 못하는 것이 당연함에도, 결정 트리는 계속하여 분류 기준을 세우고 분류를 진행해나가며 overfitting을 유발할 수 있다 .과적합은 알고리즘 성능이 떨어지므로, 트리의 크기를 사전에 제한하는 튜닝이 필요하다. 

     

    # 데이터 탐색
    my_data.columns
    my_data.size
    my_data.shape
    
    # 데이터 전처리
    # target value만 제거하고 나머지를 X에 저장한다.
    X = my_data[['Age', 'Sex', 'BP', 'Cholesterol', 'Na_to_K']].values
    X[0:5]
    
    # Categoricla -> binary하게 0,1로
    from sklearn import preprocessing
    le_sex = preprocessing.LabelEncoder()
    le_sex.fit(['F','M'])
    X[:,1] = le_sex.transform(X[:,1]) 
    print(X[:,1])
    
    # low, normal, high--> 0,1,2로 
    le_BP = preprocessing.LabelEncoder()
    le_BP.fit([ 'LOW', 'NORMAL', 'HIGH'])
    X[:,2] = le_BP.transform(X[:,2])
    
    # normal, high--> 0,1로 
    le_Chol = preprocessing.LabelEncoder()
    le_Chol.fit([ 'NORMAL', 'HIGH'])
    X[:,3] = le_Chol.transform(X[:,3]) 
    
    X[0:5]
    
    # target data
    y = my_data["Drug"]
    y[0:5]
    
    #데이터분석
    #train/test split
    from sklearn.model_selection import train_test_split
    X_trainset, X_testset, y_trainset, y_testset = train_test_split(X, y, test_size=0.3, random_state=3)
    
    #모델링
    drugTree = DecisionTreeClassifier(criterion="entropy", max_depth = 4)
    drugTree.fit(X_trainset,y_trainset)
    
    # prediction
    predTree = drugTree.predict(X_testset)
    print (predTree [0:5])
    print (y_testset [0:5])
    
    #Evaluation
    from sklearn import metrics
    import matplotlib.pyplot as plt
    print("DecisionTrees's Accuracy: ", metrics.accuracy_score(y_testset, predTree))
    
    #Visualization
    !conda install -c conda-forge pydotplus -y
    !conda install -c conda-forge python-graphviz -y
    tree.plot_tree(drugTree)
    plt.show()