== 多項式擴展 ==
上一章的最后我們提到:
訓(xùn)練集上表現(xiàn)得不好故黑,那么測試集上的效果肯定也不好儿咱,即
訓(xùn)練集上表現(xiàn)得好,測試集表現(xiàn)得不好场晶,即
如何解決本案例中遇到的欠擬合問題混埠?
1、增加數(shù)據(jù)集中的觀測值 (樣本數(shù)量)
2诗轻、增加數(shù)據(jù)的維度 (特征數(shù)量)
如果拿不到新數(shù)據(jù)的情況下(樣本數(shù)量不變)钳宪,只能通過增加數(shù)據(jù)維度的方法來解決欠擬合的問題,那用什么方式來增加維度呢扳炬?
本章我們討論“多項式擴展”的方法來解決上述問題吏颖。
1、二階多項式擴展
假設(shè)現(xiàn)在有兩個特征:x1恨樟、x2
我們做二階多項式擴展半醉,最終的結(jié)果是:
x1、x2劝术、x12缩多、x1x2 养晋、x22;
我們?nèi)藶榈迷跀?shù)據(jù)中增加了這些特征:x12绳泉、x1x2 、x22零酪;
比如新特征:x1x2(長*寬)=面積麦射。
思考:如果包含三個特征值灯谣,x1蛔琅、x2、x3罗售,他們的二階多項式擴展會以怎樣的形式展開?
x1x2寨躁、x1x3、x2x3职恳、x12、x22放钦、x32;
2操禀、三階多項式擴展
二階多項式展開,特征之間的最高次方為2颓屑,如果做三階多項式展開,特征之間的最高次方為3揪惦,但也包含也之前二階多項式展開中的所有項。
假設(shè)現(xiàn)在有兩個特征:x1丹擎、x2
我們做三階多項式擴展尾抑,最終的結(jié)果是:α+β
α:x1、x2的二階多項式展開部分:
x1蒂培、x2再愈、x12、x1x2 护戳、x22翎冲;
β:x1、x2的三階多項式展開部分:
x12x2媳荒、x1x22抗悍、x13驹饺、x23
我們發(fā)現(xiàn),僅僅兩個特征做三階多項式擴展缴渊,就會產(chǎn)生9個新的維度赏壹。
可以預(yù)測到的是:隨著最初特征數(shù)量的增加,多項式擴展增加的維度的上升速度會很快衔沼。如果一開始特征就非常多的情況下蝌借,進(jìn)行多項式擴展的階數(shù)又過高的情況下,會導(dǎo)致數(shù)據(jù)集的增長維度過快指蚁,計算機的運算量會非常巨大菩佑。我們稱為維度爆炸,或維度災(zāi)難(cures of dimension)
== 管道Pipeline ==
在Sklearn當(dāng)中有三大模型:Transformer 轉(zhuǎn)換器凝化、Estimator 估計器稍坯、Pipeline 管道
1、Transformer 轉(zhuǎn)換器 (StandardScaler搓劫,MinMaxScaler)
## 數(shù)據(jù)標(biāo)準(zhǔn)化
## StandardScaler 畫圖紙
ss = StandardScaler()
## fit_transform訓(xùn)練并轉(zhuǎn)換
## fit在計算瞧哟,transform完成輸出
X_train = ss.fit_transform(X_train)
X_train
Transformer有輸入有輸出,同時輸出可以放入Transformer或者Estimator 當(dāng)中作為輸入糟把。
2绢涡、Estimator 估計器(LinearRegression、LogisticRegression遣疯、LASSO雄可、Ridge),所有的機器學(xué)習(xí)算法模型缠犀,都被稱為估計器辨液。
## 模型訓(xùn)練
lr = LinearRegression()
## LinearRegression 是一個有監(jiān)督的算法,所以要把特征值和目標(biāo)值一起放入
lr.fit(X_train,Y_train) #訓(xùn)練模型
## 模型校驗
y_predict = lr.predict(X_test) #預(yù)測結(jié)果
y_predict 是估計器的輸出模型止吁,估計器輸出無法再放入Transformer 或 Estimator當(dāng)中再獲取另一個輸出了敬惦。
3俄删、Pipeline 管道
將Transformer畴椰、Estimator 組合起來成為一個大模型。
管道: 輸入→□→□→□→■→ 輸出
□:Transformer 抓艳; ■:Estimator 壶硅;
Transformer放在管道前幾個模型中,而Estimator 只能放到管道的最后一個模型中椒舵。
家庭用電預(yù)測demo中使用多項式擴展:
結(jié)合:《04 回歸算法 - 最小二乘線性回歸案例》
頭文件引入Pipeline:
from sklearn.pipeline import Pipeline
其他需要引入的包:
##家庭用電預(yù)測:線性回歸算法(時間與功率&功率與電流之間的關(guān)系)
## 一般用到sklearn的子庫
import sklearn
from sklearn.model_selection import train_test_split #訓(xùn)練集測試集劃分笔宿,最新版本中該庫直接歸到了sklearn的子庫
from sklearn.linear_model import LinearRegression # 線性模型
from sklearn.preprocessing import StandardScaler # 預(yù)處理的庫
from sklearn.preprocessing import MinMaxScaler
## 管道相關(guān)的包
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.model_selection import GridSearchCV
## 再提一下標(biāo)準(zhǔn)化的概念:
## StandardScaler作用:去均值和方差歸一化
## 假如對于某個特征中的一列數(shù)據(jù)集泼橘,x1,x2, ... ,xn
## 標(biāo)準(zhǔn)化后的數(shù)據(jù): (x1-均值)/標(biāo)準(zhǔn)差,(x2-均值)/標(biāo)準(zhǔn)差, ... ,(xn-均值)/標(biāo)準(zhǔn)差
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import time
## 設(shè)置字符集醋粟,防止中文亂碼
mpl.rcParams['font.sans-serif'] = ['simHei']
mpl.rcParams['axes.unicode_minus'] = False
創(chuàng)建一個關(guān)于時間的格式化字符串函數(shù)
時間 16/12/2006 用 %d/%m/%Y %H:%M:%S 格式化的方法處理數(shù)據(jù)
def data_fromat(dt):
t = time.strptime(' '.join(dt),'%d/%m/%Y %H:%M:%S')
return (t.tm_year,t.tm_mon,t.tm_mday,t.tm_hour,t.tm_min,t.tm_sec)
Pipeline的參數(shù)是一個列表米愿,列表中存放著每一個模型的信息育苟。
第0個模型名字:ss违柏,告訴系統(tǒng)我要做數(shù)據(jù)標(biāo)準(zhǔn)化
第1個模型名字:Poly香椎,告訴系統(tǒng)我要做一個多項式擴展士鸥。
PolynomialFeatures即進(jìn)行了ss= StandardScaler()的操作,并做了3階的擴展
第2個模型名字:Linear,告訴系統(tǒng)進(jìn)行模型訓(xùn)練肥照。fit_intercept=False 表示截距為0
截距:y=ax+b, b是截距勤众。一般推薦使用fit_intercept=True们颜。
如果輸入特征包含x1,x2,將特征放入多項式擴展的圖紙后努溃,我們會得到一個針對x1,x2擴展的特征集梧税,并把數(shù)據(jù)輸出出來称近。因此在多項式擴展的算法中刨秆,存儲的特征集合將是擴展后的結(jié)果。
## 時間和電壓之間的關(guān)系 (Linear - 多項式)
models = [
Pipeline([
('ss',StandardScaler()),
('Poly',PolynomialFeatures(degree=3)),#給定多項式擴展操作-3階擴展
('Linear',LinearRegression(fit_intercept=False))
])
]
model = models[0]
獲取數(shù)據(jù)尸执,在上一章中有詳細(xì)介紹剔交,本章不再贅述岖常。
## 數(shù)據(jù)文件的路徑
path1 = 'C:\\Users\\Gorde\\Desktop\\household_power_consumption\\household_power_consumption_100.txt'
#如果沒有混合類型的數(shù)據(jù)時竭鞍,可以通過low_memory=False來調(diào)用更多的內(nèi)存橄镜,提高讀取速度
df = pd.read_csv(path1,sep=';',low_memory=False)
## 處理異常數(shù)據(jù)
new_df = df.replace('?',np.nan) #替換非法字符為nan空
## how='any' 遇到空值就刪掉洽胶; axis=0 刪除行;
data = new_df.dropna(axis=0,how='any')
## 日期丐怯、時間读跷、有功功率、無功功率无切、電壓哆键、電流瘦锹、廚房用電功率、洗衣服用電功率沼本、熱水器用電功率
names2=df.columns
names=['Date', 'Time', 'Global_active_power', 'Global_reactive_power', 'Voltage', 'Global_intensity', 'Sub_metering_1', 'Sub_metering_2', 'Sub_metering_3']
## 獲取特征X和目標(biāo)Y
X = data[names[0:2]]
X = X.apply(lambda x:pd.Series(data_fromat(x)),axis=1)
Y= data[names[4]]
重點:設(shè)置1~5階多項式擴展抽兆,看哪個模型的最終擬合度最好
# 對數(shù)據(jù)集進(jìn)行測試集合訓(xùn)練集劃分
X_train,X_test,Y_train,Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)
## 數(shù)據(jù)標(biāo)準(zhǔn)化,將這一步放到了管道中
## 當(dāng)然也可以刪除管道的第0行辫红,放開下面的注釋贴妻,
## 得到的結(jié)果是一樣的
#ss = StandardScaler()
#X_train = ss.fit_transform(X_train) # 訓(xùn)練并轉(zhuǎn)換
#X_test = ss.transform(X_test) ## 直接使用在模型構(gòu)建數(shù)據(jù)上進(jìn)行一個數(shù)據(jù)標(biāo)準(zhǔn)化操作
# 模型訓(xùn)練
t=np.arange(len(X_test))
##設(shè)置1~5階多項式擴展名惩,看哪個模型的最終擬合度最好
N = 5
d_pool = np.arange(1,N,1) # 階
m = d_pool.size
clrs = [] # 顏色
for c in np.linspace(16711680, 255, m):
clrs.append('#%06x' % int(c))
line_width = 3
plt.figure(figsize=(12,6), facecolor='w')#創(chuàng)建一個繪圖窗口娩鹉,設(shè)置大小稚伍,設(shè)置顏色
for i,d in enumerate(d_pool):
plt.subplot(N-1,1,i+1)
plt.plot(t, Y_test, 'r-', label=u'真實值', ms=10, zorder=N)
## 對Poly模型中的degree參數(shù)進(jìn)行賦值
## 模型名__參數(shù)
model.set_params(Poly__degree=d) ## 設(shè)置多項式的階乘
## fit完后流轉(zhuǎn)到下一個節(jié)點
## 雖然標(biāo)準(zhǔn)化數(shù)據(jù)的時候只針對X_train个曙,但因為后面進(jìn)入Estimator環(huán)節(jié)需要Y_train的數(shù)據(jù),所以一并傳入
model.fit(X_train, Y_train)
## model.get_params()調(diào)用管道中所有模型的參數(shù)
## ['Linear'] 提取Linear模型的參數(shù)
lin = model.get_params()['Linear']
output = u'%d階艳汽,系數(shù)為:' % d
## 判斷Linear模型中是否有alpha這個參數(shù)
if hasattr(lin, 'alpha_'):
idx = output.find(u'系數(shù)')
output = output[:idx] + (u'alpha=%.6f, ' % lin.alpha_) + output[idx:]
## 判斷Linear模型中是否有l(wèi)1_ratio這個參數(shù)
if hasattr(lin, 'l1_ratio_'):
idx = output.find(u'系數(shù)')
output = output[:idx] + (u'l1_ratio=%.6f, ' % lin.l1_ratio_) + output[idx:]
## 輸出Linear模型中θ1~θn的屬性
print ('==',output, lin.coef_.ravel())
y_hat = model.predict(X_test)
s = model.score(X_test, Y_test)
z = N - 1 if (d == 2) else 0
label = u'%d階, 準(zhǔn)確率=%.3f' % (d,s)
plt.plot(t, y_hat, color=clrs[i], lw=line_width, alpha=0.75, label=label, zorder=z)
plt.legend(loc = 'upper left')
plt.grid(True)
plt.ylabel(u'%d階結(jié)果' % d, fontsize=12)
## 預(yù)測值和實際值畫圖比較
plt.suptitle(u"線性回歸預(yù)測時間和功率之間的多項式關(guān)系", fontsize=20)
plt.grid(b=True)
plt.show()
結(jié)果:
== 1階骚灸,系數(shù)為: [ 234.635375 0. 0. 0. -0.50376467
-0.43146823 0. ]
== 2階甚牲,系數(shù)為: [ 2.35318068e+02 -6.57252031e-14 1.11022302e-16 -6.55031585e-15
-5.71168427e-01 -3.76554668e-01 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 -9.24737046e-01 -8.06322387e-01
0.00000000e+00 -1.74179681e-01 0.00000000e+00 0.00000000e+00]
== 3階丈钙,系數(shù)為: [ 2.13129561e+11 1.32727630e+12 -1.30480175e+12 -5.84592052e+12
-3.54666596e+11 2.83229781e-01 1.67040304e+12 -4.22518953e+12
4.85924486e+12 6.79144658e+12 -3.32463273e+12 -1.08242302e+13
-1.09288546e+13 -1.76420169e+12 -5.09819286e+11 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 -2.07077200e+11 -1.26342773e-01
0.00000000e+00 1.85546875e-02 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 1.37336540e+11 -2.27539062e-01
0.00000000e+00 -8.84399414e-01 0.00000000e+00 0.00000000e+00
-5.73242188e-01 0.00000000e+00 0.00000000e+00 0.00000000e+00]
== 4階雏赦,系數(shù)為: [ 1.90130586e+02 3.83693077e-12 -6.94910796e-12 -4.78195261e-12
7.02006845e+01 3.40996949e+00 -1.49213975e-12 1.37134748e-12
-8.68638494e-13 -1.34292577e-12 -3.03351788e-12 4.48041604e-12
-1.94155803e-12 -1.24167343e-12 3.81561449e-12 -7.18181070e-12
-2.13162821e-13 2.57571742e-14 -6.57252031e-14 -1.87627691e-13
-2.75335310e-13 1.62536651e-13 5.57818267e+01 6.41779285e+00
-1.41220369e-13 7.68221007e+00 -1.68753900e-13 9.88098492e-14
4.91273688e-14 -8.52860415e-14 -5.38647519e-13 3.97555610e-13
-3.78653235e-29 5.04870979e-29 -2.52435490e-29 -5.04870979e-29
5.04870979e-29 0.00000000e+00 -1.00974196e-28 0.00000000e+00
-7.57306469e-29 1.39250583e-29 2.53951075e-29 -2.83803115e-29
6.57415717e-29 6.42382859e-30 -1.01636592e-28 9.72188732e-29
-2.80259693e-44 1.12103877e-44 -2.38220739e-44 -9.80908925e-45
-3.36311631e-44 -2.80259693e-45 -2.24207754e-44 1.68155816e-44
-2.24207754e-44 -1.01291903e-45 -3.04107162e-45 8.26065381e-46
1.71351712e-44 3.62881753e-45 2.07883572e-44 2.59181725e-44
4.97841222e-60 0.00000000e+00 0.00000000e+00 0.00000000e+00
-2.48920611e-60 1.24460306e-60 7.46761833e-60 3.11150764e-61
0.00000000e+00 -1.10542958e-75 -2.96604674e+01 -1.81198079e+01
4.79403659e-94 -1.11690774e+01 0.00000000e+00 0.00000000e+00
-5.14703828e-01 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 -9.61067605e+00
-1.60393413e+01 0.00000000e+00 -1.25463427e+01 0.00000000e+00
0.00000000e+00 1.29012532e-01 0.00000000e+00 0.00000000e+00
0.00000000e+00 2.89961813e-01 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00]
由于數(shù)據(jù)比較少才100條,所以模型的準(zhǔn)確度提高得不是很多寥掐。但總體來上還是在進(jìn)步的: