Tính năng_importances trong RandomForestClassifier được xác định như thế nào?


125

Tôi có một nhiệm vụ phân loại với chuỗi thời gian là đầu vào dữ liệu, trong đó mỗi thuộc tính (n = 23) đại diện cho một thời điểm cụ thể. Bên cạnh kết quả phân loại tuyệt đối tôi muốn tìm hiểu, thuộc tính / ngày nào đóng góp vào kết quả ở mức độ nào. Vì vậy, tôi chỉ sử dụng feature_importances_, hoạt động tốt cho tôi.

Tuy nhiên, tôi muốn biết làm thế nào họ đang được tính toán và biện pháp / thuật toán nào được sử dụng. Thật không may, tôi không thể tìm thấy bất kỳ tài liệu về chủ đề này.


10
Woah ba devs trên trong một chủ đề SO. Đó phải là một loại kỷ lục ^^
Andreas Mueller

Câu trả lời:


158

Thực sự có một số cách để có được tính năng "quan trọng". Như thường lệ, không có sự đồng thuận chặt chẽ về ý nghĩa của từ này.

Trong scikit-learn, chúng tôi thực hiện tầm quan trọng như được mô tả trong [1] (thường được trích dẫn, nhưng rất tiếc, hiếm khi đọc ...). Đôi khi nó được gọi là "tầm quan trọng của gini" hoặc "tạp chất giảm trung bình" và được định nghĩa là tổng giảm tạp chất của nút (trọng số của xác suất đạt đến nút đó (xấp xỉ bằng tỷ lệ mẫu đạt đến nút đó)) trung bình trên tất cả cây của đoàn.

Trong tài liệu hoặc trong một số gói khác, bạn cũng có thể tìm thấy các tính năng quan trọng được triển khai dưới dạng "độ chính xác giảm trung bình". Về cơ bản, ý tưởng là để đo độ giảm độ chính xác trên dữ liệu OOB khi bạn hoán vị ngẫu nhiên các giá trị cho tính năng đó. Nếu mức giảm thấp, thì tính năng này không quan trọng và ngược lại.

(Lưu ý rằng cả hai thuật toán đều có sẵn trong gói RandomForest R.)

[1]: Breiman, Friedman, "Phân loại và cây hồi quy", 1984.


48
Sẽ thật tuyệt nếu câu trả lời này được đề cập trong tài liệu về các thuộc tính / ví dụ quan trọng. Đã tìm kiếm nó trong một thời gian quá :)
d1337

2
Có vẻ như điểm quan trọng là trong giá trị tương đối? Ví dụ: tổng điểm quan trọng của tất cả các tính năng luôn là 1 (xem ví dụ ở đây scikit-learn.org/ sóng / auto_examples /ensemble / khăn )
RNA

5
@RNA: Có, theo mặc định các biến quan trọng được chuẩn hóa trong scikit-learn, sao cho chúng tổng hợp thành một. Bạn có thể phá vỡ điều này bằng cách lặp qua các công cụ ước tính cơ sở và gọi điện tree_.compute_feature_importances(normalize=False).
Gilles Louppe

2
@GillesLouppe Bạn có sử dụng các mẫu trong túi để đo mức giảm MSE cho một rừng hồi quy cây quyết định trong mỗi cây không? Hoặc tất cả dữ liệu đào tạo được sử dụng trên cây?
Cokes

1
Hai tài nguyên hữu ích. (1) blog.datadive.net/ Nhật một blog của Ando Saabas thực hiện cả "tạp chất giảm trung bình" và "giảm độ chính xác trung bình" như được đề cập bởi Gilles. (2) Tải xuống và đọc luận án của Gilles Louppe.
Đánh dấu Teese

54

Cách thông thường để tính các giá trị quan trọng của một cây như sau:

  1. bạn khởi tạo một mảng feature_importancesgồm tất cả các số không có kích thước n_features.

  2. bạn duyệt qua cây: đối với mỗi nút nội bộ phân tách trên tính năng, ibạn tính toán mức giảm lỗi của nút đó nhân với số lượng mẫu được định tuyến đến nút và thêm số lượng này vào feature_importances[i].

Việc giảm lỗi phụ thuộc vào tiêu chí tạp chất mà bạn sử dụng (ví dụ: Gini, Entropy, MSE, ...). Đó là tạp chất của tập hợp các ví dụ được định tuyến đến nút bên trong trừ đi tổng tạp chất của hai phân vùng được tạo bởi phần tách.

Điều quan trọng là các giá trị này liên quan đến một tập dữ liệu cụ thể (cả giảm lỗi và số lượng mẫu là cụ thể của tập dữ liệu) do đó các giá trị này không thể được so sánh giữa các bộ dữ liệu khác nhau.

Theo như tôi biết, có những cách khác để tính các giá trị quan trọng trong các cây quyết định. Một mô tả ngắn gọn về phương pháp trên có thể được tìm thấy trong "Các yếu tố của học thống kê" của Trevor Hastie, Robert Tibshirani và Jerome Friedman.


12

