feature_importances ใน RandomForestClassifier ถูกกำหนดอย่างไร


126

ฉันมีงานการจัดหมวดหมู่โดยมีอนุกรมเวลาเป็นข้อมูลป้อนข้อมูลโดยที่แต่ละแอตทริบิวต์ (n = 23) แสดงถึงช่วงเวลาที่เฉพาะเจาะจง นอกจากผลการจำแนกแบบสัมบูรณ์แล้วฉันต้องการทราบว่าคุณลักษณะ / วันที่ใดที่มีส่วนทำให้ผลลัพธ์มีขนาดเท่าใด ดังนั้นฉันแค่ใช้feature_importances_ซึ่งเหมาะกับฉัน

อย่างไรก็ตามฉันต้องการทราบว่าพวกเขาคำนวณอย่างไรและใช้การวัด / อัลกอริทึมใด ขออภัยไม่พบเอกสารใด ๆ เกี่ยวกับหัวข้อนี้


10
ว้าวนักพัฒนาหลักสามตัวในเธรด SO เดียว มันต้องเป็นบันทึกอะไรสักอย่าง ^^
Andreas Mueller

คำตอบ:


158

มีหลายวิธีในการรับคุณลักษณะ "การนำเข้า" บ่อยครั้งที่ไม่มีฉันทามติที่เข้มงวดเกี่ยวกับความหมายของคำนี้

ใน scikit-learn เราใช้ความสำคัญตามที่อธิบายไว้ใน [1] (มักอ้างถึง แต่น่าเสียดายที่ไม่ค่อยอ่าน ... ) บางครั้งเรียกว่า "gini important" หรือ "mean reduction impurity" และหมายถึงการลดลงของสิ่งเจือปนของโหนดทั้งหมด (ถ่วงน้ำหนักด้วยความน่าจะเป็นที่จะไปถึงโหนดนั้น (ซึ่งประมาณโดยสัดส่วนของตัวอย่างที่ไปถึงโหนดนั้น)) โดยเฉลี่ยจากทั้งหมด ต้นไม้ของวงดนตรี

ในเอกสารหรือในแพ็คเกจอื่น ๆ คุณสามารถค้นหาการนำเข้าคุณลักษณะที่ใช้เป็น "ค่าความแม่นยำในการลดค่าเฉลี่ย" โดยพื้นฐานแล้วแนวคิดคือการวัดการลดลงของความแม่นยำของข้อมูล OOB เมื่อคุณสุ่มอนุญาตค่าสำหรับคุณลักษณะนั้น หากการลดลงต่ำแสดงว่าคุณสมบัตินั้นไม่สำคัญและในทางกลับกัน

(โปรดทราบว่าอัลกอริทึมทั้งสองมีอยู่ในแพ็คเกจ randomForest R)

[1]: Breiman, Friedman, "Classification and regression trees", 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 สำหรับป่าของต้นไม้ที่มีการตัดสินใจในต้นไม้แต่ละต้นหรือไม่? หรือข้อมูลการฝึกอบรมทั้งหมดที่ใช้บนต้นไม้?
Cokes

1
ทรัพยากรที่มีประโยชน์สองอย่าง (1) blog.datadive.net/…บล็อกของ Ando Saabas ใช้ทั้ง "ค่าเฉลี่ยความไม่บริสุทธิ์ลดลง" และ "ค่าเฉลี่ยความถูกต้องลดลง" ตามที่กล่าวโดย Gilles (2) ดาวน์โหลดและอ่านวิทยานิพนธ์ของ Gilles Louppe
Mark Teese

54

วิธีปกติในการคำนวณค่าความสำคัญของคุณลักษณะของต้นไม้ต้นเดียวมีดังนี้:

  1. คุณเริ่มต้นอาร์เรย์ของศูนย์ทั้งหมดที่มีขนาดfeature_importancesn_features

  2. คุณสำรวจต้นไม้: สำหรับแต่ละโหนดภายในที่แยกคุณลักษณะคุณคำนวณการลดข้อผิดพลาดของโหนดนั้นคูณด้วยจำนวนตัวอย่างที่ถูกส่งไปยังโหนดและเพิ่มปริมาณนี้ifeature_importances[i]

การลดข้อผิดพลาดขึ้นอยู่กับเกณฑ์การเจือปนที่คุณใช้ (เช่น Gini, Entropy, MSE, ... ) ความไม่บริสุทธิ์ของชุดตัวอย่างที่ถูกส่งไปยังโหนดภายในลบด้วยผลรวมของสิ่งสกปรกของสองพาร์ติชันที่สร้างโดยการแบ่ง

สิ่งสำคัญคือค่าเหล่านี้สัมพันธ์กับชุดข้อมูลเฉพาะ (ทั้งการลดข้อผิดพลาดและจำนวนตัวอย่างเป็นชุดข้อมูลเฉพาะ) ดังนั้นค่าเหล่านี้จึงไม่สามารถเปรียบเทียบระหว่างชุดข้อมูลที่ต่างกันได้

เท่าที่ฉันรู้มีวิธีอื่นในการคำนวณค่าความสำคัญของคุณลักษณะในโครงสร้างการตัดสินใจ คำอธิบายสั้น ๆ ของวิธีการข้างต้นสามารถพบได้ใน "องค์ประกอบของการเรียนรู้ทางสถิติ" โดย Trevor Hastie, Robert Tibshirani และ Jerome Friedman


12

