บทนำ
บางครั้งก็สับสนกับ การถดถอยเชิงเส้น โดยสามเณร – เนื่องจากการแบ่งปันระยะ ถดถอย - การถดถอยโลจิสติก ต่างจาก .มาก การถดถอยเชิงเส้น. ในขณะที่การถดถอยเชิงเส้นทำนายค่าเช่น 2, 2.45, 6.77 หรือ ค่าต่อเนื่องทำให้เป็น ถดถอย อัลกอริทึม การถดถอยโลจิสติก ทำนายค่าต่างๆ เช่น 0 หรือ 1, 1 หรือ 2 หรือ 3 ซึ่งก็คือ ค่าที่ไม่ต่อเนื่องทำให้เป็น การจัดหมวดหมู่ อัลกอริทึม ใช่ เรียกว่า ถดถอย แต่เป็น การจัดหมวดหมู่ อัลกอริทึม เพิ่มเติมเกี่ยวกับสิ่งนั้นในอีกสักครู่
ดังนั้น หากปัญหาวิทยาศาสตร์ข้อมูลของคุณเกี่ยวข้องกับค่าต่อเนื่อง คุณสามารถใช้ a ถดถอย อัลกอริทึม (การถดถอยเชิงเส้นเป็นหนึ่งในนั้น) มิฉะนั้น หากเกี่ยวข้องกับการจัดประเภทอินพุต ค่าที่ไม่ต่อเนื่อง หรือคลาส คุณสามารถใช้ a การจัดหมวดหมู่ อัลกอริทึม (การถดถอยโลจิสติกเป็นหนึ่งในนั้น)
ในคู่มือนี้ เราจะทำการถดถอยโลจิสติกใน Python ด้วยไลบรารี Scikit-Learn เราจะอธิบายด้วยว่าทำไมคำว่า “การถดถอย” มีอยู่ในชื่อและวิธีการทำงานของการถดถอยโลจิสติก
ในการทำเช่นนั้น ก่อนอื่นเราจะโหลดข้อมูลที่จะจัดประเภท แสดงภาพ และประมวลผลล่วงหน้า จากนั้นเราจะสร้างแบบจำลองการถดถอยโลจิสติกที่จะเข้าใจข้อมูลนั้น จากนั้น โมเดลนี้จะถูกประเมิน และใช้ในการทำนายค่าตามข้อมูลใหม่
แรงจูงใจ
บริษัทที่คุณทำงานเป็นหุ้นส่วนกับฟาร์มเกษตรในตุรกี ความร่วมมือนี้เกี่ยวข้องกับการขายเมล็ดฟักทอง เมล็ดฟักทองมีความสำคัญมากสำหรับโภชนาการของมนุษย์ พวกเขามีสัดส่วนที่ดีของคาร์โบไฮเดรต ไขมัน โปรตีน แคลเซียม โพแทสเซียม ฟอสฟอรัส แมกนีเซียม เหล็ก และสังกะสี
ในทีมวิทยาศาสตร์ข้อมูล งานของคุณคือการบอกความแตกต่างระหว่างชนิดของเมล็ดฟักทองโดยใช้ข้อมูล – หรือ การจำแนกประเภท ข้อมูลตามชนิดของเมล็ด
ฟาร์มในตุรกีใช้เมล็ดฟักทองสองชนิด ชนิดหนึ่งเรียกว่า เซอร์เชเวลิก และอื่น ๆ เออร์กัป ซิวรีซี.
ในการจำแนกเมล็ดฟักทอง ทีมงานของคุณได้ติดตามเอกสารปี 2021 “การใช้แมชชีนเลิร์นนิงในการจำแนกเมล็ดฟักทอง (Cucurbita pepo L.) ทรัพยากรพันธุกรรมและวิวัฒนาการของพืช” จาก Koklu, Sarigil และ Ozbek - ในบทความนี้มีวิธีการในการถ่ายภาพและแยกการวัดเมล็ดออกจากภาพ
หลังจากเสร็จสิ้นกระบวนการที่อธิบายไว้ในกระดาษ การวัดต่อไปนี้ถูกดึงออกมา:
- พื้นที่ – จำนวนพิกเซลภายในขอบเมล็ดฟักทอง
- ปริมณฑล – เส้นรอบวงเป็นพิกเซลของเมล็ดฟักทอง
- ความยาวแกนหลัก – เส้นรอบวงเป็นพิกเซลของเมล็ดฟักทองด้วย
- ความยาวแกนรอง – ระยะแกนเล็กของเมล็ดฟักทอง
- ความผิดปกติ – ความเบี้ยวของเมล็ดฟักทอง
- พื้นที่นูน – จำนวนพิกเซลของเปลือกนูนที่เล็กที่สุดในบริเวณที่เกิดจากเมล็ดฟักทอง
- ขอบเขต – อัตราส่วนของพื้นที่เมล็ดฟักทองต่อกรอบพิกเซล
- เส้นผ่านศูนย์กลางเทียบเท่า – รากที่สองของการคูณพื้นที่เมล็ดฟักทองด้วย XNUMX หารด้วย pi
- ความเป็นปึกแผ่น – สัดส่วนพื้นที่เมล็ดฟักทองสัมพันธ์กับพื้นที่วงกลมที่มีเส้นรอบวงเท่ากัน
- ความแข็งแรง – สภาพนูนและนูนของเมล็ดฟักทอง
- ความกลม – การตกไข่ของเมล็ดฟักทองโดยไม่คำนึงถึงขอบบิดเบี้ยว
- อัตราส่วน – อัตราส่วนกว้างยาวของเมล็ดฟักทอง
นั่นคือการวัดที่คุณต้องทำงานด้วย นอกจากการวัดแล้วยังมี ชั้น ฉลากสำหรับเมล็ดฟักทองทั้งสองชนิด
ในการเริ่มจำแนกเมล็ดพันธุ์ ให้นำเข้าข้อมูลแล้วเริ่มดูกัน
การทำความเข้าใจชุดข้อมูล
หมายเหตุ คุณสามารถดาวน์โหลดชุดข้อมูลฟักทอง โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม.
หลังจากดาวน์โหลดชุดข้อมูลแล้ว เราสามารถโหลดลงในโครงสร้าง dataframe โดยใช้คำสั่ง pandas
ห้องสมุด. เนื่องจากเป็นไฟล์ excel เราจะใช้คำสั่ง read_excel()
วิธี:
import pandas as pd
fpath = 'dataset/pumpkin_seeds_dataset.xlsx'
df = pd.read_excel(fpath)
เมื่อโหลดข้อมูลแล้ว เราสามารถดู 5 แถวแรกได้อย่างรวดเร็วโดยใช้ปุ่ม head()
วิธี:
df.head()
ผลลัพธ์นี้ใน:
Area Perimeter Major_Axis_Length Minor_Axis_Length Convex_Area Equiv_Diameter Eccentricity Solidity Extent Roundness Aspect_Ration Compactness Class
0 56276 888.242 326.1485 220.2388 56831 267.6805 0.7376 0.9902 0.7453 0.8963 1.4809 0.8207 Çerçevelik
1 76631 1068.146 417.1932 234.2289 77280 312.3614 0.8275 0.9916 0.7151 0.8440 1.7811 0.7487 Çerçevelik
2 71623 1082.987 435.8328 211.0457 72663 301.9822 0.8749 0.9857 0.7400 0.7674 2.0651 0.6929 Çerçevelik
3 66458 992.051 381.5638 222.5322 67118 290.8899 0.8123 0.9902 0.7396 0.8486 1.7146 0.7624 Çerçevelik
4 66107 998.146 383.8883 220.4545 67117 290.1207 0.8187 0.9850 0.6752 0.8338 1.7413 0.7557 Çerçevelik
ที่นี่ เรามีการวัดทั้งหมดในคอลัมน์ที่เกี่ยวข้อง ของเรา คุณสมบัติและยัง ชั้น คอลัมน์ของเรา เป้าซึ่งเป็นอันสุดท้ายในดาต้าเฟรม เราสามารถดูว่าเรามีการวัดกี่หน่วยโดยใช้ shape
แอตทริบิวต์:
df.shape
ผลลัพธ์คือ:
(2500, 13)
ผลลัพธ์ของรูปร่างบอกเราว่ามี 2500 รายการ (หรือแถว) ในชุดข้อมูลและ 13 คอลัมน์ เนื่องจากเรารู้ว่ามีคอลัมน์เป้าหมายหนึ่งคอลัมน์ ซึ่งหมายความว่าเรามีคอลัมน์คุณลักษณะ 12 คอลัมน์
ตอนนี้เราสามารถสำรวจตัวแปรเป้าหมายได้แล้ว เมล็ดฟักทอง Class
. เนื่องจากเราจะทำนายตัวแปรนั้น น่าสนใจที่จะดูว่าเรามีเมล็ดฟักทองแต่ละตัวอย่างกี่ตัวอย่าง โดยปกติ ยิ่งความแตกต่างระหว่างจำนวนอินสแตนซ์ในชั้นเรียนของเราน้อยเท่าใด ตัวอย่างของเราก็จะยิ่งสมดุลมากขึ้นและการทำนายของเราก็จะยิ่งดีขึ้นเท่านั้น
การตรวจสอบนี้สามารถทำได้โดยการนับตัวอย่างเมล็ดพันธุ์แต่ละตัวอย่างด้วย value_counts()
วิธี:
df['Class'].value_counts()
รหัสด้านบนแสดง:
Çerçevelik 1300
Ürgüp Sivrisi 1200
Name: Class, dtype: int64
เราจะเห็นได้ว่ามีตัวอย่าง 1300 ตัวอย่าง เซอร์เชเวลิก เมล็ดพันธุ์และตัวอย่าง 1200 ตัวอย่าง เออร์กัป ซิวรีซี เมล็ดพันธุ์ สังเกตว่าความแตกต่างระหว่างตัวอย่างเหล่านี้คือ 100 ตัวอย่าง ซึ่งแตกต่างกันเล็กน้อย ซึ่งดีสำหรับเรา และบ่งชี้ว่าไม่จำเป็นต้องปรับสมดุลจำนวนตัวอย่าง
มาดูสถิติเชิงพรรณนาของคุณสมบัติของเราด้วย describe()
วิธีดูว่าข้อมูลกระจายตัวได้ดีแค่ไหน เราจะย้ายตารางผลลัพธ์ด้วย T
เพื่อให้ง่ายต่อการเปรียบเทียบระหว่างสถิติต่างๆ:
df.describe().T
ตารางผลลัพธ์คือ:
count mean std min 25% 50% 75% max
Area 2500.0 80658.220800 13664.510228 47939.0000 70765.000000 79076.00000 89757.500000 136574.0000
Perimeter 2500.0 1130.279015 109.256418 868.4850 1048.829750 1123.67200 1203.340500 1559.4500
Major_Axis_Length 2500.0 456.601840 56.235704 320.8446 414.957850 449.49660 492.737650 661.9113
Minor_Axis_Length 2500.0 225.794921 23.297245 152.1718 211.245925 224.70310 240.672875 305.8180
Convex_Area 2500.0 81508.084400 13764.092788 48366.0000 71512.000000 79872.00000 90797.750000 138384.0000
Equiv_Diameter 2500.0 319.334230 26.891920 247.0584 300.167975 317.30535 338.057375 417.0029
Eccentricity 2500.0 0.860879 0.045167 0.4921 0.831700 0.86370 0.897025 0.9481
Solidity 2500.0 0.989492 0.003494 0.9186 0.988300 0.99030 0.991500 0.9944
Extent 2500.0 0.693205 0.060914 0.4680 0.658900 0.71305 0.740225 0.8296
Roundness 2500.0 0.791533 0.055924 0.5546 0.751900 0.79775 0.834325 0.9396
Aspect_Ration 2500.0 2.041702 0.315997 1.1487 1.801050 1.98420 2.262075 3.1444
Compactness 2500.0 0.704121 0.053067 0.5608 0.663475 0.70770 0.743500 0.9049
โดยดูจากตารางเมื่อเปรียบเทียบ หมายความ และ ส่วนเบี่ยงเบนมาตรฐาน (std
) จะเห็นได้ว่าคุณลักษณะส่วนใหญ่มีค่าเฉลี่ยที่ห่างไกลจากค่าเบี่ยงเบนมาตรฐาน นั่นแสดงว่าค่าข้อมูลไม่ได้กระจุกตัวอยู่รอบ ๆ ค่าเฉลี่ย แต่จะกระจัดกระจายอยู่รอบๆ ค่านั้นมากกว่า - กล่าวอีกนัยหนึ่งคือ ความแปรปรวนสูง.
นอกจากนี้ เมื่อมองที่ ขั้นต่ำ (min
) and สูงสุด (max
) คอลัมน์ คุณลักษณะบางอย่าง เช่น Area
และ Convex_Area
มีค่าต่ำสุดและสูงสุดแตกต่างกันมาก ซึ่งหมายความว่าคอลัมน์เหล่านั้นมีข้อมูลขนาดเล็กมากและมีค่าข้อมูลที่ใหญ่มากด้วย หรือ แอมพลิจูดที่สูงขึ้น ระหว่างค่าข้อมูล
ด้วยความแปรปรวนสูง แอมพลิจูดสูง และคุณลักษณะที่มีหน่วยการวัดต่างกัน ข้อมูลส่วนใหญ่ของเราจะได้รับประโยชน์จากการมีมาตราส่วนเดียวกันสำหรับคุณลักษณะทั้งหมดหรือ ปรับขนาด. การปรับขนาดข้อมูลจะทำให้ข้อมูลอยู่กึ่งกลางรอบๆ ค่าเฉลี่ยและลดความแปรปรวนของข้อมูล
สถานการณ์นี้อาจบ่งชี้ว่าข้อมูลมีค่าผิดปกติและมีค่ามาก ดังนั้นควรทานบ้างดีที่สุด การรักษานอกรีต นอกจากการปรับขนาดข้อมูลแล้ว
มีอัลกอริธึมการเรียนรู้ของเครื่องบางตัว เช่น อัลกอริธึมแบบต้นไม้ เช่น การจำแนกป่าแบบสุ่มซึ่งไม่ได้รับผลกระทบจากความแปรปรวนของข้อมูลสูง ค่าผิดปกติ และค่าสุดขั้ว การถดถอยโลจิสติก แตกต่างกัน โดยขึ้นอยู่กับฟังก์ชันที่จัดหมวดหมู่ค่าของเรา และพารามิเตอร์ของฟังก์ชันนั้นอาจได้รับผลกระทบจากค่าที่อยู่นอกแนวโน้มข้อมูลทั่วไปและมีความแปรปรวนสูง
เราจะเข้าใจมากขึ้นเกี่ยวกับการถดถอยโลจิสติกในอีกสักครู่เมื่อเรานำไปใช้ สำหรับตอนนี้ เราสามารถสำรวจข้อมูลของเราต่อไปได้
หมายเหตุ มีคำกล่าวที่นิยมในวิทยาการคอมพิวเตอร์ว่า “ขยะเข้า ขยะออก” (GIGO)ซึ่งเหมาะสำหรับการเรียนรู้ของเครื่อง ซึ่งหมายความว่าเมื่อเรามีข้อมูลขยะ – การวัดที่ไม่ได้อธิบายปรากฏการณ์ในตัวเอง ข้อมูลที่ไม่เข้าใจและเตรียมมาอย่างดีตามประเภทของอัลกอริทึมหรือรุ่น มักจะสร้างเอาต์พุตที่ไม่ถูกต้องซึ่งใช้งานไม่ได้ แบบวันต่อวัน
นี่เป็นหนึ่งในเหตุผลที่การสำรวจ ทำความเข้าใจข้อมูล และวิธีการทำงานของแบบจำลองที่เลือกมีความสำคัญมาก การทำเช่นนี้ทำให้เราสามารถหลีกเลี่ยงการใส่ขยะลงในแบบจำลองของเรา โดยใส่คุณค่าเข้าไปแทน และรับคุณค่าออกมา
การแสดงข้อมูล
จนถึงปัจจุบัน ด้วยสถิติเชิงพรรณนา เรามีภาพรวมที่ค่อนข้างเป็นนามธรรมของคุณสมบัติบางอย่างของข้อมูล ขั้นตอนสำคัญอีกขั้นตอนหนึ่งคือการเห็นภาพและยืนยันสมมติฐานของเราว่ามีความแปรปรวน แอมพลิจูด และค่าผิดปกติสูง เพื่อดูว่าสิ่งที่เราสังเกตจนถึงตอนนี้แสดงในข้อมูลหรือไม่ เราสามารถพล็อตกราฟบางส่วนได้
นอกจากนี้ยังเป็นที่น่าสนใจที่จะเห็นว่าคุณลักษณะที่เกี่ยวข้องกับทั้งสองคลาสที่จะคาดการณ์ได้อย่างไร ในการทำเช่นนั้น ให้นำเข้า seaborn
แพ็คเกจและใช้ pairplot
กราฟเพื่อดูการกระจายแต่ละคุณลักษณะ และการแยกแต่ละคลาสตามคุณลักษณะ:
import seaborn as sns
sns.pairplot(data=df, hue='Class')
หมายเหตุ โค้ดด้านบนอาจใช้เวลาสักครู่ในการทำงาน เนื่องจากแพร์พล็อตจะรวม scatterplot ของคุณลักษณะทั้งหมด (สามารถทำได้) และยังแสดงการกระจายคุณลักษณะด้วย
เมื่อดูแผนภาพคู่ เราจะเห็นว่าในกรณีส่วนใหญ่จุดของ Çerçevelik
แยกชั้นอย่างชัดเจนจากจุดของ Ürgüp Sivrisi
ระดับ. คะแนนของชั้นเรียนหนึ่งจะอยู่ทางขวาเมื่อคนอื่นอยู่ทางซ้าย หรือบางส่วนอยู่ด้านบนขณะที่คนอื่นๆ อยู่ด้านล่าง หากเราใช้เส้นโค้งหรือเส้นบางประเภทเพื่อแยกชั้นเรียน แสดงว่าแยกได้ง่ายขึ้น หากผสมกัน การจัดประเภทจะเป็นงานที่ยากกว่า
ตัว Vortex Indicator ได้ถูกนำเสนอลงในนิตยสาร Eccentricity
, Compactness
และ Aspect_Ration
คอลัมน์ บางจุดที่ "แยก" หรือเบี่ยงเบนไปจากแนวโน้มข้อมูลทั่วไป - ค่าผิดปกติ - สามารถมองเห็นได้ง่ายเช่นกัน
เมื่อดูที่เส้นทแยงมุมจากด้านซ้ายบนไปด้านขวาล่างของแผนภูมิ โปรดสังเกตว่าการกระจายข้อมูลมีการกำหนดรหัสสีตามชั้นเรียนของเราด้วย รูปร่างการกระจายและระยะห่างระหว่างเส้นโค้งทั้งสองเป็นตัวบ่งชี้อื่นๆ ว่าพวกมันสามารถแยกออกได้อย่างไร - ยิ่งห่างจากกันมากเท่าไหร่ก็ยิ่งดี ในกรณีส่วนใหญ่ พวกมันจะไม่ซ้อนทับ ซึ่งหมายความว่าพวกมันแยกออกง่ายกว่า และยังช่วยสนับสนุนงานของเราด้วย
ตามลำดับ เราสามารถพล็อต boxplot ของตัวแปรทั้งหมดด้วย sns.boxplot()
กระบวนการ. ส่วนใหญ่ การจัดวางบ็อกซ์พล็อตในแนวนอนจะเป็นประโยชน์ ดังนั้นรูปร่างของบ็อกซ์พล็อตจะเหมือนกับรูปร่างการกระจาย เราสามารถทำได้ด้วย orient
ข้อโต้แย้ง:
sns.boxplot(data=df, orient='h')
ในโครงเรื่องข้างต้น สังเกตว่า Area
และ Convex_Area
มีขนาดที่สูงมากเมื่อเทียบกับขนาดของคอลัมน์อื่น เพื่อให้สามารถดู boxplots ทั้งหมดได้ เราสามารถปรับขนาดคุณสมบัติและลงจุดใหม่อีกครั้ง
ก่อนทำนั้น ให้ทำความเข้าใจว่าหากมีค่าของคุณสมบัติที่เกี่ยวข้องกับค่าอื่นๆ อย่างใกล้ชิด เช่น หากมีค่าที่มากขึ้นเช่นกันเมื่อค่าคุณสมบัติอื่นๆ มีขนาดใหญ่ขึ้น ให้มี ความสัมพันธ์ทางบวก; หรือหากมีค่าที่ทำตรงกันข้ามให้น้อยลงในขณะที่ค่าอื่น ๆ จะเล็กลงโดยมี a ความสัมพันธ์ทางลบ.
นี่เป็นสิ่งสำคัญที่ต้องพิจารณา เนื่องจากการมีความสัมพันธ์ที่แน่นแฟ้นในข้อมูลอาจหมายความว่าบางคอลัมน์ได้มาจากคอลัมน์อื่นหรือมีความหมายคล้ายกับแบบจำลองของเรา เมื่อสิ่งนี้เกิดขึ้น ผลลัพธ์ของแบบจำลองอาจถูกประเมินค่าสูงไป และเราต้องการผลลัพธ์ที่ใกล้เคียงกับความเป็นจริงมากที่สุด หากมีความสัมพันธ์ที่ชัดเจน ก็หมายความว่าเราสามารถลดจำนวนจุดสนใจ และใช้คอลัมน์น้อยลงทำให้โมเดลมีมากขึ้น ร่าเริง.
หมายเหตุ ความสัมพันธ์เริ่มต้นที่คำนวณด้วย corr()
วิธีการคือ ค่าสัมประสิทธิ์สหสัมพันธ์เพียร์สัน. สัมประสิทธิ์นี้ถูกระบุเมื่อข้อมูลเป็นข้อมูลเชิงปริมาณ กระจายตามปกติ ไม่มีค่าผิดปกติ และมีความสัมพันธ์เชิงเส้น
อีกทางเลือกหนึ่งคือการคำนวณ ค่าสัมประสิทธิ์สหสัมพันธ์ของสเปียร์แมน. สัมประสิทธิ์ของสเปียร์แมนจะใช้เมื่อข้อมูลอยู่ในลำดับ ไม่เชิงเส้น มีการแจกแจงใดๆ และมีค่าผิดปกติ โปรดสังเกตว่าข้อมูลของเราไม่ตรงกับสมมติฐานของเพียร์สันหรือสเปียร์แมนโดยสิ้นเชิง (ยังมีวิธีการสหสัมพันธ์เพิ่มเติม เช่น ของเคนดัลล์) เนื่องจากข้อมูลของเราเป็นข้อมูลเชิงปริมาณและเป็นสิ่งสำคัญสำหรับเราในการวัดความสัมพันธ์เชิงเส้น เราจะใช้สัมประสิทธิ์ของเพียร์สัน
เรามาดูความสัมพันธ์ระหว่างตัวแปรกัน จากนั้นเราสามารถย้ายเพื่อประมวลผลข้อมูลล่วงหน้าได้ เราจะคำนวณความสัมพันธ์กับ corr()
วิธีการและเห็นภาพด้วย Seaborn's heatmap()
. ขนาดมาตรฐานแผนที่ความร้อนมักจะมีขนาดเล็ก ดังนั้นเราจะนำเข้า matplotlib
(เอ็นจิ้น/ไลบรารีการสร้างภาพทั่วไปที่ Seaborn สร้างขึ้นบน) และเปลี่ยนขนาดด้วย figsize
:
import matplotlib.pyplot as plt
plt.figure(figsize=(15, 10))
correlations = df.corr()
sns.heatmap(correlations, annot=True)
ในแผนที่ความหนาแน่นนี้ ค่าที่ใกล้กับ 1 หรือ -1 คือค่าที่เราต้องให้ความสนใจ กรณีแรกแสดงถึงความสัมพันธ์เชิงบวกสูง และกรณีที่สองมีความสัมพันธ์เชิงลบสูง ค่าทั้งสอง ถ้าไม่เกิน 0.8 หรือ -0.8 จะเป็นประโยชน์ต่อแบบจำลองการถดถอยโลจิสติกของเรา
เมื่อมีความสัมพันธ์กันสูงเช่นหนึ่งใน 0.99
ระหว่าง Aspec_Ration
และ Compactness
หมายความว่าเราเลือกใช้ได้เท่านั้น Aspec_Ration
หรือเท่านั้น Compactness
, แทนที่จะเป็นทั้งคู่ (เพราะเกือบจะเท่ากัน ตัวทำนาย ของกันและกัน) เดียวกันถือเป็นสำหรับ Eccentricity
และ Compactness
กับ -0.98
สหสัมพันธ์สำหรับ Area
และ Perimeter
กับ 0.94
ความสัมพันธ์และคอลัมน์อื่นๆ
การประมวลผลข้อมูลล่วงหน้า
เนื่องจากเราได้สำรวจข้อมูลมาระยะหนึ่งแล้ว เราจึงสามารถเริ่มประมวลผลล่วงหน้าได้ ตอนนี้ ลองใช้คุณสมบัติทั้งหมดสำหรับการทำนายชั้นเรียนกัน หลังจากได้รับโมเดลแรก ซึ่งเป็นพื้นฐานแล้ว เราสามารถลบคอลัมน์ที่มีความสัมพันธ์สูงบางคอลัมน์และเปรียบเทียบกับข้อมูลพื้นฐานได้
คอลัมน์คุณสมบัติจะเป็นของเรา X
data และคอลัมน์ class ของเรา y
ข้อมูลเป้าหมาย:
y = df['Class']
X = df.drop(columns=['Class'], axis=1)
เปลี่ยนคุณสมบัติตามหมวดหมู่เป็นคุณสมบัติตัวเลข
เกี่ยวกับเรา Class
คอลัมน์ – ค่าของมันไม่ใช่ตัวเลข ซึ่งหมายความว่าเราต้องแปลงค่าเหล่านั้นด้วย มีหลายวิธีที่จะทำการเปลี่ยนแปลงนี้ ในที่นี้ เราจะใช้ replace()
วิธีการและแทนที่ Çerçevelik
ไปยัง 0
และ Ürgüp Sivrisi
ไปยัง 1
.
y = y.replace('Çerçevelik', 0).replace('Ürgüp Sivrisi', 1)
จำการทำแผนที่ไว้! เมื่ออ่านผลลัพธ์จากโมเดลของคุณ คุณจะต้องแปลงกลับเป็นอย่างน้อยในความคิดของคุณ หรือเปลี่ยนกลับเป็นชื่อคลาสสำหรับผู้ใช้รายอื่น
การแบ่งข้อมูลออกเป็นชุดฝึกและชุดทดสอบ
ในการสำรวจของเรา เราพบว่าคุณลักษณะต่างๆ จำเป็นต้องมีการปรับขนาด หากเราทำการปรับสเกลในตอนนี้ หรือแบบอัตโนมัติ เราจะปรับมาตราส่วนด้วยค่าทั้งหมด X
และ y
. ในกรณีนั้นเราจะมาแนะนำ การรั่วไหลของข้อมูลเนื่องจากค่าของชุดการทดสอบที่ใกล้จะเกิดขึ้นจะส่งผลต่อการปรับขนาด การรั่วไหลของข้อมูลเป็นสาเหตุทั่วไปของผลลัพธ์ที่ไม่สามารถทำซ้ำได้และประสิทธิภาพสูงที่ลวงตาของโมเดล ML
คิดสเกลแสดงว่าต้องแยกก่อน X
และ y
ข้อมูลต่อไปในรถไฟและชุดทดสอบแล้วไปที่ พอดี เครื่องชั่งบนชุดฝึกอบรมและเพื่อ แปลง ทั้งชุดรถไฟและชุดทดสอบ สำหรับสิ่งนี้ เราจะใช้ Scikit-Learn's train_test_split()
วิธี:
from sklearn.model_selection import train_test_split
SEED = 42
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=.25,
random_state=SEED)
การตั้งค่า test_size=.25
เพื่อให้แน่ใจว่าเราใช้ข้อมูล 25% สำหรับการทดสอบและ 75% สำหรับการฝึกอบรม สามารถละเว้นได้ เมื่อเป็นการแบ่งเริ่มต้น แต่ ไพธอน วิธีเขียนโค้ดแนะนำว่า "ชัดเจนดีกว่าโดยปริยาย"
หมายเหตุ ประโยค "ชัดเจนดีกว่าโดยนัย" เป็นการอ้างอิงถึง เซนแห่งไพธอนหรือ PEP20 มันวางคำแนะนำสำหรับการเขียนโค้ด Python หากปฏิบัติตามคำแนะนำเหล่านั้น จะถือว่ารหัส ไพธอน. คุณสามารถทราบข้อมูลเพิ่มเติมเกี่ยวกับมัน โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม.
หลังจากแยกข้อมูลออกเป็นชุดฝึกและชุดทดสอบแล้ว ควรพิจารณาว่าแต่ละชุดมีระเบียนกี่รายการเป็นแนวปฏิบัติที่ดี ที่สามารถทำได้ด้วย shape
แอตทริบิวต์:
X_train.shape, X_test.shape, y_train.shape, y_test.shape
สิ่งนี้แสดง:
((1875, 12), (625, 12), (1875,), (625,))
เราจะเห็นว่าหลังจากแยกแล้ว เรามีระเบียนสำหรับการฝึกอบรม 1875 รายการ และ 625 รายการสำหรับการทดสอบ
ข้อมูลการปรับขนาด
เมื่อเราเตรียมรถไฟและชุดทดสอบแล้ว เราสามารถดำเนินการปรับขนาดข้อมูลด้วย Scikit-Learn StandardScaler
วัตถุ (หรือเครื่องชั่งอื่น ๆ ที่ห้องสมุดจัดให้) เพื่อหลีกเลี่ยงการรั่วไหล เครื่องชั่งจะถูกติดตั้งเข้ากับ X_train
ข้อมูลและค่ารถไฟจะถูกใช้เพื่อปรับขนาด - หรือแปลง - ทั้งข้อมูลรถไฟและข้อมูลการทดสอบ:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
เนื่องจากคุณมักจะโทร:
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
สองบรรทัดแรกสามารถยุบได้ด้วยเอกพจน์ fit_transform()
โทร ซึ่งพอดีกับ scaler ในชุด และแปลงในครั้งเดียว ตอนนี้เราสามารถทำซ้ำกราฟ boxplot เพื่อดูความแตกต่างหลังจากปรับขนาดข้อมูลแล้ว
เมื่อพิจารณาถึงการปรับขนาดจะลบชื่อคอลัมน์ออก ก่อนการพล็อต เราสามารถจัดระเบียบข้อมูลรถไฟลงใน dataframe ด้วยชื่อคอลัมน์อีกครั้งเพื่ออำนวยความสะดวกในการแสดงภาพ:
column_names = df.columns[:12]
X_train = pd.DataFrame(X_train, columns=column_names)
sns.boxplot(data=X_train, orient='h')
ในที่สุดเราก็สามารถเห็น boxplot ทั้งหมดของเราได้แล้ว! สังเกตว่าทั้งหมดมีค่าผิดปกติและคุณลักษณะที่แสดงการกระจายเพิ่มเติมจากปกติ (ที่มีเส้นโค้งเบ้ไปทางซ้ายหรือขวา) เช่น Solidity
, Extent
, Aspect_Ration
และ Compactedness
เป็นชนิดเดียวกันที่มีความสัมพันธ์กันสูงกว่า
การลบ Outliers ด้วยวิธี IQR
เราทราบแล้วว่าการถดถอยโลจิสติกอาจได้รับผลกระทบจากค่าผิดปกติ วิธีรักษาอย่างหนึ่งก็คือใช้วิธีที่เรียกว่า ช่วงระหว่างควอไทล์ or ไอคิวอาร์. ขั้นตอนเริ่มต้นของวิธี IQR คือการแบ่งข้อมูลรถไฟของเราออกเป็นสี่ส่วน เรียกว่าควอร์ไทล์ ควอร์ไทล์แรก, Q1, จำนวน 25% ของข้อมูล, วินาที, Q2, ถึง 50%, ที่สาม, Q3ถึง 75% และอันสุดท้าย Q4ถึง 100% กล่องใน boxplot ถูกกำหนดโดยวิธี IQR และแสดงภาพของมัน
พิจารณา boxplot แนวนอน เส้นแนวตั้งทางด้านซ้ายทำเครื่องหมาย 25% ของข้อมูล เส้นแนวตั้งตรงกลาง 50% ของข้อมูล (หรือค่ามัธยฐาน) และเส้นแนวตั้งสุดท้ายทางด้านขวา 75% ของข้อมูล . ยิ่งสี่เหลี่ยมจัตุรัสทั้งสองที่กำหนดโดยเส้นแนวตั้งมีขนาดเท่ากัน หรือเส้นแนวตั้งมัธยฐานอยู่ตรงกลางมากขึ้น หมายความว่าข้อมูลของเราอยู่ใกล้กับการกระจายตัวแบบปกติหรือเบ้น้อยลง ซึ่งเป็นประโยชน์สำหรับการวิเคราะห์ของเรา
นอกจากกล่อง IQR แล้ว ยังมีเส้นแนวนอนทั้งสองด้าน เส้นเหล่านั้นทำเครื่องหมายค่าการกระจายต่ำสุดและสูงสุดที่กำหนดโดย
$$
ขั้นต่ำ = Q1 – 1.5*IQR
$$
และ
$$
สูงสุด = Q3 + 1.5*IQR
$$
IQR คือความแตกต่างระหว่าง Q3 และ Q1 (หรือ Q3 – Q1) และเป็นจุดศูนย์กลางของข้อมูลมากที่สุด นั่นคือเหตุผลที่เมื่อค้นหา IQR เราจะกรองค่าผิดปกติในส่วนปลายของข้อมูล หรือในจุดต่ำสุดและสูงสุด แผนภาพกล่องทำให้เราได้เห็นว่าผลลัพธ์ของวิธี IQR จะเป็นอย่างไร
ใช้แพนด้าได้ quantile()
วิธีการหาปริมาณของเราและ iqr
จาก scipy.stats
แพ็คเกจเพื่อรับช่วงข้อมูลระหว่างควอไทล์สำหรับแต่ละคอลัมน์:
from scipy.stats import iqr
Q1 = X_train.quantile(q=.25)
Q3 = X_train.quantile(q=.75)
IQR = X_train.apply(iqr)
ตอนนี้เรามี Q1, Q3 และ IQR เราสามารถกรองค่าที่ใกล้เคียงกับค่ามัธยฐาน:
minimum = X_train < (Q1-1.5*IQR)
maximum = X_train > (Q3+1.5*IQR)
filter = ~(minimum | maximum).any(axis=1)
X_train = X_train[filter]
หลังจากกรองแถวการฝึกแล้ว เราจะเห็นได้ว่าแถวนั้นยังอยู่ในข้อมูลกี่แถวด้วย shape
:
X_train.shape
ผลลัพธ์นี้ใน:
(1714, 12)
เราจะเห็นว่าจำนวนแถวเพิ่มขึ้นจาก 1875 เป็น 1714 หลังจากการกรอง ซึ่งหมายความว่า 161 แถวมีค่าผิดปกติหรือ 8.5% ของข้อมูล
หมายเหตุ ขอแนะนำว่าการกรองค่าผิดปกติ การลบค่า NaN และการดำเนินการอื่นๆ ที่เกี่ยวข้องกับการกรองและล้างข้อมูลจะอยู่ต่ำกว่าหรือไม่เกิน 10% ของข้อมูล ลองคิดหาวิธีแก้ไขปัญหาอื่นๆ หากการกรองหรือลบข้อมูลของคุณเกิน 10%
หลังจากลบค่าผิดปกติ เราเกือบจะพร้อมที่จะรวมข้อมูลในแบบจำลองแล้ว สำหรับการปรับโมเดล เราจะใช้ข้อมูลรถไฟ X_train
ถูกกรอง แต่สิ่งที่เกี่ยวกับ y_train
?
y_train.shape
ผลลัพธ์นี้:
(1875,)
สังเกตว่า y_train
ยังมี 1875 แถว เราต้องตรงกับจำนวน y_train
แถวเป็นจำนวน X_train
แถวและไม่ใช่แค่โดยพลการ เราจำเป็นต้องลบค่า y ของตัวอย่างเมล็ดฟักทองที่เราเอาออก ซึ่งน่าจะกระจัดกระจายไปทั่ว y_train
ชุด. ตัวกรอง X_train
stil มีดัชนีดั้งเดิมและดัชนีมีช่องว่างที่เราลบค่าผิดปกติ! จากนั้นเราสามารถใช้ดัชนีของ X_train
DataFrame เพื่อค้นหาค่าที่สอดคล้องกันใน y_train
:
y_train = y_train.iloc[X_train.index]
หลังจากทำอย่างนั้นแล้ว เราสามารถดูที่ y_train
รูปร่างอีกครั้ง:
y_train.shape
ผลลัพธ์ใด:
(1714,)
ดูคู่มือเชิงปฏิบัติสำหรับการเรียนรู้ Git ที่มีแนวทางปฏิบัติที่ดีที่สุด มาตรฐานที่ยอมรับในอุตสาหกรรม และเอกสารสรุปรวม หยุดคำสั่ง Googling Git และจริงๆ แล้ว เรียน มัน!
ตอนนี้ y_train
มี 1714 แถวและเหมือนกันกับ X_train
แถว ในที่สุดเราก็พร้อมที่จะสร้างแบบจำลองการถดถอยโลจิสติกของเราแล้ว!
การใช้แบบจำลองการถดถอยโลจิสติก
ส่วนที่ยากเสร็จแล้ว! การประมวลผลล่วงหน้ามักจะยากกว่าการพัฒนาโมเดล เมื่อพูดถึงการใช้ไลบรารี่อย่าง Scikit-Learn ซึ่งปรับปรุงการใช้โมเดล ML ให้เหลือเพียงไม่กี่บรรทัด
ก่อนอื่นเรานำเข้า LogisticRegression
คลาสและยกตัวอย่าง สร้าง a LogisticRegression
วัตถุ:
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression(random_state=SEED)
ประการที่สอง เราปรับข้อมูลรถไฟของเราให้เข้ากับ logreg
รุ่นที่มี fit()
วิธีและทำนายข้อมูลการทดสอบของเราด้วย predict()
วิธีการจัดเก็บผลลัพธ์เป็น y_pred
:
logreg.fit(X_train.values, y_train)
y_pred = logreg.predict(X_test)
เราได้ทำการคาดการณ์กับโมเดลของเราแล้ว! มาดู 3 แถวแรกใน X_train
เพื่อดูว่าเราใช้ข้อมูลใดบ้าง:
X_train[:3]
รหัสด้านบนส่งออก:
Area Perimeter Major_Axis_Length Minor_Axis_Length Convex_Area Equiv_Diameter Eccentricity Solidity Extent Roundness Aspect_Ration Compactness
0 -1.098308 -0.936518 -0.607941 -1.132551 -1.082768 -1.122359 0.458911 -1.078259 0.562847 -0.176041 0.236617 -0.360134
1 -0.501526 -0.468936 -0.387303 -0.376176 -0.507652 -0.475015 0.125764 0.258195 0.211703 0.094213 -0.122270 0.019480
2 0.012372 -0.209168 -0.354107 0.465095 0.003871 0.054384 -0.453911 0.432515 0.794735 0.647084 -0.617427 0.571137
และในการทำนาย 3 ครั้งแรกใน y_pred
เพื่อดูผลลัพธ์:
y_pred[:3]
ผลลัพธ์นี้ใน:
array([0, 0, 0])
สำหรับสามแถวนั้น การคาดการณ์ของเราคือเมล็ดพันธุ์ของชั้นหนึ่ง Çerçevelik
.
กับ การถดถอยโลจิสติก, แทนที่จะทำนายชั้นสุดท้าย เช่น 0
เราสามารถทำนายความน่าจะเป็นของแถวที่เกี่ยวข้องกับ 0
ระดับ. นี่คือสิ่งที่เกิดขึ้นจริงเมื่อการถดถอยโลจิสติกจัดประเภทข้อมูลและ predict()
จากนั้นเมธอดจะส่งการทำนายนี้ผ่านเกณฑ์เพื่อส่งคืนคลาส "ยาก" เพื่อทำนายความน่าจะเป็นของชั้นเรียน predict_proba()
ถูกนำมาใช้:
y_pred_proba = logreg.predict_proba(X_test)
มาดูค่า 3 ค่าแรกของการคาดคะเนความน่าจะเป็น y กัน:
y_pred_proba[:3]
ผลลัพธ์ใด:
# class 0 class 1
array([[0.54726628, 0.45273372],
[0.56324527, 0.43675473],
[0.86233349, 0.13766651]])
ตอนนี้ แทนที่จะเป็นศูนย์สามตัว เรามีหนึ่งคอลัมน์สำหรับแต่ละชั้นเรียน ในคอลัมน์ทางซ้าย เริ่มต้นด้วย 0.54726628
เป็นความน่าจะเป็นของข้อมูลที่เกี่ยวข้องกับคลาส 0
; และในคอลัมน์ขวา เริ่มต้นด้วย 0.45273372
, คือความน่าจะเป็นที่เกี่ยวข้องกับคลาส 1
.
หมายเหตุ ความแตกต่างในการจำแนกประเภทนี้เรียกอีกอย่างว่า ยาก และ อ่อนนุ่ม คาดการณ์. การคาดคะเนแบบยากจะบรรจุการทำนายลงในชั้นเรียน ในขณะที่การทำนายแบบอ่อนจะส่งออกค่า ความน่าจะเป็น ของอินสแตนซ์ที่เป็นของคลาส
มีข้อมูลเพิ่มเติมเกี่ยวกับวิธีการสร้างผลลัพธ์ที่คาดการณ์ไว้ มันไม่ใช่ 0
แต่มีโอกาส 55% ของคลาส 0
และมีโอกาส 45% ของคลาส 1
. นี้แสดงให้เห็นว่าสามตัวแรก X_test
จุดข้อมูลที่เกี่ยวข้องกับคลาส 0
มีความชัดเจนมากเฉพาะเกี่ยวกับจุดข้อมูลที่สาม โดยมีความน่าจะเป็น 86% – และไม่มากนักสำหรับจุดข้อมูลสองจุดแรก
เมื่อสื่อสารสิ่งที่ค้นพบโดยใช้เมธอด ML โดยทั่วไปแล้ว เป็นการดีที่สุดที่จะส่งคืนคลาสที่อ่อนนุ่ม และความน่าจะเป็นที่เกี่ยวข้องเป็น "ความมั่นใจ" ของการจำแนกประเภทนั้นๆ
เราจะพูดถึงวิธีการคำนวณมากขึ้นเมื่อเราเจาะลึกลงไปในตัวแบบ ในตอนนี้ เราสามารถดำเนินการขั้นตอนต่อไปได้
การประเมินแบบจำลองด้วยรายงานการจำแนกประเภท
ขั้นตอนที่สามคือการดูว่าโมเดลทำงานอย่างไรกับข้อมูลทดสอบ เราสามารถนำเข้า Scikit-Learn classification_report()
และผ่านของเรา y_test
และ y_pred
เป็นข้อโต้แย้ง หลังจากนั้น เราสามารถพิมพ์คำตอบออกมาได้
รายงานการจัดประเภทประกอบด้วยเมตริกการจัดประเภทที่ใช้มากที่สุด เช่น ความแม่นยำ, จำ, คะแนน f1และ ความถูกต้อง.
- ความแม่นยำ: เพื่อทำความเข้าใจว่าค่าการทำนายที่ถูกต้องใดที่ตัวแยกประเภทของเราพิจารณาว่าถูกต้อง ความแม่นยำจะแบ่งค่าบวกที่แท้จริงเหล่านั้นด้วยค่าใดก็ตามที่คาดการณ์ว่าเป็นค่าบวก:
$$
ความแม่นยำ = frac{text{true positive}}{text{true positive} + text{false positive}}
$$
- จำ: เพื่อทำความเข้าใจว่าตัวแยกประเภทของเราระบุถึงผลบวกที่แท้จริงจำนวนเท่าใด การเรียกคืนคำนวณโดยการหารผลบวกที่แท้จริงด้วยสิ่งที่ควรคาดการณ์ว่าเป็นบวก:
$$
เรียกคืน = frac{text{true positive}}{text{true positive} + text{false negative}}
$$
- คะแนน F1: คือความสมดุลหรือ ฮาร์โมนิก ของความแม่นยำและการเรียกคืน ค่าต่ำสุดคือ 0 และค่าสูงสุดคือ 1 เมื่อ
f1-score
เท่ากับ 1 หมายความว่าทุกคลาสได้รับการทำนายอย่างถูกต้อง – นี่เป็นคะแนนที่ยากมากที่จะได้รับจากข้อมูลจริง:
$$
ข้อความ{f1-score} = 2* frac{text{precision} * text{recall}}{text{precision} + text{recall}}
$$
- ความถูกต้อง: อธิบายจำนวนการคาดคะเนของเราที่ลักษณนามของเราได้ถูกต้อง ค่าความแม่นยำต่ำสุดคือ 0 และค่าสูงสุดคือ 1 ค่านั้นมักจะคูณด้วย 100 เพื่อให้ได้เปอร์เซ็นต์:
$$
ความแม่นยำ = frac{ข้อความ{จำนวนการคาดการณ์ที่ถูกต้อง}}{ข้อความ{จำนวนการคาดการณ์ทั้งหมด}}
$$
หมายเหตุ เป็นเรื่องยากมากที่จะได้รับความถูกต้อง 100% จากข้อมูลจริงใดๆ หากเกิดเหตุการณ์ดังกล่าว โปรดทราบว่าอาจมีการรั่วไหลหรือสิ่งผิดปกติเกิดขึ้น – ไม่มีความเห็นพ้องต้องกันเกี่ยวกับค่าความแม่นยำในอุดมคติและขึ้นอยู่กับบริบทด้วย ค่า 70% ซึ่งหมายความว่าตัวแยกประเภทจะทำผิดพลาดใน 30% ของข้อมูลหรือสูงกว่า 70% มักจะเพียงพอสำหรับรุ่นส่วนใหญ่
from sklearn.metrics import classification_report
cr = classification_report(y_test, y_pred)
print(cr)
จากนั้นเราจะดูผลลัพธ์ของรายงานการจัดหมวดหมู่:
precision recall f1-score support
0 0.83 0.91 0.87 316
1 0.90 0.81 0.85 309
accuracy 0.86 625
macro avg 0.86 0.86 0.86 625
weighted avg 0.86 0.86 0.86 625
นี่คือผลลัพธ์ของเรา สังเกตว่า precision
, recall
, f1-score
และ accuracy
เมตริกทั้งหมดนั้นสูงมาก ซึ่งสูงกว่า 80% ซึ่งเป็นอุดมคติ แต่ผลลัพธ์เหล่านั้นอาจได้รับอิทธิพลจากความสัมพันธ์ที่สูง และจะไม่คงอยู่ในระยะยาว
ความแม่นยำของโมเดลคือ 86% ซึ่งหมายความว่ามีการจำแนกประเภทผิด 14% ของเวลาทั้งหมด เรามีข้อมูลโดยรวมนั้น แต่น่าสนใจที่จะทราบว่าข้อผิดพลาด 14% เกิดขึ้นเกี่ยวกับการจำแนกประเภทของคลาสหรือไม่ 0
หรือคลาส 1
. เพื่อระบุว่าคลาสใดถูกระบุอย่างผิด ๆ และความถี่ใด - เราสามารถคำนวณและวางแผน a เมทริกซ์ความสับสน จากการคาดการณ์ของแบบจำลองของเรา
การประเมินแบบจำลองด้วยเมทริกซ์ความสับสน
ลองคำนวณแล้วพลอตเมทริกซ์ความสับสนกัน หลังจากทำแล้วเราสามารถเข้าใจแต่ละส่วนได้ ในการพล็อตเมทริกซ์ความสับสน เราจะใช้ Scikit-Learn confusion_matrix()
ซึ่งเราจะนำเข้าจาก metrics
โมดูล.
เมทริกซ์ความสับสนนั้นง่ายต่อการมองเห็นโดยใช้ Seaborn heatmap()
. ดังนั้น หลังจากที่สร้างมันขึ้นมา เราจะส่งเมทริกซ์ความสับสนเป็นอาร์กิวเมนต์สำหรับแผนที่ความหนาแน่น:
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d')
- เมทริกซ์ความสับสน: เมทริกซ์แสดงจำนวนตัวอย่างที่โมเดลถูกหรือผิดสำหรับแต่ละคลาส ค่าที่ถูกทำนายอย่างถูกต้องเรียกว่า แง่บวกที่แท้จริงและที่ทำนายว่าเป็นผลบวกแต่ไม่เป็นบวกเรียกว่า บวกเท็จ. ศัพท์เดียวกันของ เชิงลบที่แท้จริง และ เชิงลบเท็จ ใช้สำหรับค่าลบ
จากการดูพล็อตเมทริกซ์ความสับสน เราจะเห็นได้ว่าเรามี 287
ค่าที่ 0
และทำนายว่า 0
- หรือ แง่บวกที่แท้จริง สำหรับชั้นเรียน 0
(เมล็ด cerçevelik). เราก็มี 250
แง่บวกที่แท้จริงสำหรับชั้นเรียน 1
(เมล็ดเออร์กัป ซิฟริซี). ค่าบวกที่แท้จริงมักจะอยู่ในเส้นทแยงมุมของเมทริกซ์ซึ่งเริ่มจากด้านซ้ายบนไปด้านขวาล่าง
เรายังมี 29
ค่าที่ควรจะเป็น 0
แต่ทำนายว่า 1
(บวกเท็จ) and 59
ค่าที่ 1
และทำนายว่า 0
(เชิงลบเท็จ). ด้วยตัวเลขเหล่านี้ เราสามารถเข้าใจได้ว่าข้อผิดพลาดที่โมเดลสร้างมากที่สุดคือการทำนายผลลบลวง ดังนั้น ส่วนใหญ่แล้วจะสามารถจัดประเภทเมล็ดพันธุ์ เออร์กัป ซิฟริซี เป็นเมล็ดพันธุ์ เซอร์เซเวลิกได้
ข้อผิดพลาดประเภทนี้ยังอธิบายได้จากการเรียกคืนคลาส 81% 1
. สังเกตว่ามีการเชื่อมต่อเมตริก และความแตกต่างในการเรียกคืนมาจากการมีกลุ่มตัวอย่างน้อยกว่า 100 ตัวอย่างในชั้นเรียน Ürgüp Sivrisi นี่เป็นหนึ่งในความหมายของการมีตัวอย่างเพียงไม่กี่ตัวที่น้อยกว่าคลาสอื่น เพื่อปรับปรุงการเรียกคืนเพิ่มเติม คุณสามารถทดลองกับตุ้มน้ำหนักของคลาสหรือใช้ตัวอย่าง Ürgüp Sivrisi เพิ่มเติม
จนถึงตอนนี้ เราได้ดำเนินการตามขั้นตอนดั้งเดิมของวิทยาศาสตร์ข้อมูลแล้ว และใช้แบบจำลองการถดถอยโลจิสติกเป็นกล่องดำ
หมายเหตุ หากคุณต้องการไปต่อให้ใช้ การตรวจสอบความถูกต้อง (CV) และการค้นหากริด เพื่อค้นหาตามลำดับแบบจำลองที่สรุปเกี่ยวกับข้อมูลมากที่สุดและพารามิเตอร์แบบจำลองที่ดีที่สุดที่เลือกก่อนการฝึกอบรมหรือ ไฮเปอร์พารามิเตอร์.
ตามหลักการแล้ว ด้วย CV และ Grid Search คุณยังสามารถใช้วิธีเชื่อมต่อกันเพื่อทำขั้นตอนก่อนการประมวลผลข้อมูล การแยกข้อมูล การสร้างแบบจำลอง และการประเมิน ซึ่งทำได้ง่ายด้วย Scikit-Learn ท่อ.
ตอนนี้ได้เวลาเปิดกล่องดำแล้วมองเข้าไปข้างใน เพื่อทำความเข้าใจให้ลึกซึ้งยิ่งขึ้นว่าการถดถอยโลจิสติกทำงานอย่างไร
เจาะลึกว่า Logistic Regression ทำงานอย่างไร
พื้นที่ ถดถอย ไม่มีคำเกิดขึ้นโดยบังเอิญ เพื่อให้เข้าใจว่าการถดถอยโลจิสติกทำอะไร เราสามารถจำได้ว่าการถดถอยเชิงเส้นพี่น้องของมันทำอะไรกับข้อมูล สูตรการถดถอยเชิงเส้นมีดังต่อไปนี้:
$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + จุด + b_n * x_n
$$
ซึ่ง b0 เป็นการสกัดกั้นการถดถอย b1 สัมประสิทธิ์และ x1 ข้อมูล.
สมการนั้นทำให้เกิดเส้นตรงที่ใช้ทำนายค่าใหม่ เมื่อนึกถึงบทนำ ความแตกต่างในตอนนี้คือเราจะไม่ทำนายค่าใหม่ แต่เป็นคลาส เลยต้องเปลี่ยนเส้นตรง ด้วยการถดถอยโลจิสติก เราแนะนำความไม่เป็นเชิงเส้น และตอนนี้การทำนายถูกสร้างขึ้นโดยใช้เส้นโค้งแทนเส้น:
สังเกตว่าในขณะที่เส้นการถดถอยเชิงเส้นยังคงดำเนินต่อไปและประกอบด้วยค่าอนันต์ต่อเนื่อง เส้นโค้งการถดถอยโลจิสติกสามารถแบ่งได้ตรงกลางและมีค่าสุดขั้วในค่า 0 และ 1 รูปร่าง "S" นั้นเป็นสาเหตุที่จำแนกข้อมูล – จุดที่ใกล้หรือตกอยู่ที่ระดับสูงสุดเป็นของชั้น 1 ในขณะที่จุดที่อยู่ในจตุภาคล่างหรือใกล้กับ 0 เป็นของชั้น 0 ตรงกลางของ “S” อยู่ตรงกลางระหว่าง 0 ถึง 1, 0.5 – เป็นเกณฑ์สำหรับจุดถดถอยโลจิสติก
เราเข้าใจถึงความแตกต่างทางสายตาระหว่างการถดถอยโลจิสติกและการถดถอยเชิงเส้นแล้ว แต่สูตรล่ะ? สูตรสำหรับการถดถอยโลจิสติกมีดังต่อไปนี้:
$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + จุด + b_n * x_n
$$
นอกจากนี้ยังสามารถเขียนเป็น:
$$
y_{ปัญหา} = frac{1}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
หรือแม้กระทั่งเขียนเป็น:
$$
y_{ปัญหา} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
ในสมการข้างต้น เรามีความน่าจะเป็นของอินพุต แทนที่จะเป็นค่าของมัน มันมี 1 เป็นตัวเศษ จึงสามารถให้ผลลัพธ์เป็นค่าระหว่าง 0 ถึง 1 และ 1 บวกกับค่าในตัวหาร ดังนั้นค่าของมันคือ 1 และบางอย่าง ซึ่งหมายความว่าผลลัพธ์เศษส่วนทั้งหมดต้องไม่เกิน 1 .
และค่าที่อยู่ในตัวส่วนคืออะไร? มันคือ eฐานของลอการิทึมธรรมชาติ (ประมาณ 2.718282) ยกกำลังของการถดถอยเชิงเส้น:
$$
อี^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
อีกวิธีในการเขียนก็คือ
$$
ln ซ้าย ( frac{p}{1-p} right) = {(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
ในสมการสุดท้ายนั้น ln คือลอการิทึมธรรมชาติ (ฐาน e) และ p คือความน่าจะเป็น ดังนั้นลอการิทึมของความน่าจะเป็นของผลลัพธ์จึงเท่ากับผลการถดถอยเชิงเส้น
กล่าวอีกนัยหนึ่ง ด้วยผลการถดถอยเชิงเส้นและลอการิทึมธรรมชาติ เราสามารถบรรลุความน่าจะเป็นของอินพุตที่เกี่ยวข้องกับคลาสที่ออกแบบไว้หรือไม่
กระบวนการได้มาซึ่งการถดถอยโลจิสติกทั้งหมดมีดังต่อไปนี้:
$$
p{X} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
$$
p(1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}) = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
$$
พี + p*e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
p
=
e
(
b
0
+
b
1
* * * *
x
1
+
b
2
* * * *
x
2
+
b
3
* * * *
x
3
+
...
+
b
n
* * * *
x
n
)
-
p
* * * *
e
(
b
0
+
b
1
* * * *
x
1
+
b
2
* * * *
x
2
+
b
3
* * * *
x
3
+
...
+
b
n
* * * *
x
n
)
$$
frac{p}{1-p} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
$$
ซ้าย( frac{1-p} ขวา) = (b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)
$$
ซึ่งหมายความว่าแบบจำลองการถดถอยโลจิสติกยังมีสัมประสิทธิ์และค่าการสกัดกั้นด้วย เพราะมันใช้การถดถอยเชิงเส้นและเพิ่มองค์ประกอบที่ไม่เชิงเส้นเข้าไปด้วยลอการิทึมธรรมชาติ (e
).
เราสามารถเห็นค่าสัมประสิทธิ์และการสกัดกั้นของแบบจำลองของเราได้เช่นเดียวกับการถดถอยเชิงเส้นโดยใช้ coef_
และ intercept_
คุณสมบัติ:
logreg.coef_
ซึ่งแสดงค่าสัมประสิทธิ์ของแต่ละคุณสมบัติทั้ง 12 ประการ:
array([[ 1.43726172, -1.03136968, 0.24099522, -0.61180768, 1.36538261,
-1.45321951, -1.22826034, 0.98766966, 0.0438686 , -0.78687889,
1.9601197 , -1.77226097]])
logreg.intercept_
ส่งผลให้:
array([0.08735782])
ด้วยค่าสัมประสิทธิ์และค่าการสกัดกั้น เราสามารถคำนวณความน่าจะเป็นที่คาดการณ์ไว้ของข้อมูลของเรา มาเป็นคนแรกเลย X_test
ค่าอีกครั้ง เป็นตัวอย่าง:
X_test[:1]
ส่งคืนแถวแรกของ X_test
เป็นอาร์เรย์ NumPy:
array([[-1.09830823, -0.93651823, -0.60794138, -1.13255059, -1.0827684 ,
-1.12235877, 0.45891056, -1.07825898, 0.56284738, -0.17604099,
0.23661678, -0.36013424]])
ตามสมการเริ่มต้น:
$$
p{X} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
ใน python เรามี:
import math
lin_reg = logreg.intercept_[0] +
((logreg.coef_[0][0]* X_test[:1][0][0])+
(logreg.coef_[0][1]* X_test[:1][0][1])+
(logreg.coef_[0][2]* X_test[:1][0][2])+
(logreg.coef_[0][3]* X_test[:1][0][3])+
(logreg.coef_[0][4]* X_test[:1][0][4])+
(logreg.coef_[0][5]* X_test[:1][0][5])+
(logreg.coef_[0][6]* X_test[:1][0][6])+
(logreg.coef_[0][7]* X_test[:1][0][7])+
(logreg.coef_[0][8]* X_test[:1][0][8])+
(logreg.coef_[0][9]* X_test[:1][0][9])+
(logreg.coef_[0][10]* X_test[:1][0][10])+
(logreg.coef_[0][11]* X_test[:1][0][11]))
px = math.exp(lin_reg)/(1 +(math.exp(lin_reg)))
px
ผลลัพธ์นี้ใน:
0.45273372469369133
หากเรามองดูอีกครั้งที่ predict_proba
ผลลัพธ์ของครั้งแรก X_test
ไลน์ เรามี:
logreg.predict_proba(X_test[:1])
ซึ่งหมายความว่าสมการถดถอยโลจิสติกดั้งเดิมทำให้เรามีความน่าจะเป็นของอินพุตเกี่ยวกับคลาส 1
เพื่อหาความน่าจะเป็นสำหรับคลาส 0
เราสามารถ:
1 - px
สังเกตว่าทั้งสอง px
และ 1-px
เหมือนกันกับ predict_proba
ผลลัพธ์. นี่คือวิธีคำนวณการถดถอยโลจิสติกและทำไม ถดถอย เป็นส่วนหนึ่งของชื่อ แต่สิ่งที่เกี่ยวกับคำว่า โลจิสติก?
ระยะ โลจิสติก มาจาก เข้าสู่ระบบซึ่งเป็นฟังก์ชันที่เราได้เห็นแล้ว:
$$
ซ้าย( frac{1-p} ขวา)
$$
เราเพิ่งคำนวณมันด้วย px
และ 1-px
. นี่คือ logit เรียกอีกอย่างว่า บันทึกอัตราต่อรอง เพราะมันเท่ากับลอการิทึมของอัตราต่อรองโดยที่ p
คือความน่าจะเป็น
สรุป
ในคู่มือนี้ เราได้ศึกษาอัลกอริธึมการจำแนกประเภทแมชชีนเลิร์นนิ่งพื้นฐานที่สุดตัวหนึ่ง นั่นคือ การถดถอยโลจิสติก.
ในขั้นต้น เราใช้การถดถอยโลจิสติกเป็นกล่องดำที่มีไลบรารีการเรียนรู้ของเครื่อง Scikit-Learn และต่อมาเราเข้าใจทีละขั้นตอนเพื่อให้ชัดเจนว่าเหตุใดและที่มาของเงื่อนไขการถดถอยและลอจิสติกส์
เรายังได้สำรวจและศึกษาข้อมูล ความเข้าใจว่าเป็นส่วนที่สำคัญที่สุดอย่างหนึ่งของการวิเคราะห์ข้อมูลทางวิทยาศาสตร์
จากนี้ไปฉันขอแนะนำให้คุณเล่นด้วย การถดถอยโลจิสติกแบบหลายคลาส, การถดถอยโลจิสติกสำหรับมากกว่าสองคลาส – คุณสามารถใช้อัลกอริธึมการถดถอยโลจิสติกเดียวกันสำหรับชุดข้อมูลอื่นที่มีหลายคลาส และตีความผลลัพธ์
หมายเหตุ มีชุดข้อมูลที่ดี โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม เพื่อให้คุณเล่นด้วย
ฉันอยากจะแนะนำให้คุณศึกษา L1 และ L2 . ด้วย การทำให้เป็นมาตรฐานซึ่งเป็นวิธีหนึ่งในการ "ลงโทษ" ข้อมูลที่สูงกว่าเพื่อให้ข้อมูลนั้นเข้าใกล้สภาวะปกติมากขึ้น โดยยึดเอาความซับซ้อนของแบบจำลองไว้ ดังนั้นอัลกอริทึมจะได้ผลลัพธ์ที่ดีขึ้น การใช้งาน Scikit-Learn ที่เราใช้นั้นมีการทำให้เป็นมาตรฐาน L2 อยู่แล้วโดยค่าเริ่มต้น สิ่งที่ต้องดูอีกอย่างคือความแตกต่าง นักแก้ปัญหาเช่น lbgs
ซึ่งปรับประสิทธิภาพของอัลกอริธึมการถดถอยโลจิสติกให้เหมาะสม
สิ่งสำคัญคือต้องดูที่ ทางสถิติ แนวทางการถดถอยโลจิสติก มันมี สมมติฐาน เกี่ยวกับพฤติกรรมของข้อมูล และเกี่ยวกับสถิติอื่นๆ ที่ต้องมีไว้เพื่อรับประกันผลลัพธ์ที่น่าพอใจ เช่น
- การสังเกตเป็นอิสระ;
- ไม่มีความหลากหลายร่วมกันระหว่างตัวแปรอธิบาย
- ไม่มีค่าผิดปกติที่รุนแรง
- มีความสัมพันธ์เชิงเส้นตรงระหว่างตัวแปรอธิบายและบันทึกของตัวแปรตอบสนอง
- ขนาดตัวอย่างมีขนาดใหญ่เพียงพอ
สังเกตว่าสมมติฐานเหล่านั้นครอบคลุมไปแล้วกี่ข้อในการวิเคราะห์และจัดการข้อมูลของเรา
ฉันหวังว่าคุณจะสำรวจต่อไปว่าการถดถอยโลจิสติกมีให้ในแนวทางต่างๆ อย่างไร!