RandomForestClassifier의 feature_importances는 어떻게 결정됩니까?


125

데이터 입력으로 시계열이있는 분류 작업이 있는데 각 속성 (n = 23)은 특정 시점을 나타냅니다. 절대 분류 결과 외에도 어떤 속성 / 날짜가 결과에 어느 정도 기여하는지 알아 내고 싶습니다. 따라서 나는 단지 feature_importances_나를 사용하고 있습니다.

그러나 계산 방법과 사용되는 측정 / 알고리즘을 알고 싶습니다. 불행히도이 주제에 관한 문서를 찾을 수 없었습니다.


10
하나의 SO 스레드에 3 개의 핵심 개발자가 있습니다. 그것은 일종의 기록이어야합니다 ^^
Andreas Mueller

답변:


158

기능 "중요도"를 얻는 방법에는 여러 가지가 있습니다. 종종이 단어의 의미에 대한 엄격한 합의가 없습니다.

scikit-learn에서는 [1]에 설명 된대로 중요도를 구현합니다 (종종 인용되었지만 안타깝게도 거의 읽지 않습니다 ...). "중요도"또는 "평균 감소 불순물"이라고도하며 노드 전체의 평균 감소 (노드에 도달 할 확률에 의해 가중 됨 (노드에 도달 한 샘플의 비율에 의해 추정 됨))로 정의됩니다. 앙상블의 나무.

문헌 또는 기타 패키지에서 "평균 정확도 감소"로 구현 된 기능 중요도를 찾을 수 있습니다. 기본적으로 아이디어는 해당 기능의 값을 임의로 치환 할 때 OOB 데이터의 정확도 감소를 측정하는 것입니다. 감소가 낮 으면이 기능은 중요하지 않으며 그 반대도 마찬가지입니다.

(두 알고리즘 모두 randomForest R 패키지로 제공됩니다.)

[1] : Breiman, Friedman, "분류 및 회귀 트리", 1984.


48
이 속성이 중요도 속성 / 예제 문서에 언급되어 있으면 좋을 것입니다. 그것도 한동안 그것을 찾고 있었다 :)
d1337

2
중요도 점수가 상대 가치 인 것 같습니까? 예를 들어, 모든 기능의 중요도 점수의 합계는 항상 1입니다 (여기의 예제 참조 scikit-learn.org/stable/auto_examples/ensemble/… )
RNA

5
@RNA : 그렇습니다. 기본적으로 변수 중요도는 scikit-learn에서 정규화되어 하나로 합쳐집니다. 개별 기본 추정기를 반복하고을 호출하여이를 피할 수 있습니다 tree_.compute_feature_importances(normalize=False).
Gilles Louppe

2
@GillesLouppe 가방 외부 샘플을 사용하여 각 트리의 의사 결정 트리 회귀 자 포리스트에 대한 MSE 감소를 측정합니까? 아니면 나무에 사용 된 모든 훈련 데이터?
코크

1
두 가지 유용한 자료. (1) blog.datadive.net/… Ando Saabas의 블로그는 Gilles가 언급 한 것처럼 "평균 감소 불순물"과 "평균 정확도 감소"를 모두 구현합니다. (2) Gilles Louppe의 논문을 다운로드하여 읽으십시오.
Mark Teese

54

단일 트리의 기능 중요도 값을 계산하는 일반적인 방법은 다음과 같습니다.

  1. feature_importancessize로 모든 0 의 배열을 초기화합니다 n_features.

  2. 피쳐를 분할하는 각 내부 노드 i에 대해 노드로 라우팅 된 샘플 수를 곱한 노드의 오류 감소를 계산하고이 수량을에 추가합니다 feature_importances[i].

오차 감소는 사용하는 불순물 기준 (예 : Gini, Entropy, MSE 등)에 따라 다릅니다. 내부 노드로 라우팅되는 예제 세트의 불순물에서 분할에 의해 생성 된 두 파티션의 불순물의 합을 뺀 것입니다.

이러한 값은 특정 데이터 세트에 상대적이어야하며 (오류 감소 및 샘플 수는 데이터 세트에 따라 다름) 이러한 값을 다른 데이터 세트간에 비교할 수 없습니다.

내가 아는 한 의사 결정 트리에서 기능 중요도 값을 계산하는 다른 방법이 있습니다. 위의 방법에 대한 간단한 설명은 Trevor Hastie, Robert Tibshirani 및 Jerome Friedman의 "Statistical Learning의 요소"에서 찾을 수 있습니다.


12

트레이닝 세트의 총 샘플 수에 대한 앙상블 트리에서 해당 기능을 포함하는 결정 노드로 라우팅 된 샘플 수 사이의 비율입니다.

의사 결정 트리의 최상위 노드에 포함 된 기능은 더 많은 샘플을 보는 경향이 있으므로 더 중요합니다.

편집 :이 설명은 부분적으로 만 정확합니다. Gilles와 Peter의 답변이 정답입니다.


1
정확한 방법에 대한 종이 / 문서가 있는지 알고 있습니까? 예. Breiman, 2001. 방법론을 인용 할 수있는 적절한 문서가 있다면 좋을 것입니다.
user2244670

