# 多元線性迴歸（二）

``````import numpy as np
import matplotlib.pyplot as plt
import cv2
from sklearn.linear_model import LinearRegression

img = cv2.imread('data.jpg', cv2.IMREAD_GRAYSCALE)
idx = np.where(img < 127)       # 黑點的索引

data_x = idx[1]
data_y = -idx[0] + img.shape[0] # 反轉 y 軸

linreg = LinearRegression()    # 負責線性迴歸
# 擬合
linreg = linreg.fit(
data_x.reshape((data_x.size, 1)),  # 符合 fit 要求的形狀
data_y
)

plt.gca().set_aspect(1)
plt.scatter(data_x, data_y)

x = [0, 50]
y = linreg.predict([[0], [50]])  # 符合 predict 要求的形狀
plt.plot(x, y)

plt.show()
``````

`PolynomialFeatures` 正如其名，將原本的特徵，基於多項式的階數轉換為另一組特徵，例如，對於一元函式來說，fΘ(x) = Θ0 + Θ1 * x，它的特徵是 (1, x)，對於 fΘ(x) = Θ0 + Θ1 * x + Θ2 * x2，它的特徵會是 (1, x, x2)。

`PolynomialFeatures` 的階數預設為 2，可以借由 `degree` 指定，來看看實際計算特徵值的例子：

``````>>> from sklearn.preprocessing import PolynomialFeatures
>>> poly = PolynomialFeatures()
>>> poly.fit_transform([[1], [2], [3]])
array([[1., 1., 1.],
[1., 2., 4.],
[1., 3., 9.]])
>>>
``````

``````import numpy as np
import matplotlib.pyplot as plt
import cv2
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression

img = cv2.imread('data.jpg', cv2.IMREAD_GRAYSCALE)
idx = np.where(img < 127)       # 黑點的索引

data_x = idx[1]
data_y = -idx[0] + img.shape[0] # 反轉 y 軸

poly = PolynomialFeatures()     # 二次多項式
feature = poly.fit_transform(data_x.reshape([data_x.size, 1])) # 特徵值
linreg = LinearRegression()          # 線性迴歸
linreg = linreg.fit(feature, data_y) # 擬合

x = np.linspace(0, 50, 50)
y = linreg.predict(
# 記得是特徵值與縱軸的線性關係
poly.fit_transform(x.reshape((x.size, 1)))
)

plt.gca().set_aspect(1)
plt.scatter(data_x, data_y)
plt.plot(x, y)

plt.show()
``````

``````import numpy as np
import matplotlib.pyplot as plt
import cv2
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import make_pipeline

img = cv2.imread('data.jpg', cv2.IMREAD_GRAYSCALE)
idx = np.where(img < 127)       # 黑點的索引

data_x = idx[1]
data_y = -idx[0] + img.shape[0] # 反轉 y 軸

# 管線化
poly_model = make_pipeline(PolynomialFeatures(), LinearRegression())
poly_model.fit(data_x.reshape([data_x.size, 1]), data_y)

x = np.linspace(0, 50, 50)
y = poly_model.predict(x.reshape((x.size, 1)))

plt.gca().set_aspect(1)
plt.scatter(data_x, data_y)
plt.plot(x, y)

plt.show()
``````

``````import numpy as np
import matplotlib.pyplot as plt
import cv2
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression

img = cv2.imread('data.jpg', cv2.IMREAD_GRAYSCALE)
idx = np.where(img < 127)       # 黑點的索引

data_x = idx[1]
data_y = -idx[0] + img.shape[0] # 反轉 y 軸

poly = PolynomialFeatures()     # 二次多項式
feature = poly.fit_transform(data_x.reshape([data_x.size, 1])) # 特徵值
linreg = LinearRegression()          # 線性迴歸
linreg = linreg.fit(feature, data_y) # 擬合

derived_x = poly.fit_transform(data_x.reshape((data_x.size, 1)))

ax = plt.axes(projection='3d')

ax.scatter(data_x, data_y, np.zeros(len(data_x)))
ax.scatter(derived_x[:,1], derived_x[:,2], data_y)

plt.show()
``````

`PolynomialFeatures` 可以套用至多元多次，例如二元（兩個變數 x1、x2）二次的話，特徵值的計算會是 （1, x1, x2, x12, x1 * x2, x22），如果給定一組變數值，也可以透過可以求得 `PolynomialFeatures` 對應的特徵值：

``````>>> from sklearn.preprocessing import PolynomialFeatures
>>> poly = PolynomialFeatures()
>>> poly.fit_transform([[1, 2], [3, 4], [5, 6]])
array([[ 1.,  1.,  2.,  1.,  2.,  4.],
[ 1.,  3.,  4.,  9., 12., 16.],
[ 1.,  5.,  6., 25., 30., 36.]])
>>>
``````