我們認真的來做一下數據分析!
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 5, 50)
y = 1.2*x + 0.8
畫出圖形來。
plt.scatter(x,y)
plt.plot(x, 1.2*x+0.8, 'r')
[<matplotlib.lines.Line2D at 0x10abf4160>]
大概的想法就是, 我們真實世界的問題, 化成函數, 我們假設背後有個美好的函數。但相信我們很少看到真實世界的資料那麼漂亮。在統計上, 我們就是假設
$$f(x) + \varepsilon(x)$$也就是都有個 noise 項。
y = 1.2*x + 0.8 + 0.6*np.random.randn(50)
plt.scatter(x,y)
plt.plot(x, 1.2*x + 0.8, 'r')
[<matplotlib.lines.Line2D at 0x10abf40b8>]
做線性迴歸有很多套件, 但我們這裡用 sklearn
裡的 LinearRegression
來做, 嗯, 線性迴歸。
from sklearn.linear_model import LinearRegression
regr = LinearRegression()
這裡要注意我們本來的 x 是
$$[x_1, x_2, \ldots, x_{50}]$$但現在要的是
$$[[x_1], [x_2], \ldots, [x_{50}]]$$這樣的。
X = x.reshape(len(x),1)
regr.fit(X,y)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
Y = regr.predict(X)
plt.scatter(x, y)
plt.plot(x, Y, 'r')
[<matplotlib.lines.Line2D at 0x10e0e1e48>]
from sklearn.model_selection import train_test_split
把原來的 x
, y
中的 80% 給 training data, 20% 給 testing data。
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=1)
我們在「訓練」這個函數時只有以下這些資料。
plt.scatter(x_train, y_train)
<matplotlib.collections.PathCollection at 0x10e23a0b8>
記得現在我們只用 80% 的資料去訓練。
regr = LinearRegression()
X_train = x_train.reshape(len(x_train),1)
regr.fit(X_train,y_train)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
Y_train = regr.predict(X_train)
plt.scatter(x_train, y_train)
plt.plot(x_train, Y_train, 'r')
[<matplotlib.lines.Line2D at 0x10e24aef0>]
X_test = x_test.reshape(len(x_test),1)
Y_test = regr.predict(X_test)
mse = np.sum((Y_test-y_test)**2) / len(y_test)
mse
0.22741540119787182
plt.scatter(x_test, y_test)
plt.scatter(x_test, Y_test, c='r')
<matplotlib.collections.PathCollection at 0x10e476be0>
x = np.linspace(0, 5, 50)
y = np.sin(3.2*x) + 0.8*x + 0.3*np.random.randn(50)
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x10e50e4a8>]
regr_lin = LinearRegression()
X = x.reshape(len(x), 1)
regr_lin.fit(X,y)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
plt.scatter(x,y)
plt.plot(x, regr_lin.predict(X), 'r')
[<matplotlib.lines.Line2D at 0x10e7150f0>]
果然超級不準, 該如何是好?
我們來用 6 次多項式學
X_poly = np.array([[k, k**2, k**3, k**4, k**5, k**6] for k in x])
regr_poly = LinearRegression()
regr_poly.fit(X_poly, y)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
plt.scatter(x,y)
plt.plot(x, regr_poly.predict(X_poly), 'r')
[<matplotlib.lines.Line2D at 0x10e7107f0>]
def RBF(x, center, sigma):
k = np.exp(-(x - center)**2/(2*sigma**2))
return k
sigma = 0.3
X_rbf = np.array([[RBF(k, 0.5, sigma),
RBF(k, 1.5, sigma),
RBF(k, 2.5, sigma),
RBF(k, 3.5, sigma),
RBF(k, 4.5, sigma)] for k in x])
regr_rbf = LinearRegression()
regr_rbf.fit(X_rbf, y)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
plt.scatter(x,y)
plt.plot(x, regr_rbf.predict(X_rbf), 'r')
[<matplotlib.lines.Line2D at 0x10e8440b8>]
Y_lin = regr_lin.predict(X)
Y_poly = regr_poly.predict(X_poly)
Y_rbf = regr_rbf.predict(X_rbf)
plt.scatter(x,y)
plt.plot(x, Y_lin, label='linear')
plt.plot(x, Y_poly, label='polynomial')
plt.plot(x, Y_rbf, label='rbf')
plt.legend()
<matplotlib.legend.Legend at 0x10eb520b8>