Python機器學習的練習二:多元線性迴歸
在第1部分中,我們用線性迴歸來預測新的食品交易的利潤,它基於城市的人口數量。對於第2部分,我們有了一個新任務——預測房子的售價。這次的不同之處在於我們有多個因變數。我們知道房子的大小,以及房子裡臥室的數量。我們嘗試擴充套件以前的程式碼來處理多元線性迴歸。
首先讓我們看一下資料。
path= os.getcwd()+ 'dataex1data2.txt'
data2= pd.read_csv(path, header=None, names=['Size','Bedrooms','Price'])
data2.head()
Size |
Bedrooms |
Price |
|
---|---|---|---|
0 |
2104 |
3 |
399900 |
1 |
1600 |
3 |
329900 |
2 |
2400 |
3 |
369000 |
3 |
1416 |
2 |
232000 |
4 |
3000 |
4 |
539900 |
每個變數值的大小都是不同的,一個房子大約有2-5個臥室,可能每個房間的大小都不一樣,如果我們在這個資料集上執行原來的迴歸演算法,那麼“size”影響的權重就太大了,就會降低“number of bedrooms”的影響,為了解決這個問題,我們需要做一些所謂的“特徵標準化”。也就是需要調整特徵的比例來平衡競爭關係。一種方法是用特徵的均值減去另一個特徵的均值,然後除以標準差。這是使用的pandas的程式碼。
data2= (data2- data2.mean())/ data2.std() data2.head()
Size |
Bedrooms |
Price |
|
---|---|---|---|
0 |
0.130010 |
-0.223675 |
0.475747 |
1 |
-0.504190 |
-0.223675 |
-0.084074 |
2 |
0.502476 |
-0.223675 |
0.228626 |
3 |
-0.735723 |
-1.537767 |
-0.867025 |
4 |
1.257476 |
1.090417 |
1.595389 |
接下來我們需要修改練習一中的線性迴歸的實現,以處理多個因變數。下面是梯度下降函式的程式碼。
def gradientDescent(X, y, theta, alpha, iters): temp= np.matrix(np.zeros(theta.shape)) parameters= int(theta.ravel().shape[1]) cost= np.zeros(iters) for iin range(iters): error= (X* theta.T)- y for jin range(parameters): term= np.multiply(error, X[:,j]) temp[0,j]= theta[0,j]- ((alpha/ len(X))* np.sum(term)) theta= temp cost[i]= computeCost(X, y, theta) return theta, cost
仔細觀察計算誤差項的程式碼行error = (X * theta.T) – y,我們會在矩陣運算中一直使用它。這是線性代數在工作中的力量:不管X中有多少變數(列),只要引數的個數是一致的,這個程式碼就能正常工作。類似地,只要y中的行數允許,它將計算X中每行的錯誤項。這是一種將ANY表示式一次性應用於大量例項的有效方法。
由於我們的梯度下降和成本函式都使用矩陣運算,所以處理多元線性迴歸所需的程式碼實際上沒有變化。我們來測試一下,首先通過初始化建立適當的矩陣來傳遞函式。
# 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)
theta2= np.matrix(np.array([0,0,0]))
現在執行,看會發生什麼
# perform linear regression on the data set
g2, cost2= gradientDescent(X2, y2, theta2, alpha, iters)
# get the cost (error) of the model
computeCost(X2, y2, g2)
0.13070336960771897
我們可以繪製訓練過程,確認實際誤差隨著每次迭代梯度下降而減少。
fig, ax= plt.subplots(figsize=(12,8))
ax.plot(np.arange(iters), cost2,'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
解決方案的成本或誤差隨著每個成功的迭代而下降,直到它觸底。這正是我們希望發生的事情。我們的演算法起作用了。
Python的偉大之處在於它的龐大的開發者社群和豐富的開源軟體。在機器學習領域,頂級Python庫是scikit-learn。讓我們看看如何使用scikit- learn的線性迴歸類來處理第一部分的簡單線性迴歸任務。
from sklearnimport linear_model
model= linear_model.LinearRegression()
model.fit(X, y)
沒有比這更簡單的了。“fit”方法有很多引數,我們可以根據我們想要的演算法來調整引數,預設值可以感測到遺留下來的問題。試著繪製擬合引數,和之前的結果比較。
x= np.array(X[:,1].A1)
f= model.predict(X).flatten()
fig, ax= plt.subplots(figsize=(12,8))
ax.plot(x, f,'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
我使用了“predict”函式預測的y值來繪製直線。這比手動操作要容易得多。scikit- learn有一個很好的API,它可以為典型的機器學習工作流程提供很多便利功能。
本文為編譯文章,作者John Wittenauer,原網址為
http://www.johnwittenauer.net/machine-learning-exercises-in-python-part-2/