#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
使用Pipeline进行多项式回归
"""

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(666)
x = np.random.uniform(-3, 3, size=100)
y = 0.5 + x**2 + 2 + np.random.normal(0,1, size=100)

plt.scatter(x,y)
plt.show()


"""线性回归"""
from sklearn.linear_model import LinearRegression

X = x.reshape(-1,1)
lin_reg = LinearRegression()   # 线性回归
lin_reg.fit(X,y)
y_predict = lin_reg.predict(X)

lin_reg.score(X, y)   # r2只有0.003205

plt.scatter(x,y)   # 绘图观察拟合情况
plt.plot(x, y_predict, color="r")
plt.show()


"""多项式回归"""
X2 = np.hstack([X, X**2])   # 构成自变量的多项式

lin_reg2 = LinearRegression()   # 多项式回归
lin_reg2.fit(X2, y)
y_predict2 = lin_reg2.predict(X2)

lin_reg2.score(X2, y)   #多项式回归的r2，0.87749

plt.scatter(x,y)   # 绘图观察拟合情况
plt.plot(np.sort(x), y_predict2[np.argsort(x)], color="r")
plt.show()

lin_reg2.coef_   # 输出array([0.00211316, 1.00409402])
lin_reg2.intercept_     # 输出2.5153101519246723


"""sklearn的多项式回归"""
from sklearn.preprocessing import PolynomialFeatures

poly = PolynomialFeatures(degree = 2)   # degree即为多项式的幂次数
poly.fit(X)
X3 = poly.transform(X)   # X的多项式转换

X3.shape   # 多项式矩阵的形状
X3[0:5,:]   # 多项式的前5行

lin_reg3 = LinearRegression()
lin_reg3.fit(X3, y)
y_predict3 = lin_reg3.predict(X3)

lin_reg3.score(X3, y)   # 同lin_reg2
lin_reg3.coef_   
lin_reg3.intercept_ 


"""多元多项式回归"""
x4 = np.arange(1, 11).reshape(5,2)
poly = PolynomialFeatures()
poly.fit(x4)
X4 = poly.transform(x4)

X4.shape   # 形状从(5,2)变成了(5，6)
X4[0:5,:]


"""多项式回归和pipeline"""
from sklearn.pipeline import Pipeline   # 相当于一个操作程序器，将每一步操作放到“管道”里，顺序进行
from sklearn.preprocessing import StandardScaler

poly_reg = Pipeline([   # 构建“管道”，管道里面的每一步操作即为一个元素，用元组形式记录，包括步骤名和相应的实例化代码
        ('poly', PolynomialFeatures(degree = 2)),   # 第一步，构建多项式
        ('std_scale', StandardScaler()),   # 第二步，数据标准化
        ('lin_reg', LinearRegression())   # 第三步，线性回归
        ])

poly_reg.fit(X, y)
y_poly_predict = poly_reg.predict(X)

poly_reg.score(X, y)   # 输出0.8706874835672862
poly_reg['lin_reg'].coef_   # 输出array([0.        , 0.00384725, 2.8055392 ])
poly_reg['lin_reg'].intercept_   # 输出5.8457007621551496

plt.scatter(x,y)   # 绘图观察拟合情况
plt.plot(np.sort(x), y_poly_predict[np.argsort(x)], color="r")
plt.show()


