用Python實現機器學習演算法:線性回歸
在 Kaggle 最新發布的全球數據科學/機器學習現狀報告中,來自 50 多個國家的 16000 多位從業者紛紛向新手們推薦 Python 語言,用以學習機器學習。
那麼,用Python實現出來的機器學習演算法都是什麼樣子呢? 東南大學研究生「Lawlite」在GitHub 上發布了一個項目——機器學習演算法的Python實現,下面從線性回歸到反向傳播演算法、從SVM到K-means聚類演算法,咱們一一來分析其中的Python代碼。
線性回歸
https://github.com/lawlite19/MachineLearning_Python/tree/master/LinearRegression
全部代碼
https://github.com/lawlite19/MachineLearning_Python/blob/master/LinearRegression/LinearRegression.py
代價函數
其中:
下面就是要求出theta,使代價最小,即代表我們擬合出來的方程距離真實值最近
共有m條數據,其中
代表我們要擬合出來的方程到真實值距離的平方,平方的原因是因為可能有負值,正負可能會抵消
前面有係數2的原因是下面求梯度是對每個變數求偏導,2可以消去
實現代碼:
# 計算代價函數
def computerCost(X,y,theta):
m = len(y) J = 0 J = (np.transpose(X*theta-y))*(X*theta-y)/(2*m) #計算代價J return J
注意這裡的X是真實數據前加了一列1,因為有theta(0)
梯度下降演算法
代價函數對
求偏導得到:
所以對theta的更新可以寫為:
其中
為學習速率,控制梯度下降的速度,一般取0.01,0.03,0.1,0.3.....
為什麼梯度下降可以逐步減小代價函數?
假設函數f(x),泰勒展開:f(x+△x)=f(x)+f(x)*△x+o(△x),
令:△x=-α*f(x) ,即負梯度方向乘以一個很小的步長α
將△x代入泰勒展開式中:f(x+x)=f(x)-α*[f(x)]2+o(△x)
可以看出,α是取得很小的正數,[f(x)]2也是正數,所以可以得出:f(x+△x)<=f(x)
所以沿著負梯度放下,函數在減小,多維情況一樣。
# 梯度下降演算法
def gradientDescent(X,y,theta,alpha,num_iters): m = len(y) n = len(theta) temp = np.matrix(np.zeros((n,num_iters))) # 暫存每次迭代計算的theta,轉化為矩陣形式 J_history = np.zeros((num_iters,1)) #記錄每次迭代計算的代價值 for i in range(num_iters): # 遍歷迭代次數 h = np.dot(X,theta) # 計算內積,matrix可以直接乘 temp[:,i] = theta - ((alpha/m)*(np.dot(np.transpose(X),h-y))) #梯度的計算theta = temp[:,i]
J_history[i] = computerCost(X,y,theta) #調用計算代價函數 print ., return theta,J_history
均值歸一化
目的是使數據都縮放到一個範圍內,便於使用梯度下降演算法
,其中
為所有此feture數據的平均值;
可以是最大值-最小值,也可以是這個feature對應的數據的標準差
實現代碼:
# 歸一化feature
def featureNormaliza(X): X_norm = np.array(X) #將X轉化為numpy數組對象,才可以進行矩陣的運算 #定義所需變數 mu = np.zeros((1,X.shape[1])) sigma = np.zeros((1,X.shape[1])) mu = np.mean(X_norm,0) # 求每一列的平均值(0指定為列,1代表行) sigma = np.std(X_norm,0) # 求每一列的標準差for i in range(X.shape[1]): # 遍歷列
X_norm[:,i] = (X_norm[:,i]-mu[i])/sigma[i] # 歸一化 return X_norm,mu,sigma
注意預測的時候也需要均值歸一化數據
最終運行結果
代價隨迭代次數的變化
使用scikit-learn庫中的線性模型實現
https://github.com/lawlite19/MachineLearning_Python/blob/master/LinearRegression/LinearRegression_scikit-learn.py
導入包
from sklearn import linear_model
from sklearn.preprocessing import StandardScaler #引入縮放的包
歸一化
# 歸一化操作
scaler = StandardScaler() scaler.fit(X) x_train = scaler.transform(X) x_test = scaler.transform(np.array([1650,3]))
線性模型擬合
# 線性模型擬合
model = linear_model.LinearRegression() model.fit(x_train, y)
預測
#預測結果
result = model.predict(x_test)
(未完待續)
推薦閱讀:
※DeepLearning筆記:梯度下降 Gradient Descent
※機器學習各優化演算法的簡單總結
※為什麼梯度下降演算法(BGD批量梯度下降)用的是所有樣本點梯度的均值作為最終的梯度方向?
※梯度下降、隨機梯度下降(SGD)、mini-batch SGD
※隨機梯度下降和正則項之間如何處理?