@ogrisel 응답을 "가중치"에 대한 설명으로 명확하게 표시 할 수 있다면 좋을 것입니다. 가중치만으로는 기능의 중요성을 결정하지 않습니다. 나무에 평균을 둔 가중치와 결합 된 "불순 메트릭"( "자유도"또는 RSS)은 전체 기능의 중요성을 결정합니다. 불행히도 여기 scikit-learn의 문서는 다음과 같습니다. scikit-learn.org/stable/modules/… 는 정확하지 않으며 불순물 메트릭으로 "깊이"를 잘못 언급했습니다.
Ariel

11

@GillesLouppe가 위에서 지적한 바와 같이, scikit-learn은 현재 기능 중요도에 대한 "평균 감소 불순물"메트릭을 구현합니다. 개인적으로 두 번째 측정 항목이 조금 더 흥미 롭습니다. 여기서 각 기능의 값을 하나씩 무작위로 순열하고 백 아웃 성능이 얼마나 나빠지는지 알 수 있습니다.

피처 중요도를 고려한 결과는 각 피처가 전체 모델의 예측 성능에 얼마나 많은 영향을 미치는지에 따라 두 번째 메트릭은 실제로이를 직접 측정하는 반면 "평균 감소 된 불순물"은 좋은 프록시입니다.

관심이 있다면 순열 중요도 메트릭을 구현하는 작은 패키지를 작성했으며 scikit-learn 임의 포리스트 클래스의 인스턴스에서 값을 계산하는 데 사용할 수 있습니다.

https://github.com/pjh2011/rf_perm_feat_import

편집 : 이것은 3이 아닌 Python 2.7에서 작동합니다.


안녕하세요 @Peter 코드를 사용할 때 다음 오류가 발생합니다. NameError : name 'xrange'is not defined.
Aizzaac

안녕하세요 @Aizzaac. 패키지를 처음 작성하는 것은 죄송합니다. 따라서 Python 2.7 용으로 작성했습니다. def xrange (x) : try iter (range (x))를 실행하기 전에 시도하십시오
Peter

2

질문에 대답 해 드리겠습니다. 암호:

iris = datasets.load_iris()  
X = iris.data  
y = iris.target  
clf = DecisionTreeClassifier()  
clf.fit(X, y)  

decision_tree plot :
여기에 이미지 설명을 입력하십시오
compute_feature_importance : [0. , 0.01333333,0.06405596,0.92261071]
소스 코드 확인 :

cpdef compute_feature_importances(self, normalize=True):
    """Computes the importance of each feature (aka variable)."""
    cdef Node* left
    cdef Node* right
    cdef Node* nodes = self.nodes
    cdef Node* node = nodes
    cdef Node* end_node = node + self.node_count

    cdef double normalizer = 0.

    cdef np.ndarray[np.float64_t, ndim=1] importances
    importances = np.zeros((self.n_features,))
    cdef DOUBLE_t* importance_data = <DOUBLE_t*>importances.data

    with nogil:
        while node != end_node:
            if node.left_child != _TREE_LEAF:
                # ... and node.right_child != _TREE_LEAF:
                left = &nodes[node.left_child]
                right = &nodes[node.right_child]

                importance_data[node.feature] += (
                    node.weighted_n_node_samples * node.impurity -
                    left.weighted_n_node_samples * left.impurity -
                    right.weighted_n_node_samples * right.impurity)
            node += 1

    importances /= nodes[0].weighted_n_node_samples

    if normalize:
        normalizer = np.sum(importances)

        if normalizer > 0.0:
            # Avoid dividing by zero (e.g., when root is pure)
            importances /= normalizer

    return importances

기능 중요도를 계산하십시오.

print("sepal length (cm)",0)
print("sepal width (cm)",(3*0.444-(0+0)))
print("petal length (cm)",(54* 0.168 - (48*0.041+6*0.444)) +(46*0.043 -(0+3*0.444)) + (3*0.444-(0+0)))
print("petal width (cm)",(150* 0.667 - (0+100*0.5)) +(100*0.5-(54*0.168+46*0.043))+(6*0.444 -(0+3*0.444)) + (48*0.041-(0+0)))

feature_importance : np.array ([0,1.332,6.418,92.30])를 얻습니다.
정규화 된 후 배열 ([0., 0.01331334, 0.06414793, 0.92253873])을 얻을 수 있습니다 clf.feature_importances_.
모든 수업은 무게가 1이어야합니다.


1

이 주제에 대한 scikit-learn의 설명서 또는 @GillesLouppe의 답변에 대한 참조를 찾는 사람들은 다음을 수행하십시오.

RandomForestClassifier에서 estimators_attribute는 DecisionTreeClassifier의 목록입니다 ( 문서에 언급 된대로 ). scikit-learn의 소스 코드feature_importances_ 에서 RandomForestClassifier대한를 계산하기 위해 feature_importances_앙상블 의 모든 추정기 (모든 DecisionTreeClassifer) 속성에 대한 평균을 계산 합니다.

DecisionTreeClassifer의 문서 에서 "기능의 중요도는 해당 기능이 가져온 기준의 (정규화 된) 총 감소로 계산됩니다. Gini 중요도라고도합니다 [1]."

다음 은 scikit-learn의 참조에서 제공하는 변수 및 Gini 중요도에 대한 자세한 정보를 제공하는 직접 링크입니다.

[1] L. Breiman 및 A. Cutler,“랜덤 포레스트”, http://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.