บทนำ
พื้นที่ ป่าสุ่ม อัลกอริทึมเป็นอัลกอริทึมการเรียนรู้ภายใต้การดูแลแบบต้นไม้ที่ใช้การคาดคะเนของแผนผังการตัดสินใจจำนวนมาก เพื่อจัดประเภทจุดข้อมูลหรือกำหนดเป็นค่าโดยประมาณ ซึ่งหมายความว่าสามารถใช้สำหรับการจำแนกหรือการถดถอย
เมื่อนำไปใช้สำหรับการจำแนกประเภท คลาสของจุดข้อมูลจะถูกเลือกตามคลาสที่ได้รับการโหวตจากทรีมากที่สุด และเมื่อนำไปใช้สำหรับการถดถอย ค่าของจุดข้อมูลคือค่าเฉลี่ยของค่าทั้งหมดที่ส่งออกโดยต้นไม้
สิ่งสำคัญที่ต้องจำเมื่อใช้ Random Forests คือจำนวนของต้นไม้เป็นไฮเปอร์พารามิเตอร์และจะถูกกำหนดก่อนที่จะรันโมเดล
เมื่อทำงานด้านวิทยาศาสตร์ข้อมูล หนึ่งในเหตุผลที่เลือกแบบจำลอง Random Forest สำหรับโครงการเฉพาะอาจเกี่ยวข้องกับความสามารถในการดูต้นไม้ที่ล้อมรอบและทำความเข้าใจ ทำไม มีการจำแนกประเภทหรือ ทำไม ได้รับค่า - สิ่งนี้เรียกว่า อธิบายได้.
การพิจารณาอัลกอริทึมแบบต้นไม้ การพยายามอธิบายแบบจำลองสามารถทำได้หลายวิธี โดยการแสดงและดูที่ต้นไม้แต่ละต้น (อาจเป็นเรื่องยากหากแบบจำลองมีต้นไม้ 200 ต้นขึ้นไป) โดยใช้ ค่าแชปลีย์ (หรือ SHAP)ดูคุณสมบัติที่โมเดลนำมาพิจารณามากที่สุดโดยใช้ มะนาว เพื่อตรวจสอบความสัมพันธ์ระหว่างอินพุตและเอาต์พุตของโมเดล เป็นต้น โดยปกติแล้วจะใช้วิธีการทั้งหมดรวมกัน
ในคำแนะนำฉบับย่อนี้ เราจะมุ่งเน้นไปที่การสร้างแผนภูมิของคุณลักษณะที่ถือว่ามีความสำคัญสำหรับแบบจำลองในการตัดสินใจเมื่อจำแนกนกเพนกวิน สิ่งนี้เรียกว่าการสืบสวน ความสำคัญของคุณลักษณะและสามารถถ่ายทอดไปยังสมาชิกคนอื่นๆ ในทีม (ทั้งด้านเทคนิคและไม่ใช่ด้านเทคนิค) เพื่อให้เห็นภาพคร่าวๆ เกี่ยวกับวิธีการตัดสินใจ
ในการทำเช่นนี้ ให้นำเข้าไลบรารีที่จำเป็น โหลดชุดข้อมูล Palmer Penguins แยกข้อมูล สร้างโมเดล รับความสำคัญของฟีเจอร์ และใช้ Seaborn เพื่อลงจุด! เราจะไม่เจาะลึกข้อมูล EDA หรือตัวโมเดลมากนัก นั่นคือหัวข้อของคำแนะนำเฉพาะ
หมายเหตุ คุณสามารถดาวน์โหลดชุดข้อมูลได้จาก GitHub หรือโดยตรงจากรหัส
การนำเข้าไลบรารี
เริ่มต้นด้วยการนำเข้าไลบรารีบางตัวที่เราจะใช้:
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
raw_data_url = "https://gist.githubusercontent.com/cassiasamp/197b4e070f5f4da890ca4d226d088d1f/raw/38c9d4906ed121481b4dc201fa2004f2b3d0065f/penguins.csv"
df = pd.read_csv(raw_data_url)
แยกข้อมูล
มาแบ่งข้อมูลสำหรับการฝึกอบรมและการทดสอบกัน:
df = df.dropna().drop("rowid", axis=1)
y = df["species"]
X = df[["bill_length_mm", "bill_depth_mm", "flipper_length_mm"]]
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
ได้รับความสำคัญของคุณสมบัติ
สุดท้าย – เราสามารถฝึกโมเดลและส่งออกความสำคัญของคุณลักษณะด้วย:
rf = RandomForestClassifier()
rf.fit(X_train, y_train)
rf.feature_importances_
ผลลัพธ์นี้:
array([0.41267633, 0.30107056, 0.28625311])
สิ่งเหล่านี้คือค่าคุณลักษณะ หากต้องการดูชื่อคุณลักษณะ ให้เรียกใช้:
rf.feature_names_in_
ส่งผลให้ชื่อที่สอดคล้องกันของแต่ละคุณลักษณะ:
array(['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm'],
dtype=object)
ซึ่งหมายความว่าคุณสมบัติที่สำคัญที่สุดในการตัดสินใจเลือกคลาส Peguin สำหรับรุ่นนี้โดยเฉพาะคือ bill_length_mm
!
ความสำคัญจะสัมพันธ์กับการวัดว่าข้อมูลถูกแยกในแต่ละการแยกโหนดได้ดีเพียงใด ในกรณีนี้ การวัดจะได้รับจาก ดัชนีจินี – ค่าจินี่จะถูกถ่วงน้ำหนักด้วยจำนวนแถวที่ถูกแบ่งเมื่อใช้ bill_length_mm
ลักษณะเด่นและเฉลี่ยกว่า 100 ต้นทั้งมวล ผลลัพธ์ของขั้นตอนเหล่านั้นสำหรับ 0.41267633
หรือมากกว่า 40% ในกรณีนี้
การแสดงภาพความสำคัญของฟีเจอร์
วิธีทั่วไปในการแสดงค่าความสำคัญคือการใช้บาร์แชท ก่อนอื่นมาสร้าง dataframe ด้วยชื่อคุณลักษณะและความสำคัญที่สอดคล้องกัน จากนั้นจึงแสดงภาพโดยใช้ Seaborn's barplot()
:
importances_df = pd.DataFrame({"feature_names" : rf.feature_names_in_,
"importances" : rf.feature_importances_})
g = sns.barplot(x=importances_df["feature_names"],
y=importances_df["importances"])
g.set_title("Feature importances", fontsize=14);
คำแนะนำ: แนวปฏิบัติที่ดีในการนำเสนอข้อมูลคือการเรียงลำดับค่าจากน้อยไปหามากหรือจากมากไปน้อย ในกรณีนี้ ข้อมูลถูกจัดลำดับไว้แล้ว โดยค่าแรกเป็นค่าแรกที่เราต้องการทราบ หากไม่ใช่กรณีนี้ คุณสามารถสั่งซื้อ dataframe ด้วย sort_values
. สามารถทำได้ในคอลัมน์ใดก็ได้โดยเรียงลำดับจากน้อยไปหามากหรือจากมากไปหาน้อย: importances_df.sort_values(by="importances", ascending=False)
.
เมื่อดูโครงเรื่องแรกนี้ การตีความคุณค่าความสำคัญของคุณลักษณะแต่ละอย่างทำได้ยากขึ้น จะเห็นได้ชัดว่าบิลยาวกว่าอีก XNUMX แท่ง แต่ก็ไม่เชิงว่า bill_depth_mm
เทียบเท่ากับ 0.30107056
และที่ flipper_length_mm
คือ 0.28625311 ดังนั้น แผนภูมิแรกนี้สามารถปรับปรุงได้โดยการแสดงค่าของแต่ละแท่ง สามารถทำได้โดยเข้าไปที่ Seaborn's containers
วัตถุ. มันเก็บข้อมูลแต่ละแถบและส่งค่าเป็นป้ายชื่อแถบ:
ดูคู่มือเชิงปฏิบัติสำหรับการเรียนรู้ Git ที่มีแนวทางปฏิบัติที่ดีที่สุด มาตรฐานที่ยอมรับในอุตสาหกรรม และเอกสารสรุปรวม หยุดคำสั่ง Googling Git และจริงๆ แล้ว เรียน มัน!
g = sns.barplot(data=importances_df,
x="importances",
y="feature_names")
g.set_title("Feature importances", fontsize=14)
for value in g.containers:
g.bar_label(value)
ตอนนี้เราสามารถเห็นค่าความสำคัญแต่ละค่าได้อย่างชัดเจนหรือเกือบจะชัดเจนแล้ว เนื่องจาก bill_length_mm
ค่ากำลังถูกตัดด้วยเส้นแนวตั้งซึ่งเป็นส่วนหนึ่งของเส้นขอบด้านนอกของแผนภูมิ เส้นขอบใช้เพื่อล้อมรอบพื้นที่เพื่อเน้นความสนใจไปที่พื้นที่นั้นมากขึ้น แต่ในกรณีนี้ เราไม่จำเป็นต้องปิดล้อม เนื่องจากมีเพียงกราฟเดียว มาลบเส้นขอบและปรับปรุงการอ่านตัวเลข:
g = sns.barplot(data=importances_df,
x="importances",
y="feature_names")
sns.despine(bottom=True, left=True)
g.set_title("Feature importances", fontsize=14)
for value in g.containers:
g.bar_label(value)
แผนภูมิดูเหมือนอ่านง่ายกว่า แต่เครื่องหมายถูกบนแกน X ดูเหมือนจะลอยอยู่ และเรามีค่าพร้อมแท่งอยู่แล้ว เราจึงสามารถลบ xticks
:
g = sns.barplot(data=importances_df,
x="importances",
y="feature_names")
sns.despine(bottom=True, left=True)
g.set(xticks=[])
g.set_title("Feature importances", fontsize=14)
for value in g.containers:
g.bar_label(value)
สังเกตว่าหลังจากเอาติ๊กออกแล้ว ฉลาก Y และ X อ่านยากไปหน่อย ป้าย Y, feature_names
, เป็นแนวตั้งและในแกน X มีเพียง importances
. เนื่องจากชื่อเรื่องระบุอยู่แล้วว่าเป็นแผนภูมิของ ความสำคัญของคุณสมบัติเรายังสามารถลบป้ายกำกับแกน:
g = sns.barplot(data=importances_df,
x="importances",
y="feature_names")
sns.despine(bottom=True, left=True)
g.set_title("Feature importances", fontsize=14)
g.set(xticks=[])
g.set(xlabel=None)
g.set(ylabel=None)
for value in g.containers:
g.bar_label(value)
คุณสามารถดูได้ว่าแผนภูมินี้สะอาด อ่านและเข้าใจได้ง่ายอย่างไรเมื่อเปรียบเทียบกับแผนภูมิแรก ยังมีบางสิ่งที่เราสามารถทำได้ สังเกตว่าตัวเลขอยู่ใกล้แถบจริงๆ จะอ่านได้ง่ายกว่าถ้ามีช่องว่างระหว่างตัวเลขมากกว่านี้เล็กน้อย
องค์ประกอบอื่นในโครงเรื่องนี้คือสี เมื่อใช้สีที่ตัดกัน มันจะส่งแนวคิดของการแบ่งแยก ในทางกลับกัน เมื่อใช้สีที่คล้ายคลึงกัน มันจะสื่อถึงแนวคิดของเอกภาพหรือบางส่วนของทั้งหมด เนื่องจากฟีเจอร์ทั้งหมดเป็นส่วนหนึ่งของนกเพนกวิน เราจึงสามารถใช้สีที่ทำให้แต่ละแถบแตกต่างกันโดยที่ยังคงความเป็นเอกภาพ:
g = sns.barplot(data=importances_df,
x="importances",
y="feature_names",
palette="mako")
sns.despine(bottom=True, left=True)
g.set_title("Feature importances", fontsize=14)
g.set(xticks=[])
g.set(xlabel=None)
g.set(ylabel=None)
for value in g.containers:
g.bar_label(value,
padding=2)
หากต้องการให้ผลลัพธ์ตรงประเด็นยิ่งขึ้น คุณสามารถเปลี่ยนชื่อเรื่องและเพิ่มบทสรุปได้ ที่ทราบกันดีก็คือความยาวของใบเรียกเก็บเงินถือเป็นคุณสมบัติที่สำคัญที่สุดตามเกณฑ์ที่เราได้กล่าวไปแล้ว นี่อาจเป็นข้อมูลแรกสำหรับคนที่ดูโครงเรื่อง เราอาจพูดอย่างนั้นได้ ความยาวใบของนกเพนกวินเป็นคุณสมบัติที่สำคัญที่สุดสำหรับการจำแนกชนิดในแบบจำลองฐาน Random Forest (RF) :
g = sns.barplot(data=importances_df,
x="importances",
y="feature_names",
palette="mako")
sns.despine(bottom=True, left=True)
g.set_title("The penguin's bill length was the most important feature for species classification (RF base model)", fontsize=14)
g.set(xticks=[])
g.set(xlabel=None)
g.set(ylabel=None)
for value in g.containers:
g.bar_label(value, padding=2)
นี่คือผลลัพธ์สุดท้ายของแผนภูมิความสำคัญของคุณลักษณะ:
สรุป
ในคู่มือนี้ – เราได้สร้าง Random Forest Classifier – และตรวจสอบความสำคัญของฟีเจอร์ที่ใช้ในการฝึกโมเดลโดยพยายาม อธิบาย สิ่งที่แบบจำลองได้เรียนรู้และสิ่งที่ส่งผลต่อการให้เหตุผล