ความสำคัญของคุณลักษณะด้วยตัวแปรจำลอง


17

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

ถ้าฉันแบ่งตัวแปรเด็ดขาดลงเป็นตัวแปรดัมมี่ฉันจะได้รับคุณลักษณะที่แยกต่างหากต่อคลาสในตัวแปรนั้น

คำถามของฉันคือมันเหมาะสมหรือไม่ที่จะรวมตัวกันของตัวแปรดัมมีความสำคัญเป็นค่าที่สำคัญสำหรับตัวแปรเด็ดขาดโดยการรวมเข้าด้วยกัน?

จากหน้า 368 ขององค์ประกอบของการเรียนรู้ทางสถิติ:

ความสำคัญของความสัมพันธ์กำลังสองของตัวแปรคือผลรวมของการปรับปรุงยกกำลังสองดังกล่าวสำหรับโหนดภายในทั้งหมดที่ถูกเลือกให้เป็นตัวแปรการแยกX

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

ฉันได้เขียนโค้ดไพ ธ อนต่อไปนี้ (เป็นภาษาจูปีเตอร์) เป็นการสอบสวน:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import animation, rc
from sklearn.datasets import load_diabetes
from sklearn.ensemble import RandomForestClassifier
import re

#%matplotlib inline
from IPython.display import HTML
from IPython.display import set_matplotlib_formats

plt.rcParams['figure.autolayout'] = False
plt.rcParams['figure.figsize'] = 10, 6
plt.rcParams['axes.labelsize'] = 18
plt.rcParams['axes.titlesize'] = 20
plt.rcParams['font.size'] = 14
plt.rcParams['lines.linewidth'] = 2.0
plt.rcParams['lines.markersize'] = 8
plt.rcParams['legend.fontsize'] = 14

# Get some data, I could not easily find a free data set with actual categorical variables, so I just created some from continuous variables
data = load_diabetes()
df = pd.DataFrame(data.data, columns=[data.feature_names])
df = df.assign(target=pd.Series(data.target))

# Functions to plot the variable importances
def autolabel(rects, ax):
    """
    Attach a text label above each bar displaying its height
    """
    for rect in rects:
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width()/2.,
                1.05*height,
                f'{round(height,3)}',
                ha='center',
                va='bottom')

def plot_feature_importance(X,y,dummy_prefixes=None, ax=None, feats_to_highlight=None):

    # Find the feature importances by fitting a random forest
    forest = RandomForestClassifier(n_estimators=100)
    forest.fit(X,y)
    importances_dummy = forest.feature_importances_

    # If there are specified dummy variables, combing them into a single categorical 
    # variable by summing the importances. This code assumes the dummy variables were
    # created using pandas get_dummies() method names the dummy variables as
    # featurename_categoryvalue
    if dummy_prefixes is None:
        importances_categorical = importances_dummy
        labels = X.columns
    else:
        dummy_idx = np.repeat(False,len(X.columns))
        importances_categorical = []
        labels = []

        for feat in dummy_prefixes:
            feat_idx = np.array([re.match(f'^{feat}_', col) is not None for col in X.columns])
            importances_categorical = np.append(importances_categorical,
                                                sum(importances_dummy[feat_idx]))
            labels = np.append(labels,feat)
            dummy_idx = dummy_idx | feat_idx
        importances_categorical = np.concatenate((importances_dummy[~dummy_idx],
                                                  importances_categorical))
        labels = np.concatenate((X.columns[~dummy_idx], labels))

    importances_categorical /= max(importances_categorical)
    indices = np.argsort(importances_categorical)[::-1]

    # Plotting

    if ax is None:
        fig, ax = plt.subplots()

    plt.title("Feature importances")
    rects = ax.bar(range(len(importances_categorical)),
                   importances_categorical[indices],
                   tick_label=labels[indices],
                   align="center")
    autolabel(rects, ax)

    if feats_to_highlight is not None:
        highlight = [feat in feats_to_highlight for feat in labels[indices]]
        rects2 = ax.bar(range(len(importances_categorical)),
                       importances_categorical[indices]*highlight,
                       tick_label=labels[indices],
                       color='r',
                       align="center")
        rects = [rects,rects2]
    plt.xlim([-0.6, len(importances_categorical)-0.4])
    ax.set_ylim((0, 1.125))
    return rects

# Create importance plots leaving everything as categorical variables. I'm highlighting bmi and age as I will convert those into categorical variables later
X = df.drop('target',axis=1)
y = df['target'] > 140.5

plot_feature_importance(X,y, feats_to_highlight=['bmi', 'age'])
plt.title('Feature importance with bmi and age left as continuous variables')

#Create an animation of what happens to variable importance when I split bmi and age into n (n equals 2 - 25) different classes
# %%capture

fig, ax = plt.subplots()

def animate(i):
    ax.clear()

    # Split one of the continuous variables up into a categorical variable with i balanced classes
    X_test = X.copy()
    n_categories = i+2
    X_test['bmi'] = pd.cut(X_test['bmi'],
                           np.percentile(X['bmi'], np.linspace(0,100,n_categories+1)),
                           labels=[chr(num+65) for num in range(n_categories)])
    X_test['age'] = pd.cut(X_test['age'],
                           np.percentile(X['age'], np.linspace(0,100,n_categories+1)),
                           labels=[chr(num+65) for num in range(n_categories)])
    X_test = pd.get_dummies(X_test, drop_first=True)

    # Plot the feature importances
    rects = plot_feature_importance(X_test,y,dummy_prefixes=['bmi', 'age'],ax=ax, feats_to_highlight=['bmi', 'age'])
    plt.title(f'Feature importances for {n_categories} bmi and age categories')
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['bottom'].set_visible(False)
    ax.spines['left'].set_visible(False)

    return [rects,]

anim = animation.FuncAnimation(fig, animate, frames=24, interval=1000)

HTML(anim.to_html5_video())

นี่คือผลการค้นหาบางส่วน:

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

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

และสุดท้ายตัวอย่างถ้าฉันปล่อยให้พวกเขาเป็นตัวแปรหุ่น (bmi เท่านั้น):

# Split one of the continuous variables up into a categorical variable with i balanced classes
X_test = X.copy()
n_categories = 5
X_test['bmi'] = pd.cut(X_test['bmi'],
                       np.percentile(X['bmi'], np.linspace(0,100,n_categories+1)),
                       labels=[chr(num+65) for num in range(n_categories)])
X_test = pd.get_dummies(X_test, drop_first=True)

# Plot the feature importances
rects = plot_feature_importance(X_test,y, feats_to_highlight=['bmi_B','bmi_C','bmi_D', 'bmi_E'])
plt.title(f"Feature importances for {n_categories} bmi categories")

ป้อนคำอธิบายรูปภาพที่นี่

คำตอบ:


8

เมื่อทำงานกับ "ความสำคัญของคุณลักษณะ" โดยทั่วไปจะเป็นประโยชน์เมื่อต้องจำไว้ว่าในกรณีส่วนใหญ่วิธีการทำให้เป็นมาตรฐานมักจะเป็นทางเลือกที่ดี มันจะ "เลือกคุณสมบัติที่สำคัญที่สุด" โดยอัตโนมัติสำหรับปัญหาที่เกิดขึ้น ทีนี้ถ้าเราไม่ต้องการที่จะทำตามความคิดเพื่อทำให้เป็นปกติ (โดยปกติจะอยู่ในบริบทของการถดถอย) ตัวแยกประเภทของฟอเรสต์แบบสุ่มและความคิดเกี่ยวกับการทดสอบการเปลี่ยนรูปจะให้วิธีแก้ปัญหา สิ่งนี้เคยถูกถามมาก่อนแล้วที่นี่: " ความสำคัญเชิงสัมพัทธ์ของชุดพยากรณ์ในการจำแนกป่าแบบสุ่มใน R " ไม่กี่ปีหลัง วิธีการที่เข้มงวดมากขึ้นเช่น Gregorutti และคณะ: " ความสำคัญของตัวแปรที่จัดกลุ่มกับฟอเรสต์แบบสุ่มและแอปพลิเคชันสำหรับการวิเคราะห์ข้อมูลการทำงานหลายตัวแปร". การเลือกกลุ่มคุณสมบัติที่เป็นประโยชน์ของ Chakraborty & Pal ในกรอบการทำงานของ Connectionistจะพิจารณาในบริบทของ Multi-Layer Perceptron การย้อนกลับไปยัง Gregorutti et al. paper วิธีการของพวกเขานั้นสามารถนำไปใช้ได้โดยตรงกับอัลกอริธึมการจำแนกประเภท / ถดถอย ในระยะสั้นเราจะใช้เวอร์ชั่นที่อนุญาตแบบสุ่มในแต่ละตัวอย่างถุงที่ใช้ระหว่างการฝึก

ในขณะที่การทดสอบการเปลี่ยนแปลงนั้นเป็นวิธีแก้ปัญหาในท้ายที่สุดสิ่งที่ได้รับการแก้ไขอย่างถูกต้องในอดีตคือการลงโทษตัวแปรจำลองในบริบทของการถดถอยแบบปกติ คำตอบสำหรับคำถามที่เป็นกลุ่ม Lasso , กลุ่ม LARSและกลุ่มการประหารชีวิตนักโทษในสเปญ เอกสารน้ำเชื้อในงานนั้นคือ Yuan and Lin's: "การเลือกแบบจำลองและการประมาณค่าในการถดถอยด้วยตัวแปรที่จัดกลุ่ม " (2006) และ Meier et al.'s: " กลุ่ม lasso สำหรับการถดถอยโลจิสติก " (2008) วิธีการนี้ช่วยให้เราสามารถทำงานในสถานการณ์ที่: " แต่ละปัจจัยอาจมีหลายระดับและสามารถแสดงผ่านกลุ่มของตัวแปรจำลอง " (Y&L 2006) ผลที่ได้คือ "ล.1KJJ={1,...,J}Jpyglmnetการจัดกลุ่มปฎิบัติการแบบ lasso ]

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

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


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

ไม่มีปัญหา. ฉันได้ทำการแก้ไขที่เกี่ยวข้องแล้ว อย่ายกเลิกแนวคิดของการถดถอยแบบปกติอย่างที่ฉันพูดถึงข้อความแนวทางการทำให้เป็นมาตรฐานเป็นทางเลือกที่ถูกต้องสมบูรณ์ในการให้ความสำคัญ / การจัดอันดับ
usεr11852พูดว่า Reinstate Monic

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

2

คำถามคือ:

มันสมเหตุสมผลไหมที่จะรวมตัวกันของตัวแปรดัมมีความสำคัญเป็นค่าความสำคัญสำหรับตัวแปรเด็ดขาด

คำตอบสั้น ๆ :

ผมม.พีโอRเสื้อanอี(Xล.)=ผม
(ผม)2=Σเสื้อ=1J-1ผม2ผม(โวลต์(เสื้อ)=)
ผม=Σเสื้อ=1J-1ผม2ผม(โวลต์(เสื้อ)=)

คำตอบที่ใช้ได้นานและเป็นประโยชน์มากขึ้น ..

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

กำบังของตัวแปรที่สำคัญโดยผู้อื่นที่พวกเขามีความสัมพันธ์สูง (หน้า 368)

ประเด็นต่าง ๆ เช่นความเป็นไปได้หลายระดับความสัมพันธ์อาจบิดเบือนค่าความสำคัญของตัวแปรและการจัดอันดับ

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

แม้ว่าความสัมพันธ์หลายระดับไม่ส่งผลกระทบต่อประสิทธิภาพของวิธีการที่มีความสำคัญสัมพัทธ์ (WHITTAKER p366)


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

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

@ecedavis คุณหมายถึงอะไรในตำราเรียน? คุณสามารถให้ลิงค์หรือการอ้างอิงที่สมบูรณ์มากกว่านี้ได้ไหม
See24

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

รูปแบบของคำตอบของคุณดี แต่ข้อมูลและเนื้อหาบางส่วนดูเหมือนไม่ถูกต้องสมบูรณ์ บทความที่คุณเชื่อมโยงนั้นเกี่ยวกับความสำคัญของการทำนายในการถดถอยหลายครั้งในขณะที่คำถามเกี่ยวกับความสำคัญในฟอเรสต์แบบสุ่ม ฉันยังพบว่าการอ้างคำพูดของคุณเป็นปัญหาเนื่องจากประโยคเต็มคือ "นอกจากนี้เนื่องจากการหดตัว (มาตรา 10.12.1) การปิดบังตัวแปรสำคัญโดยผู้อื่นที่มีความสัมพันธ์สูงมีปัญหาน้อยมาก" ซึ่งมีความหมายแตกต่างกันมาก
See24
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.