Machine Learning 100 Days - Day1

前言

最近誤打誤撞的,跑去參加了「機器學習 百日馬拉松」,裡面有許多蠻有趣的學習範例,引用了資料科學社群 Kaggle 的資料,囊括了許多數據挖掘、資料處理、統計分析等概念,後面再來一一分享我自己對於範例中 Sample Code 的理解,以及作業解題的思路,剛好對於我自己來說也是一種複習!

統計指標實作範例

剛開始的第一堂課 : 主要是針對機器學習的基礎開始並針對一些 Python 語法作說明,裡面會提到所謂評價函數 (Metric) 的概念,也就是機器學習的計分方式,範例中會展示平均絕對誤差 (MAE) 的寫法。

1
2
3
4
5
6
7
# import 是 Python 載入套件的基本語法 (類似 C 語言的 include),後面接要載入的套件
# import AAAAA as BB,其中 BB 是代稱,表示除了載入 AAAAA 之外,之後都可以用 BB 代替 AAAAA 這個名稱
# 常用套件往往有其對應代稱,numpy 的代稱是 np,pandas 的代稱是 pd,matplotlib.pyplot 的代稱是 plt
# numpy 常用於數值/陣列運算,pandas 擅長資料格式的調整,matplotlib 擅長繪圖
import numpy as np
import matplotlib.pyplot as plt
# plt.style.use(['dark_background']) # Dark Mode for plot

這裡稍微提一下關於 Dark Mode for plot 語法的用意,主要是因為我平時使用的 MacOS 及 IDE 介面為 Dark Mode,而一般 Plot 在作圖時所呈現的樣式為 Light Background,在 Dark Mode 中會非常突兀,所以我會使用 Dark Background 來改變它的樣式,大家可以依照自己的習慣來使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Python 的變數不需要宣告,可能是文字,數值,陣列,甚至是物件,對初學者來說這往往是最難接受的地方
# 主要是 Python 在大多數情況下,可以由運算"猜"出你想要的型態,我們由下列語法看看發生了什麼事吧
# w, b 是數值
w = 3
b = 0.5

# np.linspace 是 numpy.linspace 的意思
# np.linspace(0, 100, 101) 是指 0~100 劃分成 101 個刻度(含頭尾),所也就是 0, 1, 2,...,100 這 101 個數
# 這時候,x_lin 因為要記錄不只一個數,因為 np.linspace() 傳回的是一個 Array,所以 x_lin 就變成 Array 了
x_lin = np.linspace(0, 100, 101)

# np.random.randn() 就是 numpy.random.randn(),會隨機傳回標準常態分布的取樣值
# np.random.randn(101) 表示取樣了 101 次,型態是 Array, 所以其他 + 與 * 的部分都是 Array 的加與乘
# 一行就計算了 101 筆資料
# 所以最後的結果 y,也是一個長度 101 的 Array
y = (x_lin + np.random.randn(101) * 5) * w + b

# 這邊就是將 x_lin 以及剛剛算完的 y 當作座標值,將101個點在平面上畫出來
# b. 的 b 就是 blue,而 (.) 就是最小單位的形狀,詳細可以查 matplotlib 的官方說明
plt.plot(x_lin, y, 'b.', label = 'data points')
plt.title("Assume we have data points")
plt.legend(loc = 2) # legend 標籤說明的位置
plt.show()
1
2
3
4
5
6
7
8
# 這邊的 y_hat,就沒有隨機的部分了,也就是下圖中的紅色實線部分
y_hat = x_lin * w + b
plt.plot(x_lin, y, 'b.', label = 'data')
# 上面的 'b.' 是藍色點狀,下面的 'r-' 是紅色線狀,label 是圖示上的名稱
plt.plot(x_lin, y_hat, 'r-', label = 'prediction')
plt.title("Assume we have data points (And the prediction)")
plt.legend(loc = 2)
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Python 的函數是另一個新手上手的困難點,由 def 開頭, 依序是函數名稱 / 輸入值,冒號 (:) 結尾
# 最難讓人習慣的是 Python 的函式與條件判斷,前後都沒有大括弧(其他程式常見),而是以四格空白縮排來取代
# 以本例來說, mean_absolute_error 這個函數的定義範圍到 return mae 為止,因為中間都是縮排
# 而 """ 是多行註解(井號是單行註解)
# 函數中,sum(),abs(),len() 都是 Python 原有的方法,因此可以直接呼叫
def mean_absolute_error(y, yp):
"""
計算 MAE
Args:
- y: 實際值
- yp: 預測值
Return:
- mae: MAE
"""
# MAE : 將兩個陣列相減後,取絕對值 (abs),再將整個陣列加總成一個數字 (sum),最後除以 y 的長度 (len)
# 因此稱為"平均絕對誤差"
mae = MAE = sum(abs(y - yp)) / len(y)
return mae

# 呼叫上述函式,傳回 y (藍點高度)與 y_hat (紅線高度) 的 MAE
MAE = mean_absolute_error(y, y_hat)
print("The Mean absolute error is %.3f" % (MAE))
The Mean absolute error is 13.788

練習時間

請寫一個函式用來計算 Mean Square Error

$ MSE = \frac{1}{n}\sum_{i=1}^{n}{(Y_i - \hat{Y}_i)^2} $

Hint: 如何取平方

1
2
3
# 載入基礎套件與代稱
import numpy as np
import matplotlib.pyplot as plt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def mean_absolute_error(y, yp):
"""
計算 MAE
Args:
- y: 實際值
- yp: 預測值
Return:
- mae: MAE
"""
mae = MAE = sum(abs(y - yp)) / len(y)
return mae

# 定義 mean_squared_error 這個函數,計算並傳回 MSE
def mean_squared_error(y, yp):
"""
請完成這個 Function 後往下執行
"""
mse = MSE = sum((y - yp) ** 2) / len(y)
return mse
1
2
3
4
5
6
7
8
9
10
# 與範例相同,不另外解說
w = 3
b = 0.5
x_lin = np.linspace(0, 100, 101)
y = (x_lin + np.random.randn(101) * 5) * w + b

plt.plot(x_lin, y, 'b.', label = 'data points')
plt.title("Assume we have data points")
plt.legend(loc = 2)
plt.show()
1
2
3
4
5
6
7
# 與範例相同,不另外解說
y_hat = x_lin * w + b
plt.plot(x_lin, y, 'b.', label = 'data')
plt.plot(x_lin, y_hat, 'r-', label = 'prediction')
plt.title("Assume we have data points (And the prediction)")
plt.legend(loc = 2)
plt.show()
1
2
3
4
5
# 執行 Function,確認有沒有正常執行
MSE = mean_squared_error(y, y_hat)
MAE = mean_absolute_error(y, y_hat)
print("The Mean squared error is %.3f" % (MSE))
print("The Mean absolute error is %.3f" % (MAE))
The Mean squared error is 188.713
The Mean absolute error is 11.092