天天看點

機器學習——多變量線性回歸

房價預測問題

這裡我們還是用房價預測的問題來舉例說明,你有一個房子需要轉賣,但不知道 能賣多少,需要進行預測,而對于房子能賣多少錢,能對這個結果産生影響的不單單是,房屋的面積了,房子的地理位置,房子的樓層數等都會對價格産生影響,這樣我們就需要使用多變量線性回歸來預測房價了

解決思路

1.這裡我們需要先去處理一下資料,先對模型的特性值進行特征縮放,為什麼要進行特征縮放呢,

第一點是可以幫助梯度下降更快的收斂

第二點是幫助每個模型找到合适的權重,不會對範圍較大的特征投入大量的精力

這裡的特征縮放我們用到的是标準化x=(x-μ)/σ 而他的系數μ代表的是平均值σ代表的是标準差

2.接下來我們需要去定義模型hθ(x)=θ0+θ1X+θ2X,因為矩陣的向量的性質我們可以把原式寫成hθ(x)=Xθ,這樣可以表示多個特征對結果的影響

3.模型定義好後需要看一下預測的值與實際值的差距,

這就用到了代價函數J(θ)=1/(2m) ∑ i = 1 m ( h ( x i ) − y i ) 2 \sum_{i=1}^m(h(x^i)-y^i)^2 ∑i=1m​(h(xi)−yi)2

4.計算完代價後就要開始梯度下降更新θ,為了控制梯度下将的的速度,我們可以加一個學習率α

這個過程我們可以類比自行車下坡,學習率過小時,θ更新的慢,就像是你下坡時踩着刹車一樣,

而學習率過大時,可能會越過最低點,導緻θ無法收斂,找不到最好的θ,這個就像是下坡時你還加速往下沖,就會導緻在臨近坡底時,速度過快控制不了這個速度。

5.最後在測一下這個模型的精度看一下這個模型的好壞(1-μ)v,系數μ代表預測值與實際值的方差

v代表真實值與平均值的方差

代碼展示

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 讀取資料
data = np.loadtxt(r'C:\Users\shy\PycharmProjects\untitled\week3\ex1data2.txt',delimiter=',')
# 資料提取
x = data[:,:-1]
y = data[:,-1]


# 資料預處理
def preProcess(x, y):
    # 進行特征縮放
    x -= np.mean(x,axis=0)
    x /= np.std(x,axis=0,ddof=1)
    # 資料初始化
    x = np.c_[np.ones(len(x)),x]
    print(x.shape)
    y = np.c_[y]
    return x,y


# 調用預處理函數
x,y = preProcess(x,y)
# 切分資料集(7:3)
m = len(x)
d = int(0.7*m)
train_x,text_x = np.split(x, [d])
train_y,text_y = np.split(y, [d])


# 定義模型
def model(x,theta):
    h = np.dot(x,theta)
    return h


# 定義代價函數
def costFunc(h, y):
    m = len(y)
    J = 1/(2*m)*np.sum(np.square(h-y))
    return J


# 定義梯度下降函數
def gradDesc(x,y,alpha = 0.01, iter_num=4000):
    m,n = x.shape
    print(m,n)
    theta = np.zeros((n,1))
    J_history = np.zeros(iter_num)

    for i in range(iter_num):
        h = model(x,theta)
        J_history[i] = costFunc(h,y)
        deltaTheta = 1.0/m*np.dot(x.T,h-y)
        theta -= alpha*deltaTheta
    return J_history,theta


# 求精度
def score(h,y):
    u = np.sum(np.square(h-y))
    v = np.sum(np.square(y-np.mean(y)))
    score = 1.0-u/v
    return score


# 訓練模型
J_history, theta = gradDesc(train_x,train_y)
# 求預測結果
train_h = model(train_x,theta)
text_h = model(text_x,theta)

# 求精度
score_train = score(train_h,train_y)
score_text = score(text_h,text_y)
print('訓練集精度:',score_train)
print('測試集精度:',score_text)

# 畫出代價函數
plt.title('代價函數')
plt.plot(J_history)
plt.show()

# 畫真實值和真實值的對比圖
plt.title('訓練集:真實值/預測值對比圖')
plt.scatter(train_y,train_y,label='真實值')
plt.scatter(train_y,train_h,label='預測值')
plt.legend()
plt.show()

# 畫真實值和預測值的對比圖
plt.title('測試集:真實值/預測值對比圖')
plt.scatter(text_y,text_y,label='真實值')
plt.scatter(text_y,text_h,label='預測值')
plt.legend()
plt.show()

           

效果展示

機器學習——多變量線性回歸
機器學習——多變量線性回歸
機器學習——多變量線性回歸

資料集

2104,3,399900
1600,3,329900
2400,3,369000
1416,2,232000
3000,4,539900
1985,4,299900
1534,3,314900
1427,3,198999
1380,3,212000
1494,3,242500
1940,4,239999
2000,3,347000
1890,3,329999
4478,5,699900
1268,3,259900
2300,4,449900
1320,2,299900
1236,3,199900
2609,4,499998
3031,4,599000
1767,3,252900
1888,2,255000
1604,3,242900
1962,4,259900
3890,3,573900
1100,3,249900
1458,3,464500
2526,3,469000
2200,3,475000
2637,3,299900
1839,2,349900
1000,1,169900
2040,4,314900
3137,3,579900
1811,4,285900
1437,3,249900
1239,3,229900
2132,4,345000
4215,4,549000
2162,4,287000
1664,2,368500
2238,3,329900
2567,4,314000
1200,3,299000
852,2,179900
1852,4,299900
1203,3,239500

           

這差不多就是多變量線性回歸的過程了

繼續閱讀