吳恩達機器學習 ex1 python實現

我的小鬼發表於2020-09-25

吳恩達機器學習 ex1 python實現

1 簡單練習

輸出一個5*5的單位陣

A=np.eye(5)
A
#結果:
array([[ 1.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  1.]])

2 單變數的線性迴歸

2.1 讀取資料、繪製散點圖

根據城市人口數量,預測開小吃店的利潤 資料在ex1data1.txt裡,第一列是城市人口數量,第二列是該城市小吃店利潤。
下面展示一些 內聯程式碼片

#讀取資料並展示
data = pd.read_csv(open('D:/ML/machine-learning-ex1/ex1/ex1data1.txt'),header = None,names=['Population','Profit'])
data.head()
Population	Profit
0	6.1101	17.5920
1	5.5277	9.1302
2	8.5186	13.6620
3	7.0032	11.8540
4	5.8598	6.8233
#繪製散點圖
data.plot(kind='scatter', x='Population',y='Profit',figsize=(6,4))
plt.show()

在這裡插入圖片描述

2.2 梯度下降

訓練線性迴歸引數θ

2.2.1 公式

代價函式:
在這裡插入圖片描述
假設函式:

2.2.2代價函式實現

#計算J(Ѳ),X是矩陣(一列為一個屬性),theta是一個列向量,轉置後為行向量
def computeCost(X,y,theta):
    inner = np.power((X*theta.T-y),2)
    return np.sum(inner)/(2*len(X))
#加入一列用於更新theta
data.insert(0,'Ones',1)

#初始化X、y
cols = data.shape[1] #cols為data列數
X = data.iloc[:,:-1] #X為data除最後一列
y = data.iloc[:,cols-1:cols] #y是data的最後一列

#代價函式使用的為numpy矩陣,所以轉換X,y,初始化theta
X = np.matrix(X)
y = np.matrix(y)
theta = np.matrix([0,0])

2.2.3梯度下降函式實現

實現theta的更新 記住J(θ)的變數是θ,而不是X和y,意思是說,我們變化θ的值來使J(θ)變化 檢查梯度下降是不是在正常運作的方式,是列印出每一步J()的值,看他是不是一直都在減小, 並且最後收斂至一個穩定的值。 最後的結果會用來預測小吃店在35000及70000人城市規模的利潤。

#求min J(θ),返回θ和min J(θ)
#alpha為學習率,iters為迭代次數
def gradientDescent(X, y, theta, alpha, iters):
    temp = np.matrix(np.zeros(theta.shape)) #為更新theta矩陣而定義的中間矩陣,形同theta
    parameters = int(theta.shape[1]) #theta陣列的維度
    cost = np.zeros(iters) #代價初始化 array([ 0.,  0.,  0., ...,  0.,  0.,  0.])
    
    for i in range(iters):  #迭代itear次更新theta
        error = (X * theta.T) - y  #對theta求偏導的一箇中間過程
        
        for j in range(parameters):
            term = np.multiply(error, X[:,j]) #np.multiply對應位置元素相乘
                                            #當j=0時,error*1;即J(θ)對theta0的偏導
                                            #當j=1時。error*X[:,1];即J(θ)對theta1的偏導
            temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term)) #更新theta
            
            theta = temp
            cost[i] = computeCost(X, y, theta)
            
    return theta,cost      
#預測35000和70000城市規模的小吃攤利潤
alpha = 0.01
iters = 1500
g,cost = gradientDescent(X, y, theta, alpha, iters)
print("g",g)

predict1 = [1,3.5]*g.T
print("predict1:",predict1)

predict2 = [1,7]*g.T
print("predict2:",predict2)
#繪製散點圖和預測直線
x = np.linspace(data.Population.min(),data.Population.max(),100)
f = g[0,0] + (g[0,1] * x)

fig, ax = plt.subplots(figsize=(6,4))
ax.plot(x,f,'r',label='Predicyion')
ax.scatter(data.Population,data.Profit,label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predict Profit vs. Population Size')
plt.show()
#結果:
g [[-3.63029144  1.16636235]]
predict1: [[ 0.45197679]]
predict2: [[ 4.53424501]]

在這裡插入圖片描述

三、多變數線性迴歸

ex1data2.txt裡的資料,第一列是房屋大小,第二列是臥室數量,第三列是房屋售價 根據已有資料,建立模型,預測房屋的售價

3.1 特徵歸一化

觀察資料發現,size變數是bedrooms變數的1000倍大小,統一量級會讓梯度下降收斂的更快。做法就是,將每類特徵減去他的平均值後除以標準差

data2 = pd.read_csv(open('D:/ML/machine-learning-ex1/ex1/ex1data2.txt'),header = None,names=['Size','Bedrooms','Price'])
data2 = (data2 - data2.mean())/data2.std()

3.2多元線性迴歸梯度下降的使用

#加入一列用於更新theta
data2.insert(0,'Ones',1)

#初始化x和y
cols = data2.shape[1]
X2 = data2.iloc[:,0:cols-1]
y2 = data2.iloc[:,cols-1:cols]

#轉換成matrix格式,初始化theta
X2 = np.matrix(X2.values)
y2 = np.matrix(y2.values)
theta2 = np.matrix([0,0,0])

#執行梯度下降演算法
g2 ,cost2 = gradientDescent(X2, y2, theta2, alpha, iters)
print("g2",g2)
#結果:
([[ -1.10856950e-16,   8.84042349e-01,  -5.24551809e-02]])

3.3正規方程

在這裡插入圖片描述
梯度下降與正規方程的比較:

梯度下降:需要選擇學習率α,需要多次迭代,當特徵數量n大時也能較好適用,適用於各種型別的模型

正規方程:不需要選擇學習率α,一次計算得出,需要計算image.png
如果特徵數量n較大則運算代價大,因為矩陣逆的計算時間複雜度為O(n3),通常來說當小於10000 時還是可以接受的,只適用於線性模型,不適合邏輯迴歸模型等其他模型.

# 正規方程
def normalEqn(X, y):
    theta = np.linalg.inv(X.T@X)@X.T@y#X.T@X等價於X.T.dot(X)
    return theta

final_theta2=normalEqn(X, y)#這裡用的是data1的資料
print("final_theta2:"final_theta2)
#結果:
([[-3.89578088],
        [ 1.19303364]])

感謝和鯨社群王大毛,以上是對她的程式碼的復現

資料來源史丹佛機器學習筆記

相關文章