# สร้างโมเดลการถดถอย (regression) โดยใช้ Scikit-learn: การถดถอยสี่วิธี ## หมายเหตุสำหรับผู้เริ่มต้น การถดถอยเชิงเส้นใช้เมื่อเราต้องการทำนาย **ค่าตัวเลข** (เช่น ราคาบ้าน อุณหภูมิ หรือยอดขาย) วิธีทำงานโดยการหาค่ารูปเส้นตรงที่เป็นตัวแทนที่ดีที่สุดสำหรับความสัมพันธ์ระหว่างคุณลักษณะอินพุตและผลลัพธ์ ในบทเรียนนี้ เราจะเน้นทำความเข้าใจแนวคิดก่อนที่จะสำรวจเทคนิคการถดถอยที่ก้าวหน้าขึ้น ![Linear vs polynomial regression infographic](../../../../translated_images/th/linear-polynomial.5523c7cb6576ccab.webp) > อินโฟกราฟิกโดย [Dasani Madipalli](https://twitter.com/dasani_decoded) ## [แบบทดสอบก่อนเรียน](https://ff-quizzes.netlify.app/en/ml/) > ### [บทเรียนนี้มีเวอร์ชันภาษา R!](../../../../2-Regression/3-Linear/solution/R/lesson_3.html) ### บทนำ จนถึงตอนนี้คุณได้สำรวจความหมายของการถดถอยด้วยชุดข้อมูลตัวอย่างจากชุดข้อมูลราคาฟักทองที่เราจะใช้ตลอดบทเรียนนี้แล้ว คุณยังได้แสดงภาพโดยใช้ Matplotlib ตอนนี้คุณพร้อมที่จะเจาะลึกเรื่องการถดถอยสำหรับ ML แล้ว ในขณะที่การแสดงภาพช่วยให้เข้าใจข้อมูลได้ แต่พลังที่แท้จริงของ Machine Learning มาจาก _การฝึกโมเดล_ โมเดลจะถูกฝึกด้วยข้อมูลย้อนหลังเพื่อจับความสัมพันธ์ข้อมูลโดยอัตโนมัติ และช่วยให้คุณทำนายผลลัพธ์สำหรับข้อมูลใหม่ที่โมเดลไม่เคยเห็นมาก่อน ในบทเรียนนี้ คุณจะได้เรียนรู้เพิ่มเติมเกี่ยวกับสองประเภทของการถดถอย: _การถดถอยเชิงเส้นพื้นฐาน_ และ _การถดถอยพหุนาม_ พร้อมกับคณิตศาสตร์พื้นฐานที่อยู่เบื้องหลังเทคนิคเหล่านี้ โมเดลเหล่านี้จะช่วยให้เราทำนายราคาฟักทองขึ้นอยู่กับข้อมูลอินพุตที่แตกต่างกัน [![ML for beginners - Understanding Linear Regression](https://img.youtube.com/vi/CRxFT8oTDMg/0.jpg)](https://youtu.be/CRxFT8oTDMg "ML for beginners - Understanding Linear Regression") > 🎥 คลิกที่ภาพด้านบนเพื่อชมวิดีโอสั้นๆ เกี่ยวกับภาพรวมของการถดถอยเชิงเส้น > ตลอดหลักสูตรนี้ เราสมมุติว่าความรู้ด้านคณิตศาสตร์มีเพียงเล็กน้อย และพยายามทำให้ง่ายสำหรับนักเรียนที่มาจากสาขาอื่น จึงมีบันทึก, 🧮 การเรียกดู, แผนภาพ และเครื่องมือช่วยเรียนอื่นๆ เพื่อช่วยในการเข้าใจ ### ความรู้เบื้องต้นที่ควรมี คุณควรคุ้นเคยกับโครงสร้างชุดข้อมูลฟักทองที่เรากำลังวิเคราะห์อยู่แล้ว คุณสามารถพบชุดข้อมูลที่โหลดและทำความสะอาดไว้ล่วงหน้าในไฟล์ _notebook.ipynb_ ของบทเรียนนี้ ในไฟล์นี้ราคาฟักทองจะแสดงเป็นราคาต่อบัชเชิลในกรอบข้อมูลชุดใหม่ ให้แน่ใจว่าคุณสามารถรันโน้ตบุ๊กเหล่านี้บนเคอร์เนลใน Visual Studio Code ### การเตรียมตัว เพื่อเตือนความจำ คุณกำลังโหลดข้อมูลนี้เพื่อที่จะตั้งคำถามกับมัน - เวลาใดเหมาะสมที่สุดในการซื้อฟักทอง? - ราคาที่คาดหวังของฟักทองขนาดจิ๋วเป็นเท่าไร? - ควรซื้อแบบตะกร้าครึ่งบัชเชิล หรือแบบกล่อง 1 1/9 บัชเชิลดี? ลองสำรวจข้อมูลนี้ต่อไป ในบทเรียนก่อนหน้า คุณได้สร้าง Pandas DataFrame และเติมข้อมูลบางส่วนจากชุดข้อมูลเดิมโดยการทำให้ราคาเป็นมาตรฐานต่อบัชเชิล แต่ด้วยวิธีนี้คุณได้แค่ประมาณ 400 จุดข้อมูลและเฉพาะในเดือนฤดูใบไม้ร่วงเท่านั้น ลองดูข้อมูลที่เรารโหลดไว้ล่วงหน้าในโน้ตบุ๊กที่แนบมากับบทเรียนนี้ ข้อมูลถูกโหลดไว้แล้วและมีการสร้างกราฟกระจายเบื้องต้นแสดงข้อมูลเดือน อาจจะสามารถล้างข้อมูลให้ดีขึ้นเพื่อให้เข้าใจลักษณะข้อมูลได้มากขึ้น ## เส้นการถดถอยเชิงเส้น ตามที่คุณได้เรียนรู้ในบทที่ 1 เป้าหมายของการฝึกการถดถอยเชิงเส้นคือการวางเส้นตรงที่: - **แสดงความสัมพันธ์ระหว่างตัวแปร** แสดงความสัมพันธ์ระหว่างตัวแปร - **ทำนายผลลัพธ์** ทำนายค่าที่ถูกต้องว่าจุดข้อมูลใหม่จะอยู่ที่ใดในความสัมพันธ์กับเส้นนั้น โดยปกติสำหรับ **Least-Squares Regression** จะใช้การวาดเส้นแบบนี้ คำว่า "Least-Squares" หมายถึงกระบวนการของการหาค่าความผิดพลาดรวมทั้งหมดให้น้อยที่สุดในโมเดลของเรา สำหรับทุกจุดข้อมูล เราจะวัดระยะทางในแนวดิ่ง (ซึ่งเรียกว่า residual) ระหว่างจุดจริงกับเส้นถดถอยของเรา เราจะกำหนดค่ายกกำลังสองของระยะทางเหตุผลสำคัญสองประการคือ: 1. **ขนาดไม่สนทิศทาง:** เราต้องการให้ความผิดพลาด -5 มีค่าเหมือนกับความผิดพลาด +5 การยกกำลังสองทำให้ค่าทั้งหมดเป็นบวก 2. **ลงโทษค่าเบี่ยงเบนสูง:** การยกกำลังสองทำให้ค่าความผิดพลาดมากถูกเน้นหนักขึ้น บังคับให้เส้นต้องอยู่ใกล้กับจุดที่ห่างไกลมากกว่า จากนั้นเราจะนำค่ากำลังสองทั้งหมดมารวมกัน เป้าหมายของเราคือหาค่าเส้นที่ผลบวกนี้มีค่าน้อยที่สุด (ค่าที่เล็กที่สุด) จึงเรียกว่า "Least-Squares" > **🧮 แสดงคณิตศาสตร์ให้ดู** > > เส้นนี้เรียกว่า _เส้นที่เหมาะสมที่สุด_ สามารถแสดงได้ด้วย [สูตรสมการ](https://en.wikipedia.org/wiki/Simple_linear_regression): > > ``` > Y = a + bX > ``` > > `X` คือ 'ตัวแปรอธิบาย' และ `Y` คือ 'ตัวแปรตาม' ความชันของเส้นคือ `b` และ `a` คือจุดตัดแกน y ซึ่งหมายถึงค่าของ `Y` เมื่อ `X = 0` > >![calculate the slope](../../../../translated_images/th/slope.f3c9d5910ddbfcf9.webp) > > ขั้นแรกคำนวณความชัน `b` อินโฟกราฟิกโดย [Jen Looper](https://twitter.com/jenlooper) > > กล่าวอีกนัยหนึ่ง และอ้างอิงคำถามดั้งเดิมของข้อมูลฟักทอง: "ทำนายราคาฟักทองต่อบัชเชิลตามเดือน" `X` จะหมายถึงราคา และ `Y` จะหมายถึงเดือนของการขาย > >![complete the equation](../../../../translated_images/th/calculation.a209813050a1ddb1.webp) > > คำนวณค่า Y หากคุณจ่ายเงินประมาณ 4 ดอลลาร์ ต้องเป็นเดือนเมษายนแน่ๆ อินโฟกราฟิกโดย [Jen Looper](https://twitter.com/jenlooper) > > คณิตศาสตร์ที่คำนวณเส้นต้องแสดงความชันของเส้นซึ่งขึ้นอยู่กับจุดตัดแกน y หรือที่ที่ `Y` อยู่เมื่อ `X = 0` > > คุณสามารถดูวิธีการคำนวณค่านี้ได้จากเว็บไซต์ [Math is Fun](https://www.mathsisfun.com/data/least-squares-regression.html) และสามารถไปที่ [เครื่องมือคำนวณ Least-squares](https://www.mathsisfun.com/data/least-squares-calculator.html) เพื่อดูผลกระทบของค่าตัวเลขต่อเส้นได้ ## ความสัมพันธ์ (Correlation) อีกคำหนึ่งที่ต้องเข้าใจคือ **สัมประสิทธิ์สหสัมพันธ์ (Correlation Coefficient)** ระหว่างตัวแปร X และ Y ที่กำหนด ด้วยการใช้กราฟกระจาย คุณจะมองเห็นค่าสัมประสิทธิ์นี้อย่างรวดเร็ว กราฟที่มีจุดกระจายในเส้นตรงเรียงตัวกันอย่างดีจะมีค่าสหสัมพันธ์สูง แต่กราฟที่จุดกระจายกระจัดกระจายไม่เป็นระเบียบระหว่าง X และ Y จะมีค่าสหสัมพันธ์ต่ำ โมเดลการถดถอยเชิงเส้นที่ดีจะมีค่าสัมประสิทธิ์สหสัมพันธ์สูง (ใกล้ 1 มากกว่า 0) โดยใช้วิธี Least-Squares Regression กับเส้นถดถอย ✅ รันโน้ตบุ๊กที่แนบมากับบทเรียนนี้และดูกราฟกระจายระหว่างเดือนกับราคา ข้อมูลที่สัมพันธ์ระหว่างเดือนและราคาฟักทองมีค่าสหสัมพันธ์สูงหรือต่ำตามการตีความด้วยตาเปล่าของคุณจากกราฟกระจายหรือไม่? ถ้าใช้ค่าที่ละเอียดกว่านี้แทน `Month` เช่น *วันภายในปี* (จำนวนวันนับตั้งแต่ปีเริ่มต้น) จะเปลี่ยนแปลงอย่างไร? ในโค้ดด้านล่างนี้ เราจะสมมุติว่าข้อมูลถูกทำความสะอาดแล้ว และได้ DataFrame ชื่อ `new_pumpkins` ดังนี้: ID | Month | DayOfYear | Variety | City | Package | Low Price | High Price | Price ---|-------|-----------|---------|------|---------|-----------|------------|------- 70 | 9 | 267 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 15.0 | 15.0 | 13.636364 71 | 9 | 267 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 18.0 | 18.0 | 16.363636 72 | 10 | 274 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 18.0 | 18.0 | 16.363636 73 | 10 | 274 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 17.0 | 17.0 | 15.454545 74 | 10 | 281 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 15.0 | 15.0 | 13.636364 > โค้ดในการทำความสะอาดข้อมูลหาได้ใน [`notebook.ipynb`](notebook.ipynb) เราทำการทำความสะอาดแบบเดียวกับบทก่อนหน้าและคำนวณคอลัมน์ `DayOfYear` ด้วยนิพจน์ต่อไปนี้: ```python day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days) ``` ตอนนี้คุณเข้าใจคณิตศาสตร์เบื้องหลังการถดถอยเชิงเส้นแล้ว มาเราสร้างโมเดลการถดถอยเพื่อดูว่าเราสามารถทำนายได้หรือไม่ว่าชุดฟักทองใดจะมีราคาที่ดีที่สุด ใครก็ตามที่ซื้อฟักทองสำหรับเทศกาลฟักทองอาจต้องการข้อมูลนี้เพื่อการตัดสินใจซื้อชุดฟักทองให้เหมาะสม ## การค้นหาความสัมพันธ์ [![ML for beginners - Looking for Correlation: The Key to Linear Regression](https://img.youtube.com/vi/uoRq-lW2eQo/0.jpg)](https://youtu.be/uoRq-lW2eQo "ML for beginners - Looking for Correlation: The Key to Linear Regression") > 🎥 คลิกที่ภาพด้านบนเพื่อชมวิดีโอสั้นๆ เกี่ยวกับภาพรวมของความสัมพันธ์ จากบทเรียนก่อนหน้า คุณอาจจะเห็นว่าราคากลางของแต่ละเดือนมีลักษณะดังนี้: Average price by month ซึ่งแสดงว่าต้องมีความสัมพันธ์บางอย่าง และเราสามารถลองฝึกโมเดลการถดถอยเชิงเส้นเพื่อทำนายความสัมพันธ์ระหว่าง `Month` กับ `Price` หรือระหว่าง `DayOfYear` กับ `Price` ได้ นี่คือกราฟกระจายที่แสดงความสัมพันธ์หลัง: Scatter plot of Price vs. Day of Year ลองดูความสัมพันธ์โดยใช้ฟังก์ชัน `corr`: ```python print(new_pumpkins['Month'].corr(new_pumpkins['Price'])) print(new_pumpkins['DayOfYear'].corr(new_pumpkins['Price'])) ``` ดูเหมือนว่าค่าสหสัมพันธ์จะค่อนข้างต่ำ คือ -0.15 สำหรับ `Month` และ -0.17 สำหรับ `DayOfMonth` แต่น่าจะมีความสัมพันธ์อื่นที่น่าสนใจ ดูเหมือนว่ามีกลุ่มราคาที่แตกต่างกันตามชนิดฟักทอง เพื่อยืนยันสมมติฐานนี้ ลองพล็อตค่าฟักทองแต่ละประเภทด้วยสีที่แตกต่างกัน โดยส่งพารามิเตอร์ `ax` ไปยังฟังก์ชัน `scatter` เพื่อพล็อตจุดทั้งหมดบนกราฟเดียวกัน: ```python ax=None colors = ['red','blue','green','yellow'] for i,var in enumerate(new_pumpkins['Variety'].unique()): df = new_pumpkins[new_pumpkins['Variety']==var] ax = df.plot.scatter('DayOfYear','Price',ax=ax,c=colors[i],label=var) ``` Scatter plot of Price vs. Day of Year การสืบสวนของเราชี้ว่าชนิดฟักทองมีผลต่อราคามากกว่าวันขายจริง ซึ่งจะเห็นได้ชัดในกราฟแท่ง: ```python new_pumpkins.groupby('Variety')['Price'].mean().plot(kind='bar') ``` Bar graph of price vs variety ขอให้เรามุ่งความสนใจชั่วคราวไปที่ฟักทองชนิดเดียว คือ 'pie type' และดูผลกระทบของวันที่กับราคาฟักทอง: ```python pie_pumpkins = new_pumpkins[new_pumpkins['Variety']=='PIE TYPE'] pie_pumpkins.plot.scatter('DayOfYear','Price') ``` Scatter plot of Price vs. Day of Year ถ้าเราคำนวณค่าสหสัมพันธ์ระหว่าง `Price` และ `DayOfYear` ด้วยฟังก์ชัน `corr` จะได้ค่าประมาณ `-0.27` ซึ่งหมายความว่าการฝึกโมเดลทำนายเป็นเรื่องสมเหตุสมผล > ก่อนฝึกโมเดลการถดถอยเชิงเส้น สิ่งสำคัญคือให้แน่ใจว่าข้อมูลของเราสะอาด เพราะการถดถอยเชิงเส้นทำงานไม่ดีเมื่อมีค่าว่าง จึงควรลบเซลล์ว่างทั้งหมด: ```python pie_pumpkins.dropna(inplace=True) pie_pumpkins.info() ``` อีกวิธีหนึ่งคือเติมค่าในช่องว่างเหล่านั้นด้วยค่าค่าเฉลี่ยของคอลัมน์นั้น ## การถดถอยเชิงเส้นอย่างง่าย [![ML for beginners - Linear and Polynomial Regression using Scikit-learn](https://img.youtube.com/vi/e4c_UP2fSjg/0.jpg)](https://youtu.be/e4c_UP2fSjg "ML for beginners - Linear and Polynomial Regression using Scikit-learn") > 🎥 คลิกที่ภาพด้านบนเพื่อชมวิดีโอสั้นๆ เกี่ยวกับภาพรวมของการถดถอยเชิงเส้นและพหุนาม เพื่อฝึกโมเดล Linear Regression เราจะใช้ไลบรารี **Scikit-learn** ```python from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error from sklearn.model_selection import train_test_split ``` เริ่มจากแยกค่าอินพุต (คุณลักษณะ) และผลลัพธ์ที่คาดหวัง (ป้ายชื่อ) ออกเป็นอาร์เรย์ numpy แยกกัน: ```python X = pie_pumpkins['DayOfYear'].to_numpy().reshape(-1,1) y = pie_pumpkins['Price'] ``` > โปรดสังเกตว่าเราต้องทำการ `reshape` กับข้อมูลอินพุตเพื่อให้แพ็กเกจ Linear Regression เข้าใจถูกต้อง Linear Regression ต้องการอาร์เรย์สองมิติที่แต่ละแถวเป็นเวกเตอร์คุณลักษณะอินพุต ในกรณีนี้เนื่องจากเรามีแค่คุณลักษณะเดียว เราจึงต้องการอาร์เรย์รูปทรง N×1 โดยที่ N คือขนาดข้อมูล จากนั้นเราต้องแบ่งข้อมูลออกเป็นชุดฝึก (train) และชุดทดสอบ (test) เพื่อยืนยันโมเดลหลังการฝึก: ```python X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) ``` สุดท้าย การฝึกโมเดล Linear Regression จริงๆ ใช้แค่สองบรรทัดโค้ด เราสร้างอ็อบเจ็กต์ `LinearRegression` และฟิตโมเดลกับข้อมูลโดยใช้เมธอด `fit`: ```python lin_reg = LinearRegression() lin_reg.fit(X_train,y_train) ``` อ็อบเจ็กต์ `LinearRegression` หลังจากที่ได้ `fit` แล้วจะมีค่าสัมประสิทธิ์ทั้งหมดของการถดถอยซึ่งสามารถเข้าถึงได้โดยใช้คุณสมบัติ `.coef_` ในกรณีของเรา มีสัมประสิทธิ์เพียงตัวเดียวซึ่งควรจะประมาณ `-0.017` ซึ่งหมายความว่าราคาดูเหมือนจะลดลงเล็กน้อยตามเวลา แต่ไม่มากนัก ราวๆ 2 เซนต์ต่อวัน เรายังสามารถเข้าถึงจุดตัดของเส้นถดถอยกับแกน Y ได้โดยใช้ `lin_reg.intercept_` ซึ่งในกรณีของเราจะอยู่ประมาณ `21` ซึ่งบ่งชี้ราคาตอนต้นปี เพื่อดูว่าโมเดลของเรามีความแม่นยำแค่ไหน เราสามารถทำนายราคาบนชุดข้อมูลทดสอบ และวัดว่าการทำนายของเราใกล้เคียงกับค่าที่คาดหวังแค่ไหน ซึ่งสามารถทำได้โดยใช้เมตริกค่า root mean square error (RMSE) ซึ่งเป็นรากที่ของค่าเฉลี่ยของความแตกต่างยกกำลังสองทั้งหมดระหว่างค่าที่คาดหวังและค่าที่ทำนาย ```python pred = lin_reg.predict(X_test) rmse = np.sqrt(mean_squared_error(y_test,pred)) print(f'RMSE: {rmse:3.3} ({rmse/np.mean(pred)*100:3.3}%)') ``` ข้อผิดพลาดของเราดูเหมือนจะอยู่ประมาณ 2 จุด ซึ่งราวๆ ~17% ซึ่งไม่ดีนัก อีกตัวบ่งชี้คุณภาพของโมเดลคือ **coefficient of determination** ซึ่งสามารถหาได้ดังนี้: ```python score = lin_reg.score(X_train,y_train) print('Model determination: ', score) ``` ถ้าค่าคือ 0 หมายความว่าโมเดลไม่ได้พิจารณาข้อมูลนำเข้า และทำหน้าที่เหมือน *linear predictor ที่แย่ที่สุด* ซึ่งคือค่าเฉลี่ยของผลลัพธ์ ค่าของ 1 หมายความว่าเราสามารถทำนายเอาต์พุตทั้งหมดได้อย่างสมบูรณ์ ในกรณีของเรา ค่าสัมประสิทธิ์อยู่ที่ประมาณ 0.06 ซึ่งค่อนข้างต่ำ เรายังสามารถวาดกราฟข้อมูลทดสอบพร้อมกับเส้นถดถอยเพื่อดูว่าเส้นถดถอยทำงานอย่างไรในกรณีของเราได้อีกด้วย: ```python plt.scatter(X_test,y_test) plt.plot(X_test,pred) ``` Linear regression ## การถดถอยแบบพหุนาม (Polynomial Regression) อีกประเภทหนึ่งของ Linear Regression คือ Polynomial Regression ในบางครั้งความสัมพันธ์ระหว่างตัวแปรเป็นแบบเชิงเส้น เช่น ยิ่งฟักทองมีปริมาตรมาก ราคาก็จะสูงขึ้น แต่บางครั้งความสัมพันธ์เหล่านี้ไม่สามารถแสดงบนระนาบหรือเส้นตรงได้ ✅ นี่คือ [ตัวอย่างเพิ่มเติม](https://online.stat.psu.edu/stat501/lesson/9/9.8) ของข้อมูลที่สามารถใช้ Polynomial Regression ลองดูความสัมพันธ์ระหว่าง Date กับ Price อีกครั้ง พล็อตแบบกระจายนี้ดูเหมือนควรได้รับการวิเคราะห์ด้วยเส้นตรงใช่ไหม? ราคาสามารถเปลี่ยนแปลงขึ้นลงได้หรือเปล่า? ในกรณีนี้คุณสามารถลองใช้ Polynomial Regression ได้ ✅ พหุนามคือสมการคณิตศาสตร์ที่อาจประกอบด้วยตัวแปรหนึ่งตัวหรือมากกว่าและสัมประสิทธิ์ Polynomial regression สร้างเส้นโค้งเพื่อให้พอดีกับข้อมูลที่ไม่เชิงเส้นได้ดีขึ้น ในกรณีของเรา ถ้าเราเพิ่มตัวแปร `DayOfYear` กำลังสองลงในการป้อนข้อมูล เราควรจะสามารถพอดีกับข้อมูลของเราด้วยเส้นโค้งพาราโบลาที่มีค่าต่ำสุดในจุดหนึ่งภายในปีได้ Scikit-learn มี [pipeline API](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_pipeline.html?highlight=pipeline#sklearn.pipeline.make_pipeline) ที่ช่วยรวมขั้นตอนการประมวลผลข้อมูลต่างๆ เข้าด้วยกัน **pipeline** คือสายโซ่ของ **estimators** ในกรณีของเรา เราจะสร้าง pipeline ที่เพิ่มคุณลักษณะพหุนามให้กับโมเดลก่อน แล้วค่อยฝึกถดถอย: ```python from sklearn.preprocessing import PolynomialFeatures from sklearn.pipeline import make_pipeline pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression()) pipeline.fit(X_train,y_train) ``` การใช้ `PolynomialFeatures(2)` หมายความว่าเราจะรวมพหุนามอันดับสองทั้งหมดจากข้อมูลนำเข้า ในกรณีของเรา จะหมายถึง `DayOfYear`2 เท่านั้น แต่ถ้ามีตัวแปรนำเข้า X และ Y สองตัว จะเพิ่ม X2, XY และ Y2 ลงไปด้วย เราสามารถใช้พหุนามลำดับสูงกว่านี้ได้ถ้าต้องการ Pipeline สามารถใช้เหมือนกับอ็อบเจ็กต์ `LinearRegression` เดิม เช่น เราสามารถ `fit` pipeline แล้วใช้ `predict` เพื่อรับผลการทำนาย นี่คือกราฟที่แสดงข้อมูลทดสอบ และเส้นโค้งประมาณค่า: Polynomial regression ใช้ Polynomial Regression เราจะได้ค่า MSE ต่ำลงเล็กน้อยและค่าการกำหนดสูงขึ้น แต่ไม่มากนัก เราจำเป็นต้องพิจารณาคุณลักษณะอื่นด้วย! > คุณเห็นไหมว่าราคาฟักทองต่ำสุดจะอยู่ช่วงราวๆ ฮาโลวีน คุณอธิบายเรื่องนี้อย่างไร? 🎃 ยินดีด้วย คุณเพิ่งสร้างโมเดลที่ช่วยทำนายราคาฟักทองพายได้แล้ว คุณอาจจะทำซ้ำขั้นตอนเดียวกันนี้สำหรับฟักทองชนิดอื่นๆ แต่คงจะน่าเบื่อ เรามาเรียนรู้วิธีนำหลายชนิดฟักทองมาใช้ในโมเดลกัน! ## คุณลักษณะเชิงกลุ่ม (Categorical Features) ในโลกที่สมบูรณ์แบบ เราต้องการทำนายราคาสำหรับฟักทองชนิดต่างๆโดยใช้โมเดลเดียวกัน อย่างไรก็ตาม คอลัมน์ `Variety` แตกต่างจากคอลัมน์เช่น `Month` เพราะมีค่าที่ไม่ใช่ตัวเลข คอลัมน์เหล่านี้เรียกว่า **เชิงหมวดหมู่ (categorical)** [![ML for beginners - Categorical Feature Predictions with Linear Regression](https://img.youtube.com/vi/DYGliioIAE0/0.jpg)](https://youtu.be/DYGliioIAE0 "ML for beginners - Categorical Feature Predictions with Linear Regression") > 🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอสั้น ๆ เกี่ยวกับการใช้คุณลักษณะเชิงหมวดหมู่ นี่คือภาพแสดงว่าราคากลางขึ้นอยู่กับชนิดฟักทองอย่างไร: Average price by variety เพื่อพิจารณาชนิดฟักทอง เราต้องแปลงค่าให้เป็นตัวเลข หรือที่เรียกว่า **การเข้ารหัส (encoding)** มีหลายวิธีที่เราทำได้: * การ **เข้ารหัสเชิงตัวเลขแบบง่ายๆ** จะสร้างตารางของชนิดฟักทองที่แตกต่างกัน แล้วแทนที่ชื่อชนิดด้วยดัชนีในตารางนั้น วิธีนี้ไม่เหมาะกับ Linear Regression เพราะ Linear Regression จะนำค่าตัวเลขของดัชนีไปคำนวณและคูณด้วยสัมประสิทธิ์ ในกรณีของเรา ความสัมพันธ์ระหว่างหมายเลขดัชนีและราคาไม่เป็นเชิงเส้นชัดเจน แม้เราจะจัดเรียงดัชนีให้อยู่ตามลำดับเฉพาะก็ตาม * การ **เข้ารหัสแบบ one-hot** จะแทนที่คอลัมน์ `Variety` ด้วย 4 คอลัมน์แยกต่างหาก หนึ่งคอลัมน์สำหรับแต่ละชนิด แต่ละคอลัมน์จะมีค่าเป็น `1` ถ้าแถวตรงกับชนิดนั้น และ `0` ในกรณีอื่นๆ ซึ่งหมายความว่าจะมีสี่สัมประสิทธิ์ใน Linear Regression หนึ่งสัมประสิทธิ์สำหรับแต่ละชนิดฟักทอง รับหน้าที่เป็น "ราคาฐาน" (หรือจริงๆ คือ "ราคาที่เพิ่มขึ้น") สำหรับชนิดนั้น ตัวอย่างโค้ดด้านล่างแสดงวิธีการเข้ารหัสชนิดฟักทองแบบ one-hot: ```python pd.get_dummies(new_pumpkins['Variety']) ``` ID | FAIRYTALE | MINIATURE | MIXED HEIRLOOM VARIETIES | PIE TYPE ----|-----------|-----------|--------------------------|---------- 70 | 0 | 0 | 0 | 1 71 | 0 | 0 | 0 | 1 ... | ... | ... | ... | ... 1738 | 0 | 1 | 0 | 0 1739 | 0 | 1 | 0 | 0 1740 | 0 | 1 | 0 | 0 1741 | 0 | 1 | 0 | 0 1742 | 0 | 1 | 0 | 0 ในการฝึก Linear Regression โดยใช้ชนิดฟักทองที่เข้ารหัสแบบ one-hot เป็นอินพุต เราเพียงแค่ต้องกำหนดค่า `X` และ `y` ให้ถูกต้อง: ```python X = pd.get_dummies(new_pumpkins['Variety']) y = new_pumpkins['Price'] ``` ส่วนที่เหลือของโค้ดยังคงเหมือนกับที่เราใช้ด้านบนในการฝึก Linear Regression หากทำตามนี้ คุณจะเห็นว่า mean squared error ประมาณเท่าเดิม แต่ค่าสัมประสิทธิ์การกำหนดเพิ่มขึ้นสูงมาก (~77%) เพื่อให้ได้การทำนายที่แม่นยำขึ้นอีก เราสามารถนำคุณลักษณะเชิงกลุ่มอื่นๆ รวมทั้งคุณลักษณะเชิงตัวเลข เช่น `Month` หรือ `DayOfYear` มารวมกันได้ โดยใช้ `join`: ```python X = pd.get_dummies(new_pumpkins['Variety']) \ .join(new_pumpkins['Month']) \ .join(pd.get_dummies(new_pumpkins['City'])) \ .join(pd.get_dummies(new_pumpkins['Package'])) y = new_pumpkins['Price'] ``` ที่นี่เรายังคำนึงถึง `City` และชนิด `Package` ซึ่งทำให้ได้ MSE เป็น 2.84 (10%) และค่าสัมประสิทธิ์การกำหนด 0.94! ## รวบรวมทั้งหมดเข้าด้วยกัน เพื่อสร้างโมเดลที่ดีที่สุด เราสามารถใช้ข้อมูลรวม (ข้อมูลเชิงกลุ่มแบบ one-hot และเชิงตัวเลข) จากตัวอย่างด้านบนร่วมกับ Polynomial Regression นี่คือโค้ดครบถ้วนเพื่อความสะดวกของคุณ: ```python # ตั้งค่าข้อมูลฝึกอบรม X = pd.get_dummies(new_pumpkins['Variety']) \ .join(new_pumpkins['Month']) \ .join(pd.get_dummies(new_pumpkins['City'])) \ .join(pd.get_dummies(new_pumpkins['Package'])) y = new_pumpkins['Price'] # แบ่งข้อมูลเป็นชุดฝึกและทดสอบ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) # ตั้งค่าและฝึกท่อประมวลผล pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression()) pipeline.fit(X_train,y_train) # ทำนายผลลัพธ์สำหรับข้อมูลทดสอบ pred = pipeline.predict(X_test) # คำนวณ MSE และค่าการกำหนด mse = np.sqrt(mean_squared_error(y_test,pred)) print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)') score = pipeline.score(X_train,y_train) print('Model determination: ', score) ``` โมเดลนี้ควรให้ค่าสัมประสิทธิ์การกำหนดที่ดีที่สุดเกือบ 97% และ MSE=2.23 (~8% ความผิดพลาดในการทำนาย) | โมเดล | MSE | ค่าสัมประสิทธิ์การกำหนด | |-------|-----|---------------| | `DayOfYear` Linear | 2.77 (17.2%) | 0.07 | | `DayOfYear` Polynomial | 2.73 (17.0%) | 0.08 | | `Variety` Linear | 5.24 (19.7%) | 0.77 | | ทุกคุณลักษณะ Linear | 2.84 (10.5%) | 0.94 | | ทุกคุณลักษณะ Polynomial | 2.23 (8.25%) | 0.97 | 🏆 เยี่ยมมาก! คุณสร้างโมเดล Regression สี่โมเดลในบทเรียนเดียว และเพิ่มคุณภาพของโมเดลถึง 97% ในส่วนสุดท้ายของบทเรียน Regression คุณจะได้เรียนรู้ Logistic Regression สำหรับการจำแนกประเภท --- ## 🚀ความท้าทาย ลองทดสอบตัวแปรหลายๆ ตัวในสมุดงานนี้เพื่อดูว่าความสัมพันธ์ส่งผลต่อความแม่นยำของโมเดลอย่างไร ## [แบบทดสอบหลังเรียน](https://ff-quizzes.netlify.app/en/ml/) ## ทบทวน & ศึกษาด้วยตนเอง ในบทเรียนนี้ เราได้เรียนรู้เกี่ยวกับ Linear Regression ยังมีเทคนิค Regression ประเภทอื่นที่สำคัญ อ่านเกี่ยวกับเทคนิค Stepwise, Ridge, Lasso และ Elasticnet คอร์สดีๆ ที่แนะนำให้อ่านเพิ่มเติมคือ [Stanford Statistical Learning course](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning) ## การบ้าน [สร้างโมเดล](assignment.md) --- **ข้อจำกัดความรับผิดชอบ**: เอกสารนี้ได้รับการแปลโดยใช้บริการแปลอัตโนมัติ [Co-op Translator](https://github.com/Azure/co-op-translator) แม้ว่าเราจะพยายามให้ข้อมูลถูกต้องที่สุด โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาต้นทางควรถูกพิจารณาเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลสำคัญแนะนำให้ใช้บริการแปลมืออาชีพโดยมนุษย์ เราจะไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความผิดที่เกิดจากการใช้การแปลนี้