ความสำคัญของตัวแปรเชิงสัมพันธ์สำหรับการส่งเสริม


33

ฉันกำลังมองหาคำอธิบายว่าวิธีคำนวณความสำคัญของตัวแปรแบบสัมพันธ์ในต้นไม้ที่เพิ่มขึ้นแบบไล่ระดับสีซึ่งไม่ธรรมดา / ง่ายเกินไป:

มาตรการจะขึ้นอยู่กับจำนวนครั้งที่ตัวแปรถูกเลือกสำหรับการแยกถ่วงน้ำหนักด้วยการปรับปรุงยกกำลังสองกับรูปแบบเป็นผลของแต่ละแยกและเฉลี่ยมากกว่าต้นไม้ทั้งหมด [ Elith และคณะ 2008, คู่มือการทำงานเพื่อเพิ่มความแข็งแกร่งให้กับต้นไม้ถดถอย ]

และนั่นก็เป็นนามธรรมน้อยกว่า:

ผมJ2^(T)=Σเสื้อ=1J-1ผมเสื้อ2^1(โวลต์เสื้อ=J)

โดยที่การรวมอยู่เหนือโหนดที่ไม่ใช่เทอร์มินัลของโหนดทรี ,คือตัวแปรการแยกที่เชื่อมโยงกับโหนดและเป็นการปรับปรุงเชิงประจักษ์ในข้อผิดพลาดกำลังสอง เป็นผลมาจากการแยกหมายถึงโดยที่คือการตอบสนองของลูกสาวด้านซ้ายและขวาตามลำดับและเป็นจำนวนเงินที่สอดคล้องกันของน้ำหนัก J T v t t ^ i 2 t i 2 ( R l , R r ) = w l w rเสื้อJTโวลต์เสื้อเสื้อผมเสื้อ2^ผม2(Rล.,RR)=Wล.WRWล.+WR(Yล.¯-YR¯)2Yล.¯,YR¯Wล.,WR[ Friedman 2001 การประมาณฟังก์ชั่นโลภ: เครื่องเร่งการไล่ระดับสี ]

ในที่สุดฉันไม่พบองค์ประกอบของการเรียนรู้ทางสถิติ (Hastie et al. 2008)เพื่อเป็นประโยชน์อย่างมากอ่านที่นี่เป็นส่วนที่เกี่ยวข้อง (10.13.1 หน้า 367) รสนิยมคล้ายกันมากกับการอ้างอิงที่สองข้างต้น (ซึ่งอาจอธิบายได้ จากข้อเท็จจริงที่ว่าฟรีดแมนเป็นผู้ร่วมเขียนหนังสือเล่มนี้)

PS: ฉันรู้ว่ามาตรการความสำคัญของตัวแปรสัมพัทธ์ได้รับจากsummary.gbmในแพ็คเกจ gbm R ฉันพยายามสำรวจซอร์สโค้ด แต่ฉันไม่สามารถหาตำแหน่งที่จะทำการคำนวณจริงได้

จุดบราวนี่: ฉันสงสัยว่าจะได้รับแปลงเหล่านี้ในอาร์


ฉันเพิ่งเพิ่มคำตอบใหม่สำหรับคำถามที่เชื่อมโยงเกี่ยวกับวิธีการพล็อตความสำคัญของตัวแปรตามระดับซึ่งอาจเป็นประโยชน์stackoverflow.com/a/51952918/3277050
see24

คำตอบ:


55

ฉันจะใช้รหัสsklearnเนื่องจากโดยทั่วไปแล้วจะสะอาดกว่าRโค้ดมาก

นี่คือการใช้งานคุณสมบัติ feature_importances ของGradientBoostingClassifier (ฉันลบบางบรรทัดของรหัสที่ได้รับในทางของสิ่งที่แนวคิด)

def feature_importances_(self):
    total_sum = np.zeros((self.n_features, ), dtype=np.float64)
    for stage in self.estimators_:
        stage_sum = sum(tree.feature_importances_
                        for tree in stage) / len(stage)
        total_sum += stage_sum

    importances = total_sum / len(self.estimators_)
    return importances

