【机器学习】线性回归代码练习
本課程是中國大學慕課《機器學習》的“線性回歸”章節的課后代碼。
課程地址:
https://www.icourse163.org/course/WZU-1464096179
課程完整代碼:
https://github.com/fengdu78/WZU-machine-learning-course
代碼修改并注釋:黃海廣,haiguang2000@wzu.edu.cn
單變量線性回歸
import?numpy?as?np import?pandas?as?pd import?matplotlib.pyplot?as?pltimport?matplotlib.pyplot?as?plt plt.rcParams['font.sans-serif']=['SimHei']?#用來正常顯示中文標簽 plt.rcParams['axes.unicode_minus']=False?#用來正常顯示負號path?=?'data/regress_data1.csv' data?=?pd.read_csv(path) data.head()| 6.1101 | 17.5920 |
| 5.5277 | 9.1302 |
| 8.5186 | 13.6620 |
| 7.0032 | 11.8540 |
| 5.8598 | 6.8233 |
| 97.000000 | 97.000000 |
| 8.159800 | 5.839135 |
| 3.869884 | 5.510262 |
| 5.026900 | -2.680700 |
| 5.707700 | 1.986900 |
| 6.589400 | 4.562300 |
| 8.578100 | 7.046700 |
| 22.203000 | 24.147000 |
看下數據長什么樣子
data.plot(kind='scatter',?x='人口',?y='收益',?figsize=(12,8)) plt.xlabel('人口',?fontsize=18) plt.ylabel('收益',?rotation=0,?fontsize=18) plt.show()現在讓我們使用梯度下降來實現線性回歸,以最小化代價函數。
首先,我們將創建一個以參數為特征函數的代價函數
其中:
def?computeCost(X,?y,?w):inner?=?np.power(((X?*?w.T)?-?y),?2)#?(m,n)?@?(n,?1)?->?(n,?1) #?????return?np.sum(inner)?/?(2?*?len(X))return?np.sum(inner)?/?(2?*?X.shape[0])讓我們在訓練集中添加一列,以便我們可以使用向量化的解決方案來計算代價和梯度。
data.insert(0,?'Ones',?1) data| 1 | 6.1101 | 17.59200 |
| 1 | 5.5277 | 9.13020 |
| 1 | 8.5186 | 13.66200 |
| 1 | 7.0032 | 11.85400 |
| 1 | 5.8598 | 6.82330 |
| ... | ... | ... |
| 1 | 5.8707 | 7.20290 |
| 1 | 5.3054 | 1.98690 |
| 1 | 8.2934 | 0.14454 |
| 1 | 13.3940 | 9.05510 |
| 1 | 5.4369 | 0.61705 |
97 rows × 3 columns
現在我們來做一些變量初始化。
#?set?X?(training?data)?and?y?(target?variable) cols?=?data.shape[1] X?=?data.iloc[:,:cols-1]#X是所有行,去掉最后一列 y?=?data.iloc[:,cols-1:]#X是所有行,最后一列觀察下 X (訓練集) and y (目標變量)是否正確.
X.head()#head()是觀察前5行| 1 | 6.1101 |
| 1 | 5.5277 |
| 1 | 8.5186 |
| 1 | 7.0032 |
| 1 | 5.8598 |
| 17.5920 |
| 9.1302 |
| 13.6620 |
| 11.8540 |
| 6.8233 |
代價函數是應該是numpy矩陣,所以我們需要轉換X和Y,然后才能使用它們。我們還需要初始化w。
X?=?np.matrix(X.values) y?=?np.matrix(y.values) w?=?np.matrix(np.array([0,0]))w 是一個(1,2)矩陣
wmatrix([[0, 0]])看下維度
X.shape,?w.shape,?y.shape((97, 2), (1, 2), (97, 1))計算代價函數 (theta初始值為0).
computeCost(X,?y,?w)32.072733877455676Batch Gradient Decent(批量梯度下降)
def?batch_gradientDescent(X,?y,?w,?alpha,?iters):temp?=?np.matrix(np.zeros(w.shape))parameters?=?int(w.ravel().shape[1])cost?=?np.zeros(iters)for?i?in?range(iters):error?=?(X?*?w.T)?-?yfor?j?in?range(parameters):term?=?np.multiply(error,?X[:,?j])temp[0,?j]?=?w[0,?j]?-?((alpha?/?len(X))?*?np.sum(term))w?=?tempcost[i]?=?computeCost(X,?y,?w)return?w,?cost初始化一些附加變量 - 學習速率α和要執行的迭代次數。
alpha?=?0.01 iters?=?1000現在讓我們運行梯度下降算法來將我們的參數θ適合于訓練集。
g,?cost?=?batch_gradientDescent(X,?y,?w,?alpha,?iters) gmatrix([[-3.24140214, 1.1272942 ]])最后,我們可以使用我們擬合的參數計算訓練模型的代價函數(誤差)。
computeCost(X,?y,?g)4.515955503078912現在我們來繪制線性模型以及數據,直觀地看出它的擬合。
x?=?np.linspace(data['人口'].min(),?data['人口'].max(),?100) f?=?g[0,?0]?+?(g[0,?1]?*?x)fig,?ax?=?plt.subplots(figsize=(12,?8)) ax.plot(x,?f,?'r',?label='預測值') ax.scatter(data['人口'],?data['收益'],?label='訓練數據') ax.legend(loc=2) ax.set_xlabel('人口',?fontsize=18) ax.set_ylabel('收益',?rotation=0,?fontsize=18) ax.set_title('預測收益和人口規模',?fontsize=18) plt.show()由于梯度方程式函數也在每個訓練迭代中輸出一個代價的向量,所以我們也可以繪制。請注意,代價總是降低 - 這是凸優化問題的一個例子。
多變量線性回歸
練習還包括一個房屋價格數據集,其中有2個變量(房子的大小,臥室的數量)和目標(房子的價格)。我們使用我們已經應用的技術來分析數據集。
path?=?'data/regress_data2.csv' data2?=?pd.read_csv(path) data2.head()| 2104 | 3 | 399900 |
| 1600 | 3 | 329900 |
| 2400 | 3 | 369000 |
| 1416 | 2 | 232000 |
| 3000 | 4 | 539900 |
對于此任務,我們添加了另一個預處理步驟 - 特征歸一化。這個對于pandas來說很簡單
data2?=?(data2?-?data2.mean())?/?data2.std() data2.head()| 0.130010 | -0.223675 | 0.475747 |
| -0.504190 | -0.223675 | -0.084074 |
| 0.502476 | -0.223675 | 0.228626 |
| -0.735723 | -1.537767 | -0.867025 |
| 1.257476 | 1.090417 | 1.595389 |
現在我們重復第1部分的預處理步驟,并對新數據集運行線性回歸程序。
#?add?ones?column data2.insert(0,?'Ones',?1)#?set?X?(training?data)?and?y?(target?variable) cols?=?data2.shape[1] X2?=?data2.iloc[:,0:cols-1] y2?=?data2.iloc[:,cols-1:cols]#?convert?to?matrices?and?initialize?theta X2?=?np.matrix(X2.values) y2?=?np.matrix(y2.values) w2?=?np.matrix(np.array([0,0,0]))#?perform?linear?regression?on?the?data?set g2,?cost2?=?batch_gradientDescent(X2,?y2,?w2,?alpha,?iters)#?get?the?cost?(error)?of?the?model computeCost(X2,?y2,?g2)0.13070336960771892我們也可以快速查看這一個的訓練進程。
fig,?ax?=?plt.subplots(figsize=(12,8)) ax.plot(np.arange(iters),?cost2,?'r') ax.set_xlabel('迭代次數',?fontsize=18) ax.set_ylabel('代價',?rotation=0,?fontsize=18) ax.set_title('誤差和訓練Epoch數',?fontsize=18) plt.show()我們也可以使用scikit-learn的線性回歸函數,而不是從頭開始實現這些算法。我們將scikit-learn的線性回歸算法應用于第1部分的數據,并看看它的表現。
scikit-learn model的預測表現
x?=?np.array(X[:,?1].A1) f?=?model.predict(X).flatten()fig,?ax?=?plt.subplots(figsize=(12,?8)) ax.plot(x,?f,?'r',?label='預測值') ax.scatter(data['人口'],?data['收益'],?label='訓練數據') ax.legend(loc=2,?fontsize=18) ax.set_xlabel('人口',?fontsize=18) ax.set_ylabel('收益',?rotation=0,?fontsize=18) ax.set_title('預測收益和人口規模',?fontsize=18) plt.show()正則化
,此時稱作Ridge Regression:
from?sklearn.linear_model?import?Ridge model?=?Ridge() model.fit(X,?y)Ridge()x2?=?np.array(X[:,?1].A1) f2?=?model.predict(X).flatten()fig,?ax?=?plt.subplots(figsize=(12,?8)) ax.plot(x2,?f2,?'r',?label='預測值Ridge') ax.scatter(data['人口'],?data['收益'],?label='訓練數據') ax.legend(loc=2,?fontsize=18) ax.set_xlabel('人口',?fontsize=18) ax.set_ylabel('收益',?rotation=0,?fontsize=18) ax.set_title('預測收益和人口規模',?fontsize=18) plt.show()正則化:
,此時稱作Lasso Regression
from?sklearn.linear_model?import?Lasso model?=?Lasso() model.fit(X,?y)Lasso()x3=?np.array(X[:,?1].A1) f3?=?model.predict(X).flatten()fig,?ax?=?plt.subplots(figsize=(12,?8)) ax.plot(x3,?f3,?'r',?label='預測值Lasso') ax.scatter(data['人口'],?data['收益'],?label='訓練數據') ax.legend(loc=2,?fontsize=18) ax.set_xlabel('人口',?fontsize=18) ax.set_ylabel('收益',?rotation=0,?fontsize=18) ax.set_title('預測收益和人口規模',?fontsize=18) plt.show()調參
from?sklearn.model_selection?import?cross_val_score
alphas?=?np.logspace(-3,?2,?50)
test_scores?=?[]
for?alpha?in?alphas:clf?=?Ridge(alpha)test_score?=?np.sqrt(-cross_val_score(clf,?X,?y,?cv=5,?scoring='neg_mean_squared_error'))test_scores.append(np.mean(test_score))import?matplotlib.pyplot?as?plt
plt.plot(alphas,?test_scores)
plt.title("Alpha?vs?CV?Error");
plt.show()最小二乘法(LSM):
最小二乘法的需要求解最優參數:
已知:目標函數
其中:
將向量表達形式轉為矩陣表達形式,則有 ,其中為行列的矩陣(為樣本個數,為特征個數),為行1列的矩陣(包含了),為行1列的矩陣,則可以求得最優參數
梯度下降與最小二乘法的比較:
梯度下降:需要選擇學習率,需要多次迭代,當特征數量大時也能較好適用,適用于各種類型的模型
最小二乘法:不需要選擇學習率,一次計算得出,需要計算,如果特征數量較大則運算代價大,因為矩陣逆的計算時間復雜度為,通常來說當小于10000 時還是可以接受的,只適用于線性模型,不適合邏輯回歸模型等其他模型
def?LSM(X,?y):w?=?np.linalg.inv(X.T@X)@X.T@y#X.T@X等價于X.T.dot(X)return?wfinal_w2=LSM(X,?y)#感覺和批量梯度下降的theta的值有點差距 final_w2matrix([[-3.89578088],[ 1.19303364]])#梯度下降得到的結果是matrix([[-3.24140214,??1.1272942?]])參考
機器學習,吳恩達
《統計學習方法》,李航
總結
以上是生活随笔為你收集整理的【机器学习】线性回归代码练习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PP视频怎么设置可以运行多个客户端
- 下一篇: Android平台RTMP/RTSP播放