Đó là tỷ lệ giữa số lượng mẫu được định tuyến đến một nút quyết định liên quan đến tính năng đó trong bất kỳ cây nào trong quần thể trên tổng số mẫu trong tập huấn luyện.

Các tính năng có liên quan đến các nút cấp cao nhất của cây quyết định có xu hướng nhìn thấy nhiều mẫu hơn do đó có khả năng có tầm quan trọng cao hơn.

Chỉnh sửa : mô tả này chỉ đúng một phần: Câu trả lời của Gilles và Peter là câu trả lời đúng.


1
Bạn có biết nếu có một số giấy / tài liệu về phương pháp chính xác? ví dụ. Breiman, 2001. Thật tuyệt vời nếu tôi có một số tài liệu phù hợp, mà tôi có thể trích dẫn cho phương pháp luận này.
dùng2244670

@ogrisel sẽ thật tuyệt nếu bạn có thể đánh dấu rõ ràng câu trả lời của mình là lời giải thích cho "trọng số". Chỉ riêng trọng số không xác định tầm quan trọng của tính năng. "Số liệu tạp chất" ("tầm quan trọng của gini" hoặc RSS) kết hợp với các trọng số, tính trung bình trên các cây xác định tầm quan trọng của tính năng tổng thể. Thật không may, tài liệu về scikit-learn tại đây: scikit-learn.org/ sóng / mô-đun / không chính xác và không chính xác đề cập đến "độ sâu" là số liệu tạp chất.
Ariel

11

Như @GillesLouppe đã chỉ ra ở trên, scikit-learn hiện đang thực hiện số liệu "tạp chất giảm trung bình" cho các mức độ quan trọng của tính năng. Cá nhân tôi thấy số liệu thứ hai thú vị hơn một chút, trong đó bạn ngẫu nhiên hoán vị các giá trị cho từng tính năng của mình và xem hiệu suất xuất túi của bạn tệ hơn bao nhiêu.

Vì những gì bạn có sau với tầm quan trọng của tính năng là mỗi tính năng đóng góp bao nhiêu vào hiệu suất dự đoán của mô hình tổng thể của bạn, nên số liệu thứ hai thực sự mang đến cho bạn thước đo trực tiếp về điều này, trong khi "tạp chất giảm trung bình" chỉ là một proxy tốt.

Nếu bạn quan tâm, tôi đã viết một gói nhỏ thực hiện chỉ số Tầm quan trọng cho phép và có thể được sử dụng để tính các giá trị từ một thể hiện của lớp rừng ngẫu nhiên tìm hiểu scikit:

https://github.com/pjh2011/rf_perm_feat_import

Chỉnh sửa: Điều này hoạt động cho Python 2.7, không phải 3


Xin chào @Peter khi tôi sử dụng mã của bạn, tôi gặp lỗi này: NameError: name 'xrange' không được xác định.
Aeatherac

Xin chào @Aizzaac. Xin lỗi tôi mới viết gói, vì vậy tôi nên lưu ý rằng tôi đã viết nó cho Python 2.7. Hãy thử def xrange (x): return iter (phạm vi (x)) trước khi chạy nó
Peter

2

Hãy để tôi thử trả lời câu hỏi. mã:

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

âm mưu quyết định:
nhập mô tả hình ảnh ở đây
Chúng tôi có thể nhận được compute_feature_importance: [0. , 0,01333333,0,06405596,0.92261071]
Kiểm tra mã nguồn:

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

Hãy thử tính toán tầm quan trọng của tính năng:

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)))

Chúng tôi nhận được Feature_importance: np.array ([0,1.332,6.418,92.30]).
Sau khi được chuẩn hóa, chúng ta có thể nhận được mảng ([0., 0.01331334, 0.06414793, 0.92253873]), điều này giống như clf.feature_importances_.
Hãy cẩn thận tất cả các lớp được cho là có trọng lượng một.


1

Đối với những người tìm kiếm tài liệu tham khảo cho tài liệu của scikit-learn về chủ đề này hoặc tài liệu tham khảo cho câu trả lời của @GillesLouppe:

Trong RandomForestClassifier, estimators_thuộc tính là một danh sách của ReasonTreeClassifier (như được đề cập trong tài liệu ). Để tính toán feature_importances_cho RandomForestClassifier, trong mã nguồn của scikit-learn , nó tính trung bình trên tất cả các thuộc tính của công cụ ước tính (tất cả các công cụ quyết định) feature_importances_trong toàn bộ.

Trong tài liệu của Quyết định , người ta đã đề cập rằng "Tầm quan trọng của một tính năng được tính là tổng mức giảm (bình thường hóa) của tiêu chí do tính năng đó mang lại. Nó còn được gọi là tầm quan trọng của Gini [1]."

Đây là một liên kết trực tiếp để biết thêm thông tin về tầm quan trọng của biến và Gini, như được cung cấp bởi tài liệu tham khảo của scikit-learn bên dưới.

[1] L. Breiman, và A. Cutler, Rừng Ngẫu nhiên lâm sàng, http: //www.stat.ber siêu.edu / ~ oustiman / RandomForests / cc_home.htmlm

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.