You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/th/2-Regression/3-Linear/README.md

381 lines
44 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "40e64f004f3cb50aa1d8661672d3cd92",
"translation_date": "2025-09-05T21:05:15+00:00",
"source_file": "2-Regression/3-Linear/README.md",
"language_code": "th"
}
-->
# สร้างโมเดลการถดถอยด้วย Scikit-learn: การถดถอย 4 วิธี
![อินโฟกราฟิกการถดถอยเชิงเส้นและพหุนาม](../../../../2-Regression/3-Linear/images/linear-polynomial.png)
> อินโฟกราฟิกโดย [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) การสร้างภาพช่วยให้คุณเข้าใจข้อมูล แต่พลังที่แท้จริงของการเรียนรู้ของเครื่องมาจาก _การฝึกโมเดล_ โมเดลถูกฝึกด้วยข้อมูลในอดีตเพื่อจับความสัมพันธ์ของข้อมูลโดยอัตโนมัติ และช่วยให้คุณคาดการณ์ผลลัพธ์สำหรับข้อมูลใหม่ที่โมเดลไม่เคยเห็นมาก่อน
ในบทเรียนนี้ คุณจะได้เรียนรู้เพิ่มเติมเกี่ยวกับการถดถอยสองประเภท: _การถดถอยเชิงเส้นพื้นฐาน_ และ _การถดถอยพหุนาม_ พร้อมกับคณิตศาสตร์บางส่วนที่อยู่เบื้องหลังเทคนิคเหล่านี้ โมเดลเหล่านี้จะช่วยให้เราคาดการณ์ราคาฟักทองตามข้อมูลอินพุตที่แตกต่างกัน
[![ML สำหรับผู้เริ่มต้น - เข้าใจการถดถอยเชิงเส้น](https://img.youtube.com/vi/CRxFT8oTDMg/0.jpg)](https://youtu.be/CRxFT8oTDMg "ML สำหรับผู้เริ่มต้น - เข้าใจการถดถอยเชิงเส้น")
> 🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอสั้น ๆ เกี่ยวกับการถดถอยเชิงเส้น
> ตลอดหลักสูตรนี้ เราสมมติว่าคุณมีความรู้ทางคณิตศาสตร์เพียงเล็กน้อย และพยายามทำให้เข้าใจง่ายสำหรับนักเรียนที่มาจากสาขาอื่น ดังนั้นโปรดสังเกตบันทึก 🧮 คำอธิบายภาพ และเครื่องมือการเรียนรู้อื่น ๆ เพื่อช่วยในการทำความเข้าใจ
### ความรู้พื้นฐานที่ควรมี
ตอนนี้คุณควรคุ้นเคยกับโครงสร้างของข้อมูลฟักทองที่เรากำลังตรวจสอบ คุณสามารถค้นหาข้อมูลนี้ที่โหลดไว้ล่วงหน้าและทำความสะอาดไว้ในไฟล์ _notebook.ipynb_ ของบทเรียนนี้ ในไฟล์นี้ ราคาฟักทองจะแสดงต่อบุชเชลใน DataFrame ใหม่ ตรวจสอบให้แน่ใจว่าคุณสามารถรันโน้ตบุ๊กเหล่านี้ในเคอร์เนลของ Visual Studio Code ได้
### การเตรียมตัว
เพื่อเป็นการทบทวน คุณกำลังโหลดข้อมูลนี้เพื่อถามคำถามเกี่ยวกับข้อมูล เช่น:
- ช่วงเวลาใดที่ดีที่สุดในการซื้อฟักทอง?
- ราคาที่คาดหวังสำหรับฟักทองขนาดเล็กหนึ่งกล่องคือเท่าไร?
- ควรซื้อฟักทองในตะกร้าครึ่งบุชเชลหรือในกล่องขนาด 1 1/9 บุชเชล?
มาดำดิ่งลงไปในข้อมูลนี้กันต่อ
ในบทเรียนก่อน คุณได้สร้าง Pandas DataFrame และเติมข้อมูลบางส่วนจากชุดข้อมูลต้นฉบับ โดยการปรับมาตรฐานราคาต่อบุชเชล อย่างไรก็ตาม คุณสามารถรวบรวมข้อมูลได้เพียงประมาณ 400 จุดข้อมูล และเฉพาะในช่วงฤดูใบไม้ร่วงเท่านั้น
ลองดูข้อมูลที่โหลดไว้ล่วงหน้าในโน้ตบุ๊กที่มาพร้อมกับบทเรียนนี้ ข้อมูลถูกโหลดไว้ล่วงหน้าและมีการสร้างกราฟกระจายเบื้องต้นเพื่อแสดงข้อมูลตามเดือน บางทีเราอาจได้รายละเอียดเพิ่มเติมเกี่ยวกับลักษณะของข้อมูลโดยการทำความสะอาดข้อมูลเพิ่มเติม
## เส้นการถดถอยเชิงเส้น
ตามที่คุณได้เรียนรู้ในบทเรียนที่ 1 เป้าหมายของการถดถอยเชิงเส้นคือการวาดเส้นเพื่อ:
- **แสดงความสัมพันธ์ของตัวแปร** แสดงความสัมพันธ์ระหว่างตัวแปร
- **ทำการคาดการณ์** คาดการณ์ตำแหน่งของจุดข้อมูลใหม่ในความสัมพันธ์กับเส้นนั้นอย่างแม่นยำ
โดยทั่วไป **Least-Squares Regression** จะใช้ในการวาดเส้นประเภทนี้ คำว่า 'least-squares' หมายถึงการนำจุดข้อมูลทั้งหมดรอบเส้นการถดถอยมายกกำลังสองและรวมเข้าด้วยกัน โดยอุดมคติแล้ว ผลรวมสุดท้ายควรมีค่าน้อยที่สุด เพราะเราต้องการข้อผิดพลาดที่น้อยที่สุด หรือ `least-squares`
เราทำเช่นนี้เพราะเราต้องการสร้างโมเดลเส้นที่มีระยะทางสะสมจากจุดข้อมูลทั้งหมดน้อยที่สุด นอกจากนี้ เรายังยกกำลังสองก่อนรวมกันเพราะเราสนใจขนาดของค่ามากกว่าทิศทาง
> **🧮 แสดงคณิตศาสตร์ให้ฉันดู**
>
> เส้นนี้เรียกว่า _เส้นที่เหมาะสมที่สุด_ สามารถแสดงได้ด้วย [สมการ](https://en.wikipedia.org/wiki/Simple_linear_regression):
>
> ```
> Y = a + bX
> ```
>
> `X` คือ 'ตัวแปรอธิบาย' `Y` คือ 'ตัวแปรตาม' ความชันของเส้นคือ `b` และ `a` คือจุดตัดแกน Y ซึ่งหมายถึงค่าของ `Y` เมื่อ `X = 0`
>
>![คำนวณความชัน](../../../../2-Regression/3-Linear/images/slope.png)
>
> ขั้นแรก คำนวณความชัน `b` อินโฟกราฟิกโดย [Jen Looper](https://twitter.com/jenlooper)
>
> กล่าวอีกนัยหนึ่ง และอ้างอิงจากคำถามดั้งเดิมของข้อมูลฟักทอง: "คาดการณ์ราคาฟักทองต่อบุชเชลตามเดือน" `X` จะหมายถึงราคา และ `Y` จะหมายถึงเดือนที่ขาย
>
>![สมการที่สมบูรณ์](../../../../2-Regression/3-Linear/images/calculation.png)
>
> คำนวณค่าของ Y ถ้าคุณจ่ายประมาณ $4 นั่นอาจเป็นเดือนเมษายน! อินโฟกราฟิกโดย [Jen Looper](https://twitter.com/jenlooper)
>
> คณิตศาสตร์ที่คำนวณเส้นต้องแสดงความชันของเส้น ซึ่งขึ้นอยู่กับจุดตัดแกนด้วย หรือค่าที่ `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) เพื่อดูว่าค่าต่าง ๆ ส่งผลต่อเส้นอย่างไร
## ความสัมพันธ์
อีกคำหนึ่งที่ควรเข้าใจคือ **ค่าสัมประสิทธิ์ความสัมพันธ์** ระหว่างตัวแปร X และ Y ที่กำหนด การใช้กราฟกระจาย คุณสามารถมองเห็นค่าสัมประสิทธิ์นี้ได้อย่างรวดเร็ว กราฟที่มีจุดข้อมูลกระจายเป็นเส้นเรียบมีความสัมพันธ์สูง แต่กราฟที่มีจุดข้อมูลกระจายไปทั่วระหว่าง X และ Y มีความสัมพันธ์ต่ำ
โมเดลการถดถอยเชิงเส้นที่ดีจะเป็นโมเดลที่มีค่าสัมประสิทธิ์ความสัมพันธ์สูง (ใกล้ 1 มากกว่า 0) โดยใช้วิธี Least-Squares Regression พร้อมเส้นการถดถอย
✅ รันโน้ตบุ๊กที่มาพร้อมกับบทเรียนนี้และดูกราฟกระจายของข้อมูลเดือนกับราคา ข้อมูลที่เชื่อมโยงเดือนกับราคาสำหรับการขายฟักทองดูเหมือนจะมีความสัมพันธ์สูงหรือต่ำตามการตีความด้วยสายตาของคุณ? ความสัมพันธ์นั้นเปลี่ยนไปหรือไม่หากคุณใช้มาตรการที่ละเอียดกว่า เช่น *วันในปี* (เช่น จำนวนวันตั้งแต่ต้นปี)?
ในโค้ดด้านล่าง เราจะสมมติว่าเราได้ทำความสะอาดข้อมูลแล้ว และได้ 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`](../../../../2-Regression/3-Linear/notebook.ipynb) เราได้ทำตามขั้นตอนการทำความสะอาดเดียวกับในบทเรียนก่อน และได้คำนวณคอลัมน์ `DayOfYear` โดยใช้สูตรต่อไปนี้:
```python
day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)
```
เมื่อคุณเข้าใจคณิตศาสตร์เบื้องหลังการถดถอยเชิงเส้นแล้ว มาสร้างโมเดลการถดถอยเพื่อดูว่าเราสามารถคาดการณ์ได้หรือไม่ว่าชุดฟักทองใดจะมีราคาที่ดีที่สุดสำหรับฟักทอง ผู้ที่ซื้อฟักทองสำหรับแปลงฟักทองในวันหยุดอาจต้องการข้อมูลนี้เพื่อเพิ่มประสิทธิภาพการซื้อชุดฟักทองสำหรับแปลง
## การมองหาความสัมพันธ์
[![ML สำหรับผู้เริ่มต้น - การมองหาความสัมพันธ์: กุญแจสู่การถดถอยเชิงเส้น](https://img.youtube.com/vi/uoRq-lW2eQo/0.jpg)](https://youtu.be/uoRq-lW2eQo "ML สำหรับผู้เริ่มต้น - การมองหาความสัมพันธ์: กุญแจสู่การถดถอยเชิงเส้น")
> 🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอสั้น ๆ เกี่ยวกับความสัมพันธ์
จากบทเรียนก่อน คุณอาจเห็นว่าราคาเฉลี่ยสำหรับแต่ละเดือนมีลักษณะดังนี้:
<img alt="ราคาเฉลี่ยตามเดือน" src="../2-Data/images/barchart.png" width="50%"/>
สิ่งนี้ชี้ให้เห็นว่าควรมีความสัมพันธ์บางอย่าง และเราสามารถลองฝึกโมเดลการถดถอยเชิงเส้นเพื่อคาดการณ์ความสัมพันธ์ระหว่าง `Month` และ `Price` หรือระหว่าง `DayOfYear` และ `Price` นี่คือกราฟกระจายที่แสดงความสัมพันธ์หลัง:
<img alt="กราฟกระจายของราคาเทียบกับวันในปี" src="images/scatter-dayofyear.png" width="50%" />
มาดูกันว่ามีความสัมพันธ์หรือไม่โดยใช้ฟังก์ชัน `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)
```
<img alt="กราฟกระจายของราคาเทียบกับวันในปี" src="images/scatter-dayofyear-color.png" width="50%" />
การตรวจสอบของเราชี้ให้เห็นว่าพันธุ์มีผลต่อราคามากกว่าวันที่ขาย เราสามารถเห็นสิ่งนี้ได้จากกราฟแท่ง:
```python
new_pumpkins.groupby('Variety')['Price'].mean().plot(kind='bar')
```
<img alt="กราฟแท่งของราคาเทียบกับพันธุ์" src="images/price-by-variety.png" width="50%" />
ให้เรามุ่งเน้นไปที่พันธุ์ฟักทองชนิดเดียวคือ 'pie type' และดูว่าผลของวันที่มีต่อราคาเป็นอย่างไร:
```python
pie_pumpkins = new_pumpkins[new_pumpkins['Variety']=='PIE TYPE']
pie_pumpkins.plot.scatter('DayOfYear','Price')
```
<img alt="กราฟกระจายของราคาเทียบกับวันในปี" src="images/pie-pumpkins-scatter.png" width="50%" />
หากเราคำนวณความสัมพันธ์ระหว่าง `Price` และ `DayOfYear` โดยใช้ฟังก์ชัน `corr` ตอนนี้ เราจะได้ค่าประมาณ `-0.27` - ซึ่งหมายความว่าการฝึกโมเดลการคาดการณ์มีเหตุผล
> ก่อนการฝึกโมเดลการถดถอยเชิงเส้น สิ่งสำคัญคือต้องแน่ใจว่าข้อมูลของเราสะอาด การถดถอยเชิงเส้นไม่ทำงานได้ดีนักกับค่าที่ขาดหายไป ดังนั้นจึงสมควรที่จะลบเซลล์ว่างทั้งหมด:
```python
pie_pumpkins.dropna(inplace=True)
pie_pumpkins.info()
```
อีกวิธีหนึ่งคือเติมค่าที่ว่างเปล่าด้วยค่ามeanจากคอลัมน์ที่เกี่ยวข้อง
## การถดถอยเชิงเส้นแบบง่าย
[![ML สำหรับผู้เริ่มต้น - การถดถอยเชิงเส้นและพหุนามด้วย Scikit-learn](https://img.youtube.com/vi/e4c_UP2fSjg/0.jpg)](https://youtu.be/e4c_UP2fSjg "ML สำหรับผู้เริ่มต้น - การถดถอยเชิงเส้นและพหุนามด้วย Scikit-learn")
> 🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอสั้น ๆ เกี่ยวกับการถดถอยเชิงเส้นและพหุนาม
ในการฝึกโมเดลการถดถอยเชิงเส้น เราจะใช้ไลบรารี **Scikit-learn**
```python
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
```
เริ่มต้นด้วยการแยกค่าข้อมูลอินพุต (features) และผลลัพธ์ที่คาดหวัง (label) ออกเป็นอาเรย์ numpy แยกกัน:
```python
X = pie_pumpkins['DayOfYear'].to_numpy().reshape(-1,1)
y = pie_pumpkins['Price']
```
> โปรดทราบว่าเราต้องใช้ `reshape` กับข้อมูลอินพุตเพื่อให้แพ็กเกจ Linear Regression เข้าใจได้อย่างถูกต้อง Linear Regression คาดหวังอาเรย์ 2 มิติเป็นอินพุต โดยที่แต่ละแถวของอาเรย์สอดคล้องกับเวกเตอร์ของฟีเจอร์อินพุต ในกรณีของเรา เนื่องจากเรามีอินพุตเพียงหนึ่งตัว - เราต้องการอาเรย์ที่มีรูปร่าง N×1 โดยที่ N คือขนาดของชุดข้อมูล
จากนั้น เราต้องแบ่งข้อมูลออกเป็นชุดข้อมูลการฝึกและการทดสอบ เพื่อให้เราสามารถตรวจสอบความถูกต้องของโมเดลหลังการฝึกได้:
```python
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
```
สุดท้าย การฝึกโมเดลการถดถอยเชิงเส้นจริงใช้เพียงสองบรรทัดโค้ด เรากำหนดออบเจ็กต์ `LinearRegression` และปรับให้เข้ากับข้อมูลของเราโดยใช้เมธอด `fit`:
```python
lin_reg = LinearRegression()
lin_reg.fit(X_train,y_train)
```
ออบเจ็กต์ `LinearRegression` หลังจาก `fit` จะมีสัมประสิทธิ์ทั้งหมดของการถดถอย ซึ่งสามารถเข้าถึงได้โดยใช้คุณสมบัติ `.coef_` ในกรณีของเรา มีเพียงสัมประสิทธิ์เดียว ซึ่งควรอยู่ที่ประมาณ `-0.017` ซึ่งหมายความว่าราคาดูเหมือนจะลดลงเล็กน้อยตามเวลา แต่ไม่มากนัก ประมาณ 2 เซนต์ต่อวัน นอกจากนี้เรายังสามารถเข้าถึงจุดตัดแกน Y ของการถดถอยได้โดยใช้ `lin_reg.intercept_` - ซึ่งจะอยู่ที่ประมาณ `21` ในกรณีของเรา ซึ่งบ่งชี้ถึงราคาต้นปี
เพื่อดูว่าโมเดลของเรามีความแม่นยำเพียงใด เราสามารถคาดการณ์ราคาบนชุดข้อมูลทดสอบ และวัดว่าการคาดการณ์ของเราใกล้เคียงกับค่าที่คาดหวังเพียงใด สิ่งนี้สามารถทำได้โดยใช้เมตริก Mean Square Error (MSE) ซึ่งเป็นค่าเฉลี่ยของผลต่างกำลังสองทั้งหมดระหว่างค่าที่คาดหวังและค่าที่คาดการณ์
```python
pred = lin_reg.predict(X_test)
mse = np.sqrt(mean_squared_error(y_test,pred))
print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)')
```
ข้อผิดพลาดของเราดูเหมือนจะอยู่ที่ประมาณ 2 จุด ซึ่งคิดเป็น ~17% ไม่ค่อยดีนัก ตัวบ่งชี้อีกตัวหนึ่งของคุณภาพโมเดลคือ **ค่าสัมประสิทธิ์การกำหนด** ซึ่งสามารถหาได้ดังนี้:
```python
score = lin_reg.score(X_train,y_train)
print('Model determination: ', score)
```
หากค่ามีค่าเท่ากับ 0 หมายความว่าโมเดลไม่ได้คำนึงถึงข้อมูลนำเข้า และทำหน้าที่เป็น *ตัวทำนายเชิงเส้นที่แย่ที่สุด* ซึ่งเป็นเพียงค่าเฉลี่ยของผลลัพธ์เท่านั้น ค่าที่เท่ากับ 1 หมายความว่าเราสามารถทำนายผลลัพธ์ที่คาดหวังได้อย่างสมบูรณ์แบบ ในกรณีของเรา ค่าสัมประสิทธิ์อยู่ที่ประมาณ 0.06 ซึ่งค่อนข้างต่ำ
เรายังสามารถสร้างกราฟข้อมูลทดสอบพร้อมกับเส้นการถดถอยเพื่อดูว่าการถดถอยทำงานอย่างไรในกรณีของเรา:
```python
plt.scatter(X_test,y_test)
plt.plot(X_test,pred)
```
<img alt="Linear regression" src="images/linear-results.png" width="50%" />
## การถดถอยเชิงพหุนาม
อีกประเภทหนึ่งของการถดถอยเชิงเส้นคือการถดถอยเชิงพหุนาม บางครั้งความสัมพันธ์ระหว่างตัวแปรอาจเป็นเชิงเส้น เช่น ยิ่งฟักทองมีปริมาตรมาก ราคาก็ยิ่งสูงขึ้น แต่บางครั้งความสัมพันธ์เหล่านี้ไม่สามารถวาดเป็นระนาบหรือเส้นตรงได้
✅ [ตัวอย่างเพิ่มเติม](https://online.stat.psu.edu/stat501/lesson/9/9.8) ของข้อมูลที่สามารถใช้การถดถอยเชิงพหุนาม
ลองดูความสัมพันธ์ระหว่างวันที่และราคาอีกครั้ง กราฟกระจายนี้ดูเหมือนควรจะวิเคราะห์ด้วยเส้นตรงหรือไม่? ราคาสามารถผันผวนได้หรือไม่? ในกรณีนี้ คุณสามารถลองใช้การถดถอยเชิงพหุนาม
✅ พหุนามเป็นนิพจน์ทางคณิตศาสตร์ที่อาจประกอบด้วยตัวแปรและสัมประสิทธิ์หนึ่งตัวหรือมากกว่า
การถดถอยเชิงพหุนามสร้างเส้นโค้งเพื่อให้เหมาะสมกับข้อมูลที่ไม่เป็นเชิงเส้นได้ดียิ่งขึ้น ในกรณีของเรา หากเรารวมตัวแปร `DayOfYear` กำลังสองเข้าไปในข้อมูลนำเข้า เราควรจะสามารถปรับข้อมูลของเราให้เข้ากับเส้นโค้งพาราโบลา ซึ่งจะมีค่าต่ำสุดในช่วงเวลาหนึ่งของปี
Scikit-learn มี [API pipeline](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`<sup>2</sup> แต่หากมีตัวแปรนำเข้าสองตัว X และ Y จะเพิ่ม X<sup>2</sup>, XY และ Y<sup>2</sup> เราอาจใช้พหุนามระดับสูงกว่านี้หากต้องการ
Pipeline สามารถใช้งานได้ในลักษณะเดียวกับวัตถุ `LinearRegression` ดั้งเดิม เช่น เราสามารถ `fit` pipeline และใช้ `predict` เพื่อรับผลการทำนาย นี่คือกราฟที่แสดงข้อมูลทดสอบและเส้นโค้งประมาณค่า:
<img alt="Polynomial regression" src="images/poly-results.png" width="50%" />
การใช้การถดถอยเชิงพหุนาม เราสามารถลดค่า MSE และเพิ่มค่าสัมประสิทธิ์การกำหนดได้เล็กน้อย แต่ไม่มากนัก เราจำเป็นต้องพิจารณาคุณสมบัติอื่นๆ ด้วย!
> คุณจะเห็นว่าราคาฟักทองต่ำสุดจะอยู่ประมาณวันฮาโลวีน คุณจะอธิบายเรื่องนี้ได้อย่างไร?
🎃 ยินดีด้วย คุณเพิ่งสร้างโมเดลที่สามารถช่วยทำนายราคาฟักทองสำหรับทำพาย คุณอาจทำขั้นตอนเดียวกันนี้ซ้ำสำหรับฟักทองทุกประเภท แต่จะค่อนข้างน่าเบื่อ มาเรียนรู้วิธีนำประเภทฟักทองมาพิจารณาในโมเดลของเรากันเถอะ!
## คุณสมบัติประเภทหมวดหมู่
ในโลกอุดมคติ เราต้องการสามารถทำนายราคาสำหรับฟักทองหลากหลายประเภทโดยใช้โมเดลเดียว อย่างไรก็ตาม คอลัมน์ `Variety` นั้นแตกต่างจากคอลัมน์อย่าง `Month` เพราะมันมีค่าที่ไม่ใช่ตัวเลข คอลัมน์เหล่านี้เรียกว่า **หมวดหมู่**
[![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")
> 🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอสั้นๆ เกี่ยวกับการใช้คุณสมบัติประเภทหมวดหมู่
นี่คือกราฟที่แสดงให้เห็นว่าราคาเฉลี่ยขึ้นอยู่กับประเภทฟักทองอย่างไร:
<img alt="Average price by variety" src="images/price-by-variety.png" width="50%" />
เพื่อพิจารณาประเภทฟักทอง เราต้องแปลงมันเป็นรูปแบบตัวเลขก่อน หรือ **เข้ารหัส** มีหลายวิธีที่เราสามารถทำได้:
* การเข้ารหัสตัวเลขแบบง่ายจะสร้างตารางของประเภทฟักทองต่างๆ และแทนที่ชื่อประเภทฟักทองด้วยดัชนีในตารางนั้น วิธีนี้ไม่เหมาะสำหรับการถดถอยเชิงเส้น เพราะการถดถอยเชิงเส้นจะใช้ค่าตัวเลขของดัชนีจริงๆ และเพิ่มเข้าไปในผลลัพธ์โดยการคูณด้วยสัมประสิทธิ์ ในกรณีของเรา ความสัมพันธ์ระหว่างหมายเลขดัชนีและราคานั้นชัดเจนว่าไม่เป็นเชิงเส้น แม้ว่าเราจะจัดลำดับดัชนีในลักษณะเฉพาะก็ตาม
* **การเข้ารหัสแบบ one-hot** จะเปลี่ยนคอลัมน์ `Variety` เป็น 4 คอลัมน์ที่แตกต่างกัน หนึ่งคอลัมน์สำหรับแต่ละประเภทฟักทอง แต่ละคอลัมน์จะมีค่า `1` หากแถวที่เกี่ยวข้องเป็นประเภทฟักทองนั้น และ `0` หากไม่ใช่ นั่นหมายความว่าจะมีสัมประสิทธิ์สี่ตัวในการถดถอยเชิงเส้น หนึ่งตัวสำหรับแต่ละประเภทฟักทอง ซึ่งรับผิดชอบ "ราคาเริ่มต้น" (หรือ "ราคาที่เพิ่มขึ้น") สำหรับประเภทนั้นๆ
โค้ดด้านล่างแสดงวิธีการเข้ารหัสแบบ 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
เพื่อฝึกการถดถอยเชิงเส้นโดยใช้ประเภทฟักทองที่เข้ารหัสแบบ one-hot เป็นข้อมูลนำเข้า เราเพียงแค่ต้องกำหนดข้อมูล `X` และ `y` ให้ถูกต้อง:
```python
X = pd.get_dummies(new_pumpkins['Variety'])
y = new_pumpkins['Price']
```
โค้ดที่เหลือเหมือนกับที่เราใช้ด้านบนเพื่อฝึกการถดถอยเชิงเส้น หากคุณลอง คุณจะเห็นว่าค่า MSE ใกล้เคียงกัน แต่เราจะได้ค่าสัมประสิทธิ์การกำหนดที่สูงขึ้น (~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 + ตัวเลข) จากตัวอย่างด้านบนร่วมกับการถดถอยเชิงพหุนาม นี่คือโค้ดทั้งหมดเพื่อความสะดวกของคุณ:
```python
# set up training data
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']
# make train-test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
# setup and train the pipeline
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)
# predict results for test data
pred = pipeline.predict(X_test)
# calculate MSE and determination
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 |
| All features Linear | 2.84 (10.5%) | 0.94 |
| All features Polynomial | 2.23 (8.25%) | 0.97 |
🏆 ยอดเยี่ยม! คุณสร้างโมเดลการถดถอย 4 โมเดลในบทเรียนเดียว และปรับปรุงคุณภาพโมเดลได้ถึง 97% ในส่วนสุดท้ายเกี่ยวกับการถดถอย คุณจะได้เรียนรู้เกี่ยวกับการถดถอยโลจิสติกเพื่อกำหนดหมวดหมู่
---
## 🚀ความท้าทาย
ทดสอบตัวแปรต่างๆ ในโน้ตบุ๊กนี้เพื่อดูว่าความสัมพันธ์สอดคล้องกับความแม่นยำของโมเดลอย่างไร
## [แบบทดสอบหลังการบรรยาย](https://ff-quizzes.netlify.app/en/ml/)
## ทบทวนและศึกษาด้วยตนเอง
ในบทเรียนนี้เราได้เรียนรู้เกี่ยวกับการถดถอยเชิงเส้น ยังมีประเภทการถดถอยที่สำคัญอื่นๆ อ่านเกี่ยวกับเทคนิค Stepwise, Ridge, Lasso และ Elasticnet หลักสูตรที่ดีในการศึกษาเพิ่มเติมคือ [Stanford Statistical Learning course](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning)
## งานที่ได้รับมอบหมาย
[สร้างโมเดล](assignment.md)
---
**ข้อจำกัดความรับผิดชอบ**:
เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI [Co-op Translator](https://github.com/Azure/co-op-translator) แม้ว่าเราจะพยายามให้การแปลมีความถูกต้อง แต่โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่แม่นยำ เอกสารต้นฉบับในภาษาดั้งเดิมควรถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ แนะนำให้ใช้บริการแปลภาษาจากผู้เชี่ยวชาญ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความที่ผิดพลาดซึ่งเกิดจากการใช้การแปลนี้