การรับสมัครในวิทยาเขต: ปัญหาการจำแนกประเภทกับการถดถอยโลจิสติก

การรับสมัครในวิทยาเขต: ปัญหาการจำแนกประเภทกับการถดถอยโลจิสติก

โหนดต้นทาง: 1996810

บทนำ

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

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

ปัญหาวิทยาศาสตร์ข้อมูลกับการถดถอยโลจิสติก

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

บทความนี้เผยแพร่โดยเป็นส่วนหนึ่งของไฟล์ Blogathon วิทยาศาสตร์ข้อมูล

สารบัญ

  1. ขั้นตอนที่เกี่ยวข้องในการแก้ปัญหา
  2. เตรียมข้อมูล
  3. สร้างแบบจำลองการถดถอยโลจิสติก
  4. ผลลัพธ์ของแบบจำลองการถดถอยโลจิสติก
  5. สรุป

ขั้นตอนที่เกี่ยวข้องในการแก้ปัญหา

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

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

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

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

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

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

สุดท้ายนี้ ก่อนที่จะดำดิ่งสู่งาน เรามาแนะนำตัวเองกับห้องสมุดที่เราจะใช้โยนโปรเจ็กต์กันก่อน ขั้นแรก เราจะนำเข้าข้อมูลของเราไปยังสมุดบันทึก Google Colabe ลงในไลบรารี io จากนั้น เนื่องจากเราจะใช้แบบจำลองการถดถอยลอจิสติก เราจะนำเข้าสิ่งนั้นจาก scikit-learn หลังจากนั้นก็มาจาก scikit เรียนรู้เราจะนำเข้าตัวชี้วัดประสิทธิภาพ คะแนนความแม่นยำ และการแบ่งการทดสอบรถไฟ

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

เรามาเตรียมข้อมูลกันดีกว่า

#import libraries
import io
import warnings import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.preprocessing import LabelEncoder
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler warnings.simplefilter(action="ignore", category=FutureWarning)

เตรียมข้อมูล

นำเข้า

เพื่อเริ่มต้นการเตรียมข้อมูล เรามาทำงานที่สำคัญกันดีกว่า ขั้นแรก เราโหลดไฟล์ข้อมูลของเรา จากนั้นเราต้องใส่ไฟล์เหล่านั้นลงใน DataFrame `df.`

from google.colab import files
uploaded = files.upload()
# Read CSV file
df = pd.read_csv(io.BytesIO(uploaded["Placement_Data_Full_Class.csv"]))
print(df.shape)
df.head()
ชุดข้อมูลสำหรับการถดถอยโลจิสติก

เราสามารถเห็น DataFrame ที่สวยงามของเรา และเรามี 215 บันทึกและ 15 คอลัมน์ที่มีแอตทริบิวต์ `สถานะ` ซึ่งเป็นเป้าหมายของเรา นี่คือคำอธิบายสำหรับคุณสมบัติทั้งหมด

การถดถอยโลจิสติก

อ่านเพิ่มเติม...

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