เป็นอัตราส่วนระหว่างจำนวนตัวอย่างที่ส่งไปยังโหนดการตัดสินใจที่เกี่ยวข้องกับคุณลักษณะนั้นในต้นไม้ใด ๆ ของวงดนตรีกับจำนวนตัวอย่างทั้งหมดในชุดการฝึกอบรม

คุณลักษณะที่เกี่ยวข้องกับโหนดระดับบนสุดของแผนผังการตัดสินใจมักจะเห็นตัวอย่างมากขึ้นจึงน่าจะมีความสำคัญมากกว่า

แก้ไข : คำอธิบายนี้ถูกต้องเพียงบางส่วน: คำตอบของ Gilles และ Peter เป็นคำตอบที่ถูกต้อง


1
คุณทราบหรือไม่ว่ามีกระดาษ / เอกสารเกี่ยวกับวิธีการที่แน่นอนหรือไม่? เช่น. Breiman, 2001 มันจะดีมากถ้าฉันมีเอกสารที่เหมาะสมซึ่งฉันสามารถอ้างถึงวิธีการนี้ได้
user2244670

@ogrisel จะดีมากถ้าคุณสามารถระบุคำตอบของคุณเป็นคำอธิบายของ "การถ่วงน้ำหนัก" ได้อย่างชัดเจน การให้น้ำหนักเพียงอย่างเดียวไม่ได้กำหนดความสำคัญของคุณลักษณะ "เมตริกความไม่บริสุทธิ์" ("gini-important" หรือ RSS) รวมกับน้ำหนักโดยเฉลี่ยจากต้นไม้จะเป็นตัวกำหนดความสำคัญของคุณลักษณะโดยรวม น่าเสียดายที่เอกสารเกี่ยวกับ scikit-learn ที่นี่: scikit-learn.org/stable/modules/…ไม่ถูกต้องและกล่าวถึง "ความลึก" อย่างไม่ถูกต้องว่าเป็นเมตริกสิ่งเจือปน
Ariel

11

ดังที่ @GillesLouppe ได้กล่าวไว้ข้างต้นปัจจุบัน scikit-learn ใช้เมตริก "การลดค่าเฉลี่ยความไม่บริสุทธิ์" สำหรับการนำเข้าคุณลักษณะ โดยส่วนตัวแล้วฉันพบว่าเมตริกที่สองนั้นน่าสนใจกว่าเล็กน้อยโดยที่คุณสุ่มกำหนดค่าสำหรับคุณลักษณะแต่ละรายการของคุณทีละรายการและดูว่าประสิทธิภาพการทำงานนอกกระเป๋าของคุณแย่ลงเพียงใด

เนื่องจากสิ่งที่คุณให้ความสำคัญกับคุณลักษณะคือคุณลักษณะแต่ละอย่างมีส่วนช่วยในประสิทธิภาพการคาดการณ์โดยรวมของแบบจำลองของคุณมากเพียงใดเมตริกที่สองจึงช่วยให้คุณสามารถวัดสิ่งนี้ได้โดยตรงในขณะที่ "ค่าเฉลี่ยความไม่บริสุทธิ์ลดลง" เป็นเพียงพร็อกซีที่ดี

หากคุณสนใจฉันเขียนแพ็คเกจเล็ก ๆ ที่ใช้เมตริกความสำคัญของการเรียงลำดับและสามารถใช้ในการคำนวณค่าจากอินสแตนซ์ของคลาสฟอเรสต์สุ่ม scikit-learn:

https://github.com/pjh2011/rf_perm_feat_import

แก้ไข: ใช้ได้กับ Python 2.7 ไม่ใช่ 3


สวัสดี @Peter เมื่อฉันใช้รหัสของคุณฉันได้รับข้อผิดพลาดนี้: NameError: ไม่ได้กำหนดชื่อ 'xrange'
Aizzaac

สวัสดี @Aizzaac ขออภัยฉันยังใหม่กับการเขียนแพ็คเกจดังนั้นฉันควรสังเกตว่าฉันเขียนสำหรับ Python 2.7 ลอง def xrange (x): ส่งคืนค่า (range (x)) ก่อนที่จะรัน
ปีเตอร์

2

ให้ฉันลองตอบคำถาม รหัส:

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

แผนภาพการตัดสินใจ:
ใส่คำอธิบายภาพที่นี่
เราสามารถรับ 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

สำหรับผู้ที่กำลังมองหาการอ้างอิงเอกสารของ scikit-learn ในหัวข้อนี้หรือการอ้างอิงถึงคำตอบโดย @GillesLouppe:

ใน RandomForestClassifier estimators_แอตทริบิวต์คือรายการของ DecisionTreeClassifier (ดังที่กล่าวไว้ในเอกสารประกอบ ) ในการคำนวณfeature_importances_สำหรับ RandomForestClassifier ในซอร์สโค้ดของ scikit-learn จะมีค่าเฉลี่ยเหนือfeature_importances_แอตทริบิวต์ของตัวประมาณค่าทั้งหมด (DecisionTreeClassifer's) ทั้งหมดในชุด

ในเอกสารประกอบของ DecisionTreeClassifer มีการกล่าวถึงว่า "ความสำคัญของคุณลักษณะคำนวณจากการลดลงทั้งหมด (ปกติ) ของเกณฑ์ที่นำมาจากคุณลักษณะนั้นเรียกอีกอย่างว่า Gini important [1]"

นี่คือลิงค์โดยตรงสำหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวแปรและความสำคัญของ Gini ตามข้อมูลอ้างอิงของ scikit-learn ด้านล่าง

[1] L. Breiman และ A. Cutler,“ Random Forests”, http://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.