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

387 lines
43 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.

# สร้างโมเดลการถดถอยโดยใช้ 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 แล้ว ในขณะที่การสร้างภาพช่วยให้คุณเข้าใจข้อมูลได้ แต่พลังที่แท้จริงของการเรียนรู้ของเครื่องมาจากการ _ฝึกโมเดล_ โมเดลถูกฝึกด้วยข้อมูลในอดีตเพื่อจับความสัมพันธ์ของข้อมูลโดยอัตโนมัติ และช่วยให้คุณทำนายผลลัพธ์สำหรับข้อมูลใหม่ที่โมเดลไม่เคยเห็นมาก่อน
ในบทเรียนนี้ คุณจะได้เรียนรู้เพิ่มเติมเกี่ยวกับการถดถอยสองประเภท: _การถดถอยเชิงเส้นพื้นฐาน_ และ _การถดถอยพหุนาม_ พร้อมกับคณิตศาสตร์เบื้องหลังเทคนิคเหล่านี้ โมเดลเหล่านี้จะช่วยให้เราทำนายราคาฟักทองขึ้นอยู่กับข้อมูลนำเข้าที่แตกต่างกัน
[![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 และเติมข้อมูลบางส่วนจากชุดข้อมูลต้นฉบับ โดยปรับราคาต่อบัชเชล แต่ด้วยวิธีนี้ คุณได้รวบรวมข้อมูลเพียงประมาณ 400 จุดข้อมูลและเฉพาะในเดือนฤดูใบไม้ร่วงเท่านั้น
ดูข้อมูลที่เราโหลดไว้ล่วงหน้าในโน้ตบุ๊กที่แนบมากับบทเรียนนี้ ข้อมูลนี้ถูกโหลดไว้ล่วงหน้าและสร้างแผนภูมิแบบกระจาย (scatterplot) แรกเพื่อนำเสนอข้อมูลเดือน อาจจะได้รับรายละเอียดมากขึ้นเกี่ยวกับลักษณะของข้อมูลโดยการทำความสะอาดเพิ่มเติม
## เส้นการถดถอยเชิงเส้น
อย่างที่คุณได้เรียนในบทเรียนที่ 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` เมื่อ `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` อยู่เมื่อ `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 ที่กำหนด โดยใช้ scatterplot คุณสามารถเห็นสัมประสิทธิ์นี้ได้อย่างรวดเร็ว กราฟที่มีจุดกระจายเรียงเป็นเส้นตรงจะมีความสัมพันธ์สูง แต่กราฟที่จุดกระจายกระจัดกระจายไปทั่วระหว่าง X และ Y จะมีความสัมพันธ์ต่ำ
โมเดลการถดถอยเชิงเส้นที่ดีจะต้องมีสัมประสิทธิ์สหสัมพันธ์สูง (ใกล้ 1 มากกว่า 0) โดยใช้วิธี Least-Squares Regression กับเส้นถดถอย
✅ รันโน้ตบุ๊กที่แนบมากับบทเรียนนี้และดูกราฟกระจายข้อมูลระหว่างเดือนกับราคา ข้อมูลที่เชื่อมโยงเดือนกับราคาขายในฟักทองดูเหมือนจะมีความสัมพันธ์สูงหรือต่ำ ตามการตีความด้วยสายตาของคุณจากแผนภูมิการกระจาย? นั่นจะเปลี่ยนไปไหมถ้าคุณใช้มาตรวัดที่ละเอียดขึ้นแทน `เดือน` เช่น *วันของปี* (จำนวนวันตั้งแต่ต้นปี)?
ในโค้ดด้านล่างนี้ เราจะสมมติว่าเราได้ทำความสะอาดข้อมูลแล้ว และได้กรอบข้อมูลชื่อ `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")
> 🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอสั้นเกี่ยวกับความสัมพันธ์
จากบทเรียนก่อน คุณน่าจะเห็นว่าราคากลางในแต่ละเดือนดูเหมือนจะเป็นแบบนี้:
<img alt="Average price by month" src="../../../../translated_images/th/barchart.a833ea9194346d76.webp" width="50%"/>
ซึ่งบ่งชี้ว่าควรมีความสัมพันธ์บางอย่าง และเราสามารถลองฝึกโมเดลการถดถอยเชิงเส้นเพื่อทำนายความสัมพันธ์ระหว่าง `Month` กับ `Price` หรือระหว่าง `DayOfYear` กับ `Price` นี่คือกราฟกระจายที่แสดงความสัมพันธ์หลัง:
<img alt="Scatter plot of Price vs. Day of Year" src="../../../../translated_images/th/scatter-dayofyear.bc171c189c9fd553.webp" 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="Scatter plot of Price vs. Day of Year" src="../../../../translated_images/th/scatter-dayofyear-color.65790faefbb9d54f.webp" width="50%" />
การสืบค้นของเราชี้ว่าพันธุ์มีผลต่อราคามากกว่าวันที่ขายจริง เราสามารถเห็นได้ชัดในกราฟแท่ง:
```python
new_pumpkins.groupby('Variety')['Price'].mean().plot(kind='bar')
```
<img alt="Bar graph of price vs variety" src="../../../../translated_images/th/price-by-variety.744a2f9925d9bcb4.webp" width="50%" />
ขอให้เรามุ่งเน้นที่พันธุ์ฟักทอง 'ชนิดพาย' เท่านั้น และดูว่าวันมีผลต่อราคาอย่างไร:
```python
pie_pumpkins = new_pumpkins[new_pumpkins['Variety']=='PIE TYPE']
pie_pumpkins.plot.scatter('DayOfYear','Price')
```
<img alt="Scatter plot of Price vs. Day of Year" src="../../../../translated_images/th/pie-pumpkins-scatter.d14f9804a53f927e.webp" width="50%" />
ถ้าเราคำนวณค่าความสัมพันธ์ระหว่าง `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")
> 🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอสั้นเกี่ยวกับการถดถอยเชิงเส้นและพหุนาม
เพื่อฝึกโมเดลการถดถอยเชิงเส้นของเรา เราจะใช้ไลบรารี **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 เข้าใจอย่างถูกต้อง โมเดลการถดถอยเชิงเส้นต้องการอาเรย์ 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% ไม่ดีมาก ตัวชี้วัดอีกอย่างของคุณภาพโมเดลคือ **coefficient of determination** ซึ่งสามารถหาค่าได้ดังนี้:
```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="../../../../translated_images/th/linear-results.f7c3552c85b0ed1c.webp" width="50%" />
## การถดถอยแบบพหุนาม
อีกประเภทหนึ่งของการถดถอยเชิงเส้นคือ การถดถอยแบบพหุนาม (Polynomial Regression) ในขณะที่บางครั้งมีความสัมพันธ์เชิงเส้นระหว่างตัวแปร — เช่น ลูกฟักทองที่มีปริมาตรมากกว่าจะมีราคาสูงกว่า — บางครั้งความสัมพันธ์เหล่านี้ไม่สามารถพล็อตเป็นระนาบหรือตรงได้
✅ นี่คือตัวอย่างเพิ่มเติมบางส่วน [some more examples](https://online.stat.psu.edu/stat501/lesson/9/9.8) ของข้อมูลที่สามารถใช้การถดถอยแบบพหุนามได้
ลองพิจารณาความสัมพันธ์ระหว่าง Date กับ Price อีกครั้ง กราฟกระจายนี้ดูเหมือนว่าควรจะวิเคราะห์ด้วยเส้นตรงเท่านั้นหรือไม่? ราคาสามารถผันผวนได้หรือไม่? ในกรณีนี้ คุณสามารถลองใช้การถดถอยแบบพหุนามได้
✅ พหุนามคือสมการทางคณิตศาสตร์ที่อาจประกอบด้วยตัวแปรและสัมประสิทธิ์หนึ่งตัวหรือมากกว่านั้น
การถดถอยแบบพหุนามสร้างเส้นโค้งเพื่อการฟิตข้อมูลที่ไม่เชิงเส้นได้ดีขึ้น สำหรับกรณีของเรา หากเราเพิ่มตัวแปรยกกำลังสองของ `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="../../../../translated_images/th/poly-results.ee587348f0f1f60b.webp" width="50%" />
การใช้การถดถอยแบบพหุนาม เราจะได้ค่า MSE ต่ำลงเล็กน้อยและค่า determination สูงขึ้นเล็กน้อยแต่ไม่มากนัก เราต้องพิจารณาคุณลักษณะอื่น ๆ ด้วย!
> คุณจะเห็นว่าราคาฟักทองต่ำสุดจะถูกสังเกตเห็นราว ๆ วันฮัลโลวีน คุณอธิบายสิ่งนี้ได้อย่างไร?
🎃 ยินดีด้วย คุณเพิ่งสร้างโมเดลที่ช่วยทำนายราคาของฟักทองทำพาย คุณน่าจะทำขั้นตอนนี้ซ้ำสำหรับฟักทองชนิดอื่น ๆ แต่จะยุ่งยาก มาเรียนรู้วิธีที่จะรวมชนิดฟักทองเข้ากับโมเดลของเรากัน!
## คุณลักษณะเชิงหมวดหมู่
ในโลกในอุดมคติ เราต้องการทำนายราคาในชนิดฟักทองต่าง ๆ โดยใช้โมเดลเดียวกัน อย่างไรก็ตาม คอลัมน์ `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")
> 🎥 คลิกที่ภาพด้านบนเพื่อชมวิดีโอสั้น ๆ เรื่องการใช้คุณลักษณะเชิงหมวดหมู่
นี่แสดงให้เห็นว่าราคาเฉลี่ยขึ้นอยู่กับชนิดฟักทองอย่างไร:
<img alt="Average price by variety" src="../../../../translated_images/th/price-by-variety.744a2f9925d9bcb4.webp" width="50%" />
เพื่อพิจารณาชนิดฟักทอง เราต้องแปลงเป็นตัวเลขหรือ **เข้ารหัส (encode)** ก่อน มีวิธีทำได้หลายวิธี:
* **การเข้ารหัสเชิงตัวเลขแบบง่าย** คือการสร้างตารางของชนิดที่แตกต่างกัน จากนั้นแทนที่ชื่อชนิดด้วยดัชนีในตารางนั้น วิธีนี้ไม่เหมาะสำหรับการถดถอยเชิงเส้นเพราะการถดถอยเชิงเส้นจะใช้ค่าตัวเลขจริงของดัชนีและเพิ่มเข้าไปในผลลัพธ์โดยคูณด้วยค่าสัมประสิทธิ์ ในกรณีของเรา ความสัมพันธ์ระหว่างหมายเลขดัชนีกับราคาชัดเจนว่าไม่เป็นเชิงเส้น แม้เราจะจัดเรียงดัชนีอย่างเป็นระบบ
* **การเข้ารหัสแบบ 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 encoded เป็นข้อมูลเข้า เราเพียงแค่ตั้งค่า `X` และ `y` ให้ถูกต้อง:
```python
X = pd.get_dummies(new_pumpkins['Variety'])
y = new_pumpkins['Price']
```
โค้ดที่เหลือเหมือนกับที่เราใช้เทรน Linear Regression ด้านบน หากคุณลองดูจะเห็นว่า mean squared error เท่ากันประมาณเดิมแต่เราได้ coefficient of determination สูงขึ้นมาก (~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%) และ coefficient of determination 0.94!
## รวมทุกอย่างเข้าด้วยกัน
เพื่อทำโมเดลที่ดีที่สุด เราสามารถใช้ข้อมูลรวมกัน (เชิงหมวดหมู่ one-hot encoded + ตัวเลข) จากตัวอย่างข้างต้นพร้อมกับการถดถอยแบบพหุนาม นี่คือโค้ดทั้งหมดเพื่อความสะดวกของคุณ:
```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
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)
```
สิ่งนี้ควรให้ค่าค่าสัมประสิทธิ์การกำหนด (determination coefficient) ที่ดีที่สุดเกือบ 97% และ MSE=2.23 (~8% ความผิดพลาดการทำนาย)
| Model | MSE | Determination |
|-------|-----|---------------|
| `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 |
🏆 เยี่ยมมาก! คุณสร้างโมเดล 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 DISCLAIMER START -->
**ข้อจำกัดความรับผิด**:
เอกสารฉบับนี้ได้รับการแปลโดยใช้บริการแปลภาษาอัตโนมัติ [Co-op Translator](https://github.com/Azure/co-op-translator) แม้ว่าเราจะพยายามให้ความถูกต้อง โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่แม่นยำ เอกสารต้นฉบับในภาษาต้นทางถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ แนะนำให้ใช้การแปลโดยผู้เชี่ยวชาญมืออาชีพ เราจะไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความที่ผิดพลาดที่อาจเกิดขึ้นจากการใช้การแปลนี้
<!-- CO-OP TRANSLATOR DISCLAIMER END -->