# Inspect DataFrame
df.info() <class 'pandas.core.frame.DataFrame'>
RangeIndex: 215 entries, 0 to 214
Data columns (total 15 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 sl_no 215 non-null int64 1 gender 215 non-null object 2 ssc_p 215 non-null float64 3 ssc_b 215 non-null object 4 hsc_p 215 non-null float64 5 hsc_b 215 non-null object 6 hsc_s 215 non-null object 7 degree_p 215 non-null float64 8 degree_t 215 non-null object 9 workex 215 non-null object 10 etest_p 215 non-null float64 11 specialisation 215 non-null object 12 mba_p 215 non-null float64 13 status 215 non-null object 14 salary 148 non-null float64
dtypes: float64(6), int64(1), object(8)
memory usage: 25.3+ KB

เมื่อเราดูข้อมูล `df` มีสองสิ่งที่เรากำลังมองหา เรามี 215 แถวใน dataframe และคำถามที่เราต้องการถามตัวเองคือ มีข้อมูลใดหายไปหรือไม่ และถ้าเราดูที่นี่ ดูเหมือนว่าเราไม่มีข้อมูลขาดหายไป ยกเว้นคอลัมน์เงินเดือน ตามที่คาดไว้ เนื่องจากผู้สมัครที่ไม่ได้รับการว่าจ้าง

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

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

df.drop(columns="salary", inplace=True)

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

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

# Plot class balance
df["status"].value_counts(normalize=True).plot( kind="bar", xlabel="Class", ylabel="Relative Frequency", title="Class Balance"
);
ความไม่สมดุลของคลาสสำหรับการถดถอยโลจิสติก

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

เรามาสร้างภาพข้อมูลอีกครั้งเพื่อสังเกตความเชื่อมโยงระหว่างคุณลักษณะของเรากับเป้าหมาย เริ่มจากคุณสมบัติเชิงตัวเลขกันก่อน

ขั้นแรก เราจะเห็นการแจกแจงแต่ละคุณลักษณะโดยใช้แผนภาพการกระจาย และเราจะเห็นความสัมพันธ์ระหว่างคุณลักษณะเชิงตัวเลขและเป้าหมายของเราโดยใช้โครงเรื่องแบบกล่อง

fig,ax=plt.subplots(5,2,figsize=(15,35))
for index,i in enumerate(df.select_dtypes("number").drop(columns="sl_no")): plt.suptitle("Visualizing Distribution of Numerical Columns Indivualy and by Class",size=20) sns.histplot(data=df, x=i, kde=True, ax=ax[index,0]) sns.boxplot(data=df, x='status', y=i, ax=ax[index,1]);
"การถดถอยโลจิสติก

ในคอลัมน์แรกจากพล็อตของเรา เราจะเห็นว่าการแจกแจงทั้งหมดเป็นไปตามการแจกแจงแบบปกติ และผลการเรียนของผู้สมัครส่วนใหญ่อยู่ระหว่าง 60-80%

ในคอลัมน์ที่สอง เรามีพล็อตกล่องคู่ที่มีคลาส 'วาง' ทางด้านขวา และคลาส 'ไม่ได้วาง' ทางด้านซ้าย สำหรับคุณสมบัติ 'etest_p' และ 'mba_p' การแจกแจงทั้งสองนี้มีความแตกต่างกันไม่มากนักจากมุมมองของการสร้างแบบจำลอง มีการทับซ้อนกันอย่างมีนัยสำคัญในการกระจายของคลาส ดังนั้นฟีเจอร์เหล่านี้จึงไม่สามารถทำนายเป้าหมายของเราได้ดี สำหรับคุณสมบัติที่เหลือ มีความแตกต่างเพียงพอที่จะถือเป็นตัวทำนายที่ดีต่อเป้าหมายของเรา มาดูคุณสมบัติหมวดหมู่กันดีกว่า และเพื่อสำรวจพวกมัน เราจะใช้แผนผังการนับ

fig,ax=plt.subplots(7,2,figsize=(15,35))
for index,i in enumerate(df.select_dtypes("object").drop(columns="status")): plt.suptitle("Visualizing Count of Categorical Columns",size=20) sns.countplot(data=df,x=i,ax=ax[index,0]) sns.countplot(data=df,x=i,ax=ax[index,1],hue="status")
"การถดถอยโลจิสติก

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

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

corr = df.select_dtypes("number").corr()
# Plot heatmap of `correlation`
plt.title('Correlation Matrix')
sns.heatmap(corr, vmax=1, square=True, annot=True, cmap='GnBu');
เมทริกซ์สหสัมพันธ์

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

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

# Check for high- and low-cardinality categorical features
df.select_dtypes("object").nunique() gender 2
ssc_b 2
hsc_b 2
hsc_s 3
degree_t 3
workex 2
specialisation 2
status 2
dtype: int64

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

df.drop(columns="sl_no", inplace=True)

คุณสมบัติการเข้ารหัส

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

lb = LabelEncoder () cat_data = ['gender', 'ssc_b', 'hsc_b', 'hsc_s', 'degree_t', 'workex', 'specialisation', 'status']
for i in cat_data: df[i] = lb.fit_transform(df[i]) df.head()
เอาต์พุตโค้ด

แยก

เรานำเข้าและล้างข้อมูลของเรา เราได้ทำการวิเคราะห์ข้อมูลเชิงสำรวจไปบ้างแล้ว และตอนนี้เราจำเป็นต้องแบ่งข้อมูลของเรา เรามีการแยกสองประเภท: การแยกแนวตั้งหรือคุณลักษณะ-เป้าหมาย และการแยกแนวนอนหรือชุดการทดสอบรถไฟ เริ่มจากแนวตั้งกันก่อน เราจะสร้างเมทริกซ์คุณลักษณะ 'X' และเวกเตอร์เป้าหมาย 'y' เป้าหมายของเราคือ "สถานะ" คุณลักษณะของเราควรเป็นคอลัมน์ทั้งหมดที่เหลืออยู่ใน 'df'

#vertical split
target = "status"
X = df.drop(columns = target)
y = df[target]

โดยทั่วไปแล้ว โมเดลจะทำงานได้ดีขึ้นเมื่อมีข้อมูลที่ทำให้เป็นมาตรฐานในการฝึก แล้วการทำให้เป็นมาตรฐานคืออะไร normalization กำลังแปลงค่าของตัวแปรหลายตัวให้อยู่ในช่วงใกล้เคียงกัน เป้าหมายของเราคือการทำให้ตัวแปรของเราเป็นมาตรฐาน ดังนั้นช่วงค่าจะอยู่ระหว่าง 0 ถึง 1 ลองทำดู แล้วฉันจะใช้ `StandardScaler`

scaler = StandardScaler()
X = scaler.fit_transform(X)

ตอนนี้เรามาทำชุดแยกแนวนอนหรือชุดทดสอบรถไฟกันดีกว่า เราจำเป็นต้องแบ่งข้อมูลของเรา (X และ y) ออกเป็นชุดการฝึกอบรมและการทดสอบโดยใช้การแบ่งการทดสอบรถไฟแบบสุ่ม ชุดทดสอบของเราควรเป็น 20% ของข้อมูลทั้งหมดของเรา และอย่าลืมตั้งค่า Random_state เพื่อการทำซ้ำ

X_train, X_test, y_train, y_test = train_test_split( X, y, test_size = 0.2, random_state = 42 ) print("X_train shape:", X_train.shape)
print("y_train shape:", y_train.shape)
print("X_test shape:", X_test.shape)
print("y_test shape:", y_test.shape) X_train shape: (172, 12)
y_train shape: (172,)
X_test shape: (43, 12)
y_test shape: (43,)

สร้างแบบจำลองการถดถอยโลจิสติก

baseline

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

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

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

เราสามารถใช้วิธี 'value_counts' กับอาร์กิวเมนต์ `normalize = True` เพื่อคำนวณความแม่นยำพื้นฐาน:

acc_baseline = y_train.value_counts(normalize=True).max()
print("Baseline Accuracy:", round(acc_baseline, 2)) Baseline Accuracy: 0.68

เราจะเห็นว่าความแม่นยำพื้นฐานของเราคือ 68% หรือ 0.68 ตามสัดส่วน ดังนั้นเพื่อเพิ่มมูลค่าในการใช้งาน เราต้องการอยู่เหนือตัวเลขนั้นและเข้าใกล้ตัวเลขนั้นมากขึ้น นั่นคือเป้าหมายของเรา และตอนนี้เรามาเริ่มสร้างแบบจำลองของเรากันดีกว่า

ย้ำ

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

ตามแกน x สมมุติว่าฉันมี p_degrees ของผู้สมัครในชุดข้อมูลของเรา และเมื่อฉันย้ายจากขวาไปซ้าย องศาจะสูงขึ้นเรื่อยๆ และตามแกน Y ฉันจะมีคลาสที่เป็นไปได้สำหรับการวางตำแหน่ง: ศูนย์และหนึ่ง

กราฟสำหรับการถดถอยโลจิสติก

ถ้าเราวาดจุดข้อมูลออกมา มันจะหน้าตาเป็นยังไง? การวิเคราะห์ของเราแสดงให้เห็นว่าผู้สมัครที่มี `p_degree` ในระดับสูงมีแนวโน้มที่จะได้รับการว่าจ้างมากกว่า ดังนั้น มันอาจมีลักษณะประมาณนี้ โดยที่ผู้สมัครที่มีค่า `p_degree` เล็กน้อยจะลดลงที่ศูนย์ และผู้สมัครที่มี `p_degree` สูงก็จะได้อันดับหนึ่ง

p-degree สำหรับการถดถอยโลจิสติก

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

ย้ำ

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

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

คำทำนาย

สิ่งที่เราเห็นตรงนี้คือข้อจำกัดร้ายแรงบางประการในการใช้การถดถอยเชิงเส้นในการจำแนกประเภท แล้วเราต้องทำอย่างไร? เราจำเป็นต้องสร้างแบบจำลองที่เป็นอันดับหนึ่ง: ไม่ต่ำกว่าศูนย์หรือสูงกว่าหนึ่ง ดังนั้นจึงต้องผูกไว้ระหว่างศูนย์ถึงหนึ่ง และเลขสอง ไม่ว่าจะออกมาจากฟังก์ชันนั้น สมการที่เราสร้างขึ้น เราอาจไม่ควรมองว่ามันเป็นการทำนาย แต่เป็นขั้นตอนในการทำนายขั้นสุดท้าย

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

img

มันมีวิธีผูกเส้นตรงระหว่าง 0 ถึง 1 สิ่งที่เราทำได้คือนำฟังก์ชันนี้ที่เราเพิ่งสร้างขึ้นมาใส่ไว้ในฟังก์ชันอื่น สิ่งที่เรียกว่าฟังก์ชันซิกมอยด์

ฟังก์ชั่นสำหรับการถดถอยโลจิสติก

ผมจะใส่สมการเชิงเส้นที่เราเพิ่งมี และผมจะย่อมันลงในฟังก์ชันซิกมอยด์ แล้วใส่มันเป็นเลขชี้กำลัง

ฟังก์ชั่นสำหรับการถดถอยโลจิสติก

สิ่งที่เกิดขึ้นคือแทนที่จะได้เส้นตรง เราได้เส้นที่หน้าตาแบบนี้ มันติดอยู่ที่หนึ่ง มันเข้ามาแล้วย่อตัวลงไป แล้วมันติดอยู่ที่ศูนย์

การถดถอยโลจิสติก

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

การถดถอยโลจิสติก

ฉันหมายถึงอะไร? นั่นหมายความว่าเมื่อฉันทำนาย ฉันจะได้รับค่าทศนิยมระหว่าง 0 ถึง 1 และสิ่งที่ฉันจะทำคือถือว่ามันเป็นความน่าจะเป็นที่การทำนายของฉันอยู่ในระดับที่เป็นบวก

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

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

พีดีกรี

ตอนนี้ฉันมีฟังก์ชันที่ให้การทำนายระหว่างศูนย์ถึงหนึ่ง และฉันถือว่ามันเป็นความน่าจะเป็น และถ้าความน่าจะเป็นนั้นสูงกว่า 0.5 หรือ 50% ฉันบอกว่า โอเค เป็นบวกระดับ 50 และถ้ามันต่ำกว่า 1000% ฉันบอกว่านั่นคือระดับลบ ศูนย์ นั่นคือวิธีการทำงานของการถดถอยโลจิสติก และตอนนี้เราเข้าใจแล้ว มาเขียนโค้ดและปรับแต่งมันกันดีกว่า ฉันจะตั้งค่าไฮเปอร์พารามิเตอร์ 'max_iter' เป็น XNUMX พารามิเตอร์นี้อ้างอิงถึงจำนวนการวนซ้ำสูงสุดเพื่อให้นักแก้ปัญหามาบรรจบกัน

# Build model
model = LogisticRegression(max_iter=1000) # Fit model to training data
model.fit(X_train, y_train) LogisticRegression(max_iter=1000)

ประเมินค่า

ตอนนี้ได้เวลาดูว่าโมเดลของเราทำงานอย่างไร ถึงเวลาประเมินโมเดล Logistic Regression ดังนั้น โปรดจำไว้ว่าคราวนี้ เมตริกประสิทธิภาพที่เราสนใจคือคะแนนความแม่นยำ และเราต้องการคะแนนที่แม่นยำ และเราอยากเอาชนะเส้นฐานที่ 0.68 ความแม่นยำของแบบจำลองสามารถคำนวณได้โดยใช้ฟังก์ชันความแม่นยำ_คะแนน ฟังก์ชันนี้ต้องการอาร์กิวเมนต์สองรายการ ได้แก่ ป้ายกำกับที่แท้จริงและป้ายกำกับที่คาดการณ์

acc_train = accuracy_score(y_train, model.predict(X_train))
acc_test = model.score(X_test, y_test) print("Training Accuracy:", round(acc_train, 2))
print("Test Accuracy:", round(acc_test, 2)) Training Accuracy: 0.9
Test Accuracy: 0.88

เราสามารถเห็นความแม่นยำในการฝึกของเราได้ที่ 90% มันกำลังเอาชนะพื้นฐาน ความแม่นยำในการทดสอบของเราลดลงเล็กน้อยที่ 88% มันเอาชนะเส้นฐานได้และใกล้เคียงกับความแม่นยำในการฝึกซ้อมของเรามาก นั่นเป็นข่าวดีเพราะนั่นหมายความว่าโมเดลของเราไม่ได้พอดีเกินไปหรืออะไรเลย

ผลลัพธ์ของแบบจำลองการถดถอยโลจิสติก

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

model.predict(X_train)[:5] array([0, 1, 1, 1, 1])

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

y_train_pred_proba = model.predict_proba(X_train)
print(y_train_pred_proba[:5]) [[0.92003219 0.07996781] [0.03202019 0.96797981] [0.00678421 0.99321579] [0.03889446 0.96110554] [0.00245525 0.99754475]]

เราจะเห็นรายการแบบซ้อนซึ่งมีสองคอลัมน์ที่แตกต่างกันอยู่ในนั้น คอลัมน์ทางด้านซ้ายแสดงถึงความน่าจะเป็นที่จะไม่ได้วางผู้สมัคร หรือระดับเชิงลบของเรา 'ไม่ได้วาง' อีกคอลัมน์หนึ่งแสดงถึงคลาสเชิงบวก `วาง` หรือความน่าจะเป็นที่ผู้สมัครจะถูกวาง เราจะเน้นที่คอลัมน์ที่สอง หากเราดูค่าประมาณความน่าจะเป็นอันแรกถูกต้อง เราจะเห็นว่านี่คือ 0.07 เนื่องจากนั่นต่ำกว่า 50% แบบจำลองของเราบอกว่า การทำนายของฉันจึงเป็นศูนย์ และสำหรับการทำนายต่อไปนี้ เราจะเห็นว่าค่าเหล่านี้มากกว่า 0.5 ทั้งหมด และนั่นคือสาเหตุที่แบบจำลองของเราทำนายค่าหนึ่งในตอนท้าย

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

# Features names
features = ['gender', 'ssc_p', 'ssc_b', 'hsc_p', 'hsc_b', 'hsc_s', 'degree_p' ,'degree_t', 'workex', 'etest_p', 'specialisation', 'mba_p']
# Get importances
importances = model.coef_[0]
# Put importances into a Series
odds_ratios = pd.Series(np.exp(importances), index= features).sort_values()
# Review odds_ratios.head() mba_p 0.406590
degree_t 0.706021
specialisation 0.850301
hsc_b 0.876864
etest_p 0.877831
dtype: float64

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

# Horizontal bar chart, five largest coefficients
odds_ratios.tail().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("High Importance Features");
# แผนภูมิแท่งแนวนอน ห้าค่าสัมประสิทธิ์ที่ใหญ่ที่สุด odds_ratios.tail().plot(kind=

ตอนนี้ผมอยากให้คุณจินตนาการถึงเส้นตั้งตรงที่ 5 และผมอยากเริ่มด้วยการดูมัน เรามาพูดถึงแต่ละเรื่องเป็นรายบุคคลหรือเพียงคู่แรก เรามาเริ่มกันที่นี่ด้วย 'ssc_p' ซึ่งหมายถึง 'เปอร์เซ็นต์การศึกษาระดับมัธยมศึกษา - เกรด 10' และเราจะเห็นว่าอัตราต่อรองอยู่ที่ 30 ทีนี้หมายความว่าอย่างไร? หมายความว่าหากผู้สมัครมี 'ssc_p' สูง โอกาสที่จะได้ตำแหน่งจะสูงกว่าผู้สมัครคนอื่นๆ ถึงหกเท่า โดยทุกสิ่งจะเท่าเทียมกัน วิธีคิดอีกวิธีหนึ่งคือ เมื่อผู้สมัครมี `ssc_p` โอกาสในการรับสมัครของผู้สมัครจะเพิ่มขึ้นหกเท่า

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

odds_ratios.head().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("Low Importance Features");
คุณลักษณะที่มีความสำคัญต่ำ

สิ่งแรกที่เราต้องดูตรงนี้คือ สังเกตบนแกน x ทุกอย่างมีค่าต่ำกว่าหนึ่งหรือต่ำกว่า ทีนี้หมายความว่าอย่างไร? ลองดูอัตราต่อรองที่น้อยที่สุดของเราที่นี่ มันคือ mba_p ซึ่งหมายถึงเปอร์เซ็นต์ MBA เราจะเห็นว่าพร้อมประมาณ 0.45 ทีนี้หมายความว่าอย่างไร? ทีนี้ ผลต่างระหว่าง 0.45 กับ 1 คือ 0.55 เอาล่ะ? และตัวเลขนั้นหมายความว่าอย่างไร? ผู้สมัครที่เรียน MBA มีโอกาสน้อยที่จะได้รับการคัดเลือก 55% สิ่งอื่น ๆ ทั้งหมดเท่าเทียมกัน เอาล่ะ? ดังนั้นจึงลดอัตราการรับสมัครลง 0.55 หรือ 55% และนั่นก็จริงสำหรับทุกสิ่งที่นี่

สรุป

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

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

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

รหัสที่มาของโครงการ: https://github.com/SawsanYusuf/Campus-Recruitment.git

สื่อที่แสดงในบทความนี้ไม่ได้เป็นของ Analytics Vidhya และถูกใช้ตามดุลยพินิจของผู้เขียน 

ประทับเวลา:

เพิ่มเติมจาก การวิเคราะห์ วิทยา