มันค่อนข้างเข้าใจง่าย self.estimators_เป็นอาร์เรย์ที่มีต้นไม้แต่ละต้นในบูสเตอร์ดังนั้นสำหรับลูปจะวนซ้ำไปตามต้นไม้แต่ละต้น มีหนึ่ง hickup ด้วย

stage_sum = sum(tree.feature_importances_
                for tree in stage) / len(stage)

นี่คือการดูแลกรณีตอบกลับที่ไม่ใช่ไบนารี ที่นี่เราพอดีกับต้นไม้หลายต้นในแต่ละขั้นตอนด้วยวิธีเดียวกับทั้งหมด tree.feature_importances_แนวคิดที่ง่ายที่สุดที่จะมุ่งเน้นไปที่กรณีไบนารีที่ผลรวมมีหนึ่งตัวตั้งและนี้เป็นเพียง ดังนั้นในกรณีไบนารีเราสามารถเขียนทั้งหมดนี้เป็น

def feature_importances_(self):
    total_sum = np.zeros((self.n_features, ), dtype=np.float64)
    for tree in self.estimators_:
        total_sum += tree.feature_importances_ 
    importances = total_sum / len(self.estimators_)
    return importances

ดังนั้นโดยสรุปแล้วคุณลักษณะสำคัญของต้นไม้แต่ละต้นแล้วหารด้วยจำนวนต้นไม้ทั้งหมด มันยังคงอยู่เพื่อดูวิธีการคำนวณความสำคัญของคุณลักษณะสำหรับต้นไม้ต้นเดียว

การคำนวณความสำคัญของต้นไม้นั้นถูกนำไปใช้ในระดับ cythonแต่ก็ยังสามารถติดตามได้ นี่คือรหัสเวอร์ชันที่ล้างแล้ว

cpdef compute_feature_importances(self, normalize=True):
    """Computes the importance of each feature (aka variable)."""

    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

    return importances

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

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)

จากนั้นเมื่อเสร็จแล้วให้หารทั้งหมดด้วยน้ำหนักรวมของข้อมูล (ในกรณีส่วนใหญ่จำนวนการสังเกต)

importances /= nodes[0].weighted_n_node_samples

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

ในบริบทของการส่งเสริมการไล่ระดับสีต้นไม้เหล่านี้มักจะเป็นต้นไม้ถดถอย (ลดข้อผิดพลาดกำลังสองอย่างตะกละตะกลาม) ให้พอดีกับการไล่ระดับของฟังก์ชันการสูญเสีย


ขอบคุณมากสำหรับคำตอบที่ละเอียดมากนี้ ให้ฉันใช้เวลาอย่างระมัดระวังผ่านมันก่อนที่ฉันจะยอมรับมัน
แอนทอน

4
ในขณะที่ดูเหมือนว่าสามารถใช้เกณฑ์การปนเปื้อนที่หลากหลายได้ แต่ดัชนี Gini ไม่ใช่เกณฑ์ที่ Friedman ใช้ เป็นที่กล่าวถึงในคำถามและสาย 878 ของการเชื่อมโยงที่สามของคุณฉันฟรีดแมนใช้ค่าเฉลี่ยกำลังสองเกณฑ์ข้อผิดพลาดสิ่งเจือปนที่มีคะแนนการปรับปรุง หากคุณสามารถอัปเดตคำตอบของคุณในส่วนนี้จะดีมาก และใช่คุณพูดถูกแล้วดูเหมือนว่าน้ำหนักนั้นเป็นจำนวนการสังเกต
แอนทอน

3
หรือบางทีมันอาจจะทำให้คำตอบของคุณดียิ่งขึ้นเพื่อให้ทั้งสองส่วนเกี่ยวกับดัชนี Gini และเกณฑ์ดั้งเดิมของ Friedman โดยเน้นว่าสิ่งแรกนั้นถูกใช้สำหรับการจำแนกและที่สองสำหรับการถดถอย
แอนทอน

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

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