iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
AI/ ML & Data

Web仔也來學ML系列 第 4

Web仔也來學ML [Day 4] - Regression(下)

  • 分享至 

  • xImage
  •  

在上一篇文章中,我們介紹了線性回歸(Linear Regression)的基本概念。接下來,我們將通過一個實際範例來演示線性回歸的應用。本範例使用 Python 的 sklearn 套件,數據來源為臺北市政府民政局提供的臺北市歷年出生及死亡人口數。選擇這組資料的原因主要是因為我無法找到更合適的公開數據,而本文重點在於展示機器學習的框架與算法,因此我希望能減少在數據預處理方面的工作量。

檢視資料

首先,我們將資料用表格和圖表的方式展示出來:

出生人數 死亡人數
57年 40,923 6,471
58年 41,667 6,365
59年 45,078 6,574
60年 43,542 6,769
61年 42,252 6,869
62年 41,998 7,005
63年 43,113 7,312
64年 41,710 7,333
65年 48,284 7,433
66年 43,229 7,977
67年 44,124 7,908
68年 45,978 8,149
69年 43,998 8,188
70年 44,019 8,548
71年 42,948 8,653
72年 40,917 8,945
73年 40,142 8,957
74年 38,984 9,198
75年 35,542 9,218
76年 36,799 9,740
77年 41,040 10,300
78年 38,343 10,296
79年 39,601 10,631
80年 36,538 10,614
81年 35,310 11,011
82年 34,374 11,025
83年 33,605 11,245
84年 34,763 11,809
85年 34,151 12,221
86年 35,062 12,359
87年 30,203 12,374
88年 31,812 12,669
89年 33,678 12,989
90年 26,998 13,337
91年 25,647 13,522
92年 23,311 13,777
93年 22,154 14,016
94年 20,962 14,516
95年 21,151 14,011
96年 21,620 14,871
97年 20,691 15,606
98年 19,403 15,260
99年 18,530 15,398
100年 25,132 15,988
101年 29,498 16,579
102年 26,710 16,379
103年 29,024 17,177
104年 28,987 17,106
105年 27,992 17,982
106年 25,042 17,467
107年 22,849 17,902
108年 21,468 18,026
109年 19,029 17,212
110年 16,695 18,623
111年 14,528 20,783
112年 16,027 20,357

這些數據展示了臺北市近幾十年的出生與死亡人數。我們假設出生人數和死亡人數之間可能存在某種關聯,因為每個人最終都會死亡,所以我們可以嘗試通過出生人數來預測死亡人數。然而,需要強調的是我們此次使用的模型可能不夠合理,具體的理由將在文章結尾進一步解釋。

首先,我們可以用程式生成圖表:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.font_manager import fontManager

fontManager.addfont('ChineseFont.ttf')
mpl.rc('font', family='ChineseFont')

census = pd.read_excel('born_and_death.xlsx')
x = census['出生人數']
y = census['死亡人數']

plt.title('臺北市出生與死亡人數')
plt.xlabel('出生(人)')
plt.xlim(12000, 50000)
plt.ylabel('死亡(人)')
plt.ylim(5000, 23000)
plt.scatter(x, y)
plt.show()

https://ithelp.ithome.com.tw/upload/images/20240916/20162542PqVxSBFSNy.png

分割資料

接下來,我們將數據分成訓練集和測試集,使用 sklearntrain_test_split 方法進行分割:

from sklearn.model_selection import train_test_split

# 分割Training Data和Testing Data
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=55)

在這裡,我們將數據分為訓練集(X_train, y_train)和測試集(X_test, y_test)。test_size=0.2 表示將整個數據集的20%作為測試數據,而 random_state 是為了固定隨機分割的結果,這樣可以讓他人復現你的結果。

模型訓練

使用 sklearn 的線性回歸模型進行訓練:

from sklearn.linear_model import LinearRegression

# 建立線性回歸模型
model = LinearRegression()

# 用分割出的Training Data訓練模型
model.fit(X_train, y_train)

模型預測

使用訓練好的模型進行預測:

# 進行預測
y_pred = model.predict(X_test)

評估模型

我們可以使用 MSE(均方誤差)來評估模型的效果:

from sklearn.metrics import mean_squared_error

# 評估模型
mse = mean_squared_error(y_test, y_pred)

成果展示

最後,我們將結果打印出來並畫出統計圖來展示成果:

# 視覺化
print('Mean Squared Error:', mse)
print('w', model.coef_[0])
print('b', model.intercept_)

plt.scatter(X_test, y_test, label='實際')
plt.plot(X_test, y_pred, color='red', label='預測')
plt.title('臺北市出生與死亡人數')
plt.xlabel('出生人數')
plt.ylabel('死亡人數')
plt.xlim(12000, 50000)
plt.ylim(5000, 23000)
plt.legend()
plt.show()

結果顯示:

  • Mean Squared Error: 1,575,190.041844703
  • w: -0.37729215695462853
  • b: 24,612.811200156662

https://ithelp.ithome.com.tw/upload/images/20240916/20162542E5iU1J9vmN.png

我們也可以嘗試去掉 random_state,將會得到不同的結果(因為資料的切割是隨機的):

  • Mean Squared Error: 1,201,404.311721069
  • w: -0.3942065341143934
  • b: 25,017.309383823005

https://ithelp.ithome.com.tw/upload/images/20240916/20162542EQH2f4m1gX.png

可以看到,這次的結果與上次不同。

附上完整程式碼,供參考:

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 讀取資料
census = pd.read_excel('born_and_death.xlsx')

# 特徵工程
X = census[['出生人數']]
y = census['死亡人數']

# 分割Training Data和Testing Data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=55)

# 建立線性迴歸模型(這邊就直接使用套件而不實作了)
model = LinearRegression()

# 用先前分割的Training Data訓練模型
model.fit(X_train, y_train)

# 進行預測
y_pred = model.predict(X_test)

# 評估模型好壞
mse = mean_squared_error(y_test, y_pred)

# 視覺化
print('Mean Squared Error:', mse)
print('w', model.coef_[0])
print('b', model.intercept_)

plt.scatter(X_test, y_test, label='實際')
plt.plot(X_test, y_pred, color='red', label='預測')
plt.title('臺北市出生與死亡人數')
plt.xlabel('出生人數')
plt.ylabel('死亡人數')
plt.xlim(12000, 50000)
plt.ylim(5000, 23000)
plt.legend()
plt.show()

結尾

在前文中提到,我們使用的模型可能不夠合理。這是因為一般人的平均壽命大約在70到80歲之間(內政部:111年國人平均壽命79.84歲),而我們的數據統計範圍為57年到112年,共55年,這些數據無法真實反映出生與死亡人數之間的關係。但這個實驗對於練習簡單的線性回歸仍然是有價值的。今天的文章就到這裡,期待下一篇文章的分享。


上一篇
Web仔也來學ML [Day 3] - Regression(上)
下一篇
Web仔也來學ML [Day 5] - 常見名詞解釋(一)
系列文
Web仔也來學ML30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言