機器學習基礎:線性回歸

本文旨在通過介紹線性回歸來引出一些基本概念:h(x),J(θ),梯度下降法,並使用tensorflow實現一個簡單的線性回歸例子

在生活中,我們經常會碰到這樣的問題:

通過過往房屋面積與總價的關係,來估測一幢房屋的價格

這種答案只有是和否的問題(y=0 or 1),被稱為線性回歸

有一組數據:

x=[1,2,3,4,5,6,7,8,9,10]

y=[1,2,3,4,5,6,7,8,9,10]

要求畫一條過原點的直線,穿過上述所有點

這組數據在二維平面表現如下

引入概念,假設函數:h(x)。h代表hypothesis

由於是過原點的直線,所以可以列出方程h(x):

先隨意假設一個 	heta_{1} ,在這先假設 	heta_{1}=0.5 ,函數圖如下

顯而易見這條直線並不是我們想要的。那麼具體的,怎麼判斷一條直線的好壞呢

引入概念代價函數 cost function

在本例中,可以由擬合數據和原始數據對應點的誤差的平方的均值來判斷直線的好壞;列出J(θ)如下:

其中m表示數據的總量,在本題中為10; x^{(i)} 並不是代表x的i次方,而是代表第i個x的數值,例如在本例中, x^{(2)} 為2

將h(x)帶入,得

函數圖是這樣一個形狀,數值對不上,湊合著看吧;有一點值得注意,在J(θ)中, x^{(i)}y^{(i)} 都應該作為常量來處理

顯然,J(θ)值越小,點到直線的距離總和越少,畫出來的直線效果也就越好。放到題目中就是當J(θ)=0的時候,畫出的直線穿過了所有的點

那麼問題就變成了如何最小化J(θ)

在這個例子中可以手動計算,也就是正規方程法,但是隨著問題複雜度的增加,正規方程法的實用性會越來越低

引入梯度下降法

其中α為步幅

梯度下降法可以解釋為:對J(θ)求關於 	heta_{j} (本例中只有 	heta_{1} )的偏導數並乘以步幅,再用 	heta_{j} 減去該值,得到的結果賦值給 	heta_{j} 。此過程需要重複多次

步幅的選擇會直接關係到梯度下降法的效果,如下圖

當選取了一個較小步幅的時候,將正確收斂

當選取了一個較大步幅的時候,將震蕩收斂

當選取了一個過大步幅的時候,將無法收斂

調整一下例子

x=[5,6,7,8,9,10,11,12,13,14]

y=[1,2,3,4,5,6,7,8,9,10]

要求畫一條直線,穿過上述所有點

很明顯,對於這組數據,僅僅是過原點的直線無法滿足要求,所以列出新的h(x):

而判斷一條直線的好壞還可以沿用之前的J(θ):

函數圖是這樣一個形狀,數值對不上,湊合著看吧

之後就是如何最小化J(θ)的問題了。下面給出tensorflow的代碼實現

import tensorflow as tfimport numpy as npimport matplotlib.pyplot as plt# Parameterslearning_rate = 0.05training_epochs = 2000display_step = 50# Training Datatrain_X = np.asarray([5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0])train_Y = train_X - 4paint_X = np.asarray([-100.0, 100.0])n_samples = train_X.shape[0]# tf Graph InputX = tf.placeholder("float")Y = tf.placeholder("float")# Set model weightsW = tf.Variable(-10., name="weight")b = tf.Variable(10., name="bias")# Construct a linear modelpred = tf.add(tf.multiply(X, W), b)# Mean squared errorcost = tf.reduce_sum(tf.pow(pred - Y, 2)) / (2 * n_samples)# Gradient descentoptimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)# Initializing the variablesinit = tf.global_variables_initializer()# Launch the graphplt.figure()plt.ion()with tf.Session() as sess: sess.run(init) # Fit all training data for epoch in range(training_epochs): for (x, y) in zip(train_X, train_Y): sess.run(optimizer, feed_dict={X: x, Y: y}) # Display logs per epoch step if (epoch + 1) % display_step == 0: c = sess.run(cost, feed_dict={X: train_X, Y: train_Y}) print("Epoch:", "%04d" % (epoch + 1), "cost=", "{:.9f}".format(c), "W=", sess.run(W), "b=", sess.run(b)) plt.axis([0.0, np.max(train_X) + 1, 0.0, np.max(train_Y) + 1]) plt.plot(train_X, train_Y, "ro", label="Original data") plt.plot(paint_X, sess.run(W) * paint_X + sess.run(b), label="Fitted line") plt.pause(0.001) plt.clf() print("Optimization Finished!") training_cost = sess.run(cost, feed_dict={X: train_X, Y: train_Y}) print("Training cost=", training_cost, "W=", sess.run(W), "b=", sess.run(b), "
") plt.axis([0.0, np.max(train_X) + 1, 0.0, np.max(train_Y) + 1]) plt.plot(train_X, train_Y, "ro", label="Original data") plt.plot(paint_X, sess.run(W) * paint_X + sess.run(b), label="Fitted line") plt.pause(10)

推薦閱讀:

深度學習框架跑分測驗(TensorFlow/Caffe/MXNet/Keras/PyTorch)
深度卷積GAN之圖像生成
Docker--深度學習環境配置一站式解決方案
一個基於 TensorFlow 的「顏值評分」開源項目:FaceRank

TAG:机器学习 | TensorFlow |