本文將繼續(xù)修煉回歸模型算法,并總結(jié)了一些常用的除線性回歸模型之外的模型,其中包括一些單模型及集成學(xué)習(xí)器。
保序回歸、多項(xiàng)式回歸、多輸出回歸、多輸出K近鄰回歸、決策樹回歸、多輸出決策樹回歸、AdaBoost回歸、梯度提升決策樹回歸、人工神經(jīng)網(wǎng)絡(luò)、隨機(jī)森林回歸、多輸出隨機(jī)森林回歸、XGBoost回歸。
需要面試或者需要總體了解/復(fù)習(xí)機(jī)器學(xué)習(xí)回歸模型的小伙伴可以通讀下本文,理論總結(jié)加代碼實(shí)操,有助于理解模型。
保序回歸
保序回歸或單調(diào)回歸是一種將自由形式的直線擬合到一系列觀測(cè)值上的技術(shù),這樣擬合的直線在所有地方都是非遞減(或非遞增)的,并且盡可能靠近觀測(cè)值。
理論規(guī)則是
- 如果預(yù)測(cè)輸入與訓(xùn)練中的特征值完全匹配,則返回相應(yīng)標(biāo)簽。如果一個(gè)特征值對(duì)應(yīng)多個(gè)預(yù)測(cè)標(biāo)簽值,則返回其中一個(gè),具體是哪一個(gè)未指定。
- 如果預(yù)測(cè)輸入比訓(xùn)練中的特征值都高(或者都低),則相應(yīng)返回最高特征值或者最低特征值對(duì)應(yīng)標(biāo)簽。如果一個(gè)特征值對(duì)應(yīng)多個(gè)預(yù)測(cè)標(biāo)簽值,則相應(yīng)返回最高值或者最低值。
- 如果預(yù)測(cè)輸入落入兩個(gè)特征值之間,則預(yù)測(cè)將會(huì)是一個(gè)分段線性函數(shù),其值由兩個(gè)最近的特征值的預(yù)測(cè)值計(jì)算得到。如果一個(gè)特征值對(duì)應(yīng)多個(gè)預(yù)測(cè)標(biāo)簽值,則使用上述兩種情況中的處理方式解決。
n = len(dataset['Adj Close'])
X = np.array(dataset['Open'].values)
y = dataset['Adj Close'].values
from sklearn.isotonic import IsotonicRegression
ir=IsotonicRegression()
y_ir=ir.fit_transform(X,y)
將擬合過程可視化
紅色散點(diǎn)圖是原始數(shù)據(jù)X-y
關(guān)系圖,綠色線為保序回歸擬合后的數(shù)據(jù)X-y_ir
關(guān)系圖。這里以可視化的形式表現(xiàn)了保序回歸的理論規(guī)則。
lines=[[[i,y[i]],[i,y_ir[i]]] for i in range(n)]
lc=LineCollection(lines)
plt.figure(figsize=(15,6))
plt.plot(X,y,'r.',markersize=12)
plt.plot(X,y_ir,'g.-',markersize=12)
plt.gca().add_collection(lc)
plt.legend(('Data','Isotonic Fit','Linear Fit'))
plt.title("Isotonic Regression")
plt.show()
多項(xiàng)式回歸
多項(xiàng)式回歸(PolynomialFeatures)是一種用多項(xiàng)式函數(shù)作為自變量的非線性方程的回歸方法。
將數(shù)據(jù)轉(zhuǎn)換為多項(xiàng)式。多項(xiàng)式回歸是一般線性回歸模型的特殊情況。它對(duì)于描述曲線關(guān)系很有用。曲線關(guān)系可以通過平方或設(shè)置預(yù)測(cè)變量的高階項(xiàng)來實(shí)現(xiàn)。
sklearn中的多項(xiàng)式擬合
X = dataset.iloc[ : , 0:4].values
Y = dataset.iloc[ : , 4].values
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
poly=PolynomialFeatures(degree=3)
poly_x=poly.fit_transform(X)
regressor=LinearRegression()
regressor.fit(poly_x,Y)
plt.scatter(X,Y,color='red')
plt.plot(X,regressor.predict(poly.fit_transform(X)),color='blue')
plt.show()
以原始數(shù)據(jù)繪制X-Y
紅色散點(diǎn)圖,并繪制藍(lán)色的、經(jīng)過多項(xiàng)式擬合后再進(jìn)行線性回歸模型擬合的直線圖。
一元自變量計(jì)算三階多項(xiàng)式
from scipy import *
f = np.polyfit(X,Y,3)
p = np.poly1d(f)
print(p)
3 2
-6.228e-05x + 0.0023x + 0.9766x + 0.05357
多元自變量的多項(xiàng)式
from sklearn.preprocessing import PolynomialFeatures
from sklearn import linear_model
X = np.array(dataset[['Open', 'High', 'Low']].values)
Y = np.array(dataset['Adj Close'].values)
Y = Y.reshape(Y.shape[0], -1)
poly = PolynomialFeatures(degree=3)
X_ = poly.fit_transform(X)
predict_ = poly.fit_transform(Y)
Pipeline形式
from sklearn.pipeline import Pipeline
X = np.array(dataset['Open'].values)
Y = np.array(dataset['Adj Close'].values)
X = X.reshape(X.shape[0], -1)
Y = Y.reshape(Y.shape[0], -1)
Input=[('scale',StandardScaler()),('polynomial', PolynomialFeatures(include_bias=False)),('model',LinearRegression())]
pipe = Pipeline(Input)
pipe.fit(X,Y)
yhat = pipe.predict(X)
yhat[0:4]
array([[3.87445269],
[3.95484371],
[4.00508501],
[4.13570206]])
numpy 中的多項(xiàng)式擬合
首先理解nump用于多項(xiàng)式擬合的兩個(gè)主要方法。
np.poly1d
np.poly1d(c_or_r,
r=False,
variable=None)
一維多項(xiàng)式類,用于封裝多項(xiàng)式上的"自然"操作,以便上述操作可以在代碼中采用慣用形式。如何理解呢?看看下面幾個(gè)例子。
c_or_r
系數(shù)向量
import numpy as np
a=np.array([2,1,1])
f=np.poly1d(a)
print(f)
2
2 x + 1 x + 1
r=False
是否反推
表示把數(shù)組中的值作為根,然后反推多項(xiàng)式。
f=np.poly1d([2,3,5],r=True)
#(x - 2)*(x - 3)*(x - 5) = x^3 - 10x^2 + 31x -30
print(f)
3 2
1 x - 10 x + 31 x - 30
variable=None
表示改變未知數(shù)的字母
f=np.poly1d([2,3,5],r=True,variable='z')
print(f)
3 2
1 z - 10 z + 31 z - 30
np.polyfit
np.polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False)
最小二乘多項(xiàng)式擬合。
擬合多項(xiàng)式。返回一個(gè)系數(shù)'p'
的向量,以最小化平方誤差的順序'deg','deg-1',…"0"
。
推薦使用 類方法,因?yàn)樗跀?shù)值上更穩(wěn)定。
下圖是以原始數(shù)據(jù)繪制的藍(lán)色X-Y
散點(diǎn)圖,以及紅色的X
分布圖。
X = dataset['Open'].values
y = dataset['Adj Close'].values
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)
plt.figure(figsize=(10,6))
plt.plot(X_train, y_train, 'bo')
plt.plot(X_test, np.zeros_like(X_test), 'r+')
plt.show()
numpy與sklearn中的多項(xiàng)式回歸對(duì)比
# numpy
model_one = np.poly1d(np.polyfit(X_train, y_train,1))
preds_one = model_one(X_test)
print(preds_one[:3])
> >> [11.59609048 10.16018804 25.23716889]
# sklearn
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train.reshape(-1, 1), y_train)
preds = model.predict(X_test.reshape(-1, 1))
preds[:3]
> >> array([11.59609048, 10.16018804, 25.23716889])
# 預(yù)測(cè)結(jié)果是一樣的
print("all close?", np.allclose(preds, preds_one))
> >> 'all close? True
結(jié)果表明兩者相比預(yù)測(cè)結(jié)果時(shí)一致的。
多階多項(xiàng)式效果對(duì)比
比較一階、二階及三階多項(xiàng)式擬合,多線性回歸模型的效果影響。由圖可看出,三條線基本重合,且RMSE
相差不大。
model_one = np.poly1d(np.polyfit(X_train, y_train,1))
model_two = np.poly1d(np.polyfit(X_train, y_train, 2))
model_three = np.poly1d(np.polyfit(X_train, y_train, 3))
fig, axes = plt.subplots(1, 2, figsize=(14, 5),sharey=True)
labels = ['line', 'parabola', 'nonic']
models = [model_one, model_two, model_three]
train = (X_train, y_train)
test = (X_test, y_test)
for ax, (ftr, tgt) in zip(axes, [train, test]):
ax.plot(ftr, tgt, 'k+')
num = 0
for m, lbl in zip(models, labels):
ftr = sorted(ftr)
ax.plot(ftr, m(ftr), '-', label=lbl)
if ax == axes[1]:
ax.text(2,55-num, f"{lbl}_RMSE: {round(np.sqrt(mse(tgt, m(tgt))),3)}")
num += 5
axes[1].set_ylim(-10, 60)
axes[0].set_title("Train")
axes[1].set_title("Test");
axes[0].legend(loc='best');
繪制類似學(xué)習(xí)曲線
因低階多項(xiàng)式效果相差并不明顯,因此增大多項(xiàng)式階數(shù),并以殘差平方和為y軸,看模型擬合效果,由圖可以看出,隨著多項(xiàng)式階數(shù)越來越高,模型出現(xiàn)嚴(yán)重的過擬合(訓(xùn)練集殘差平方和降低,而測(cè)試集卻在上漲)。
results = []
for complexity in [1, 2, 3, 4, 5, 6,7,8, 9]:
model = np.poly1d(np.polyfit(X_train, y_train, complexity))
train_error = np.sqrt(mse(y_train, model(X_train)))
test_error = np.sqrt(mse(y_test,model(X_test)))
results.append((complexity, train_error, test_error))
columns = ["Complexity", "Train Error", "Test Error"]
results_df = pd.DataFrame.from_records(results,
columns=columns,
index="Complexity")
results_df
results_df.plot(figsize=(10,6))
多輸出回歸
多輸出回歸為每個(gè)樣本分配一組目標(biāo)值。這可以認(rèn)為是預(yù)測(cè)每一個(gè)樣本的多個(gè)屬性,比如說一個(gè)具體地點(diǎn)的風(fēng)的方向和大小。
多輸出回歸支持 MultiOutputRegressor
可以被添加到任何回歸器中。這個(gè)策略包括對(duì)每個(gè)目標(biāo)擬合一個(gè)回歸器。因?yàn)槊恳粋€(gè)目標(biāo)可以被一個(gè)回歸器精確地表示,通過檢查對(duì)應(yīng)的回歸器,可以獲取關(guān)于目標(biāo)的信息。因?yàn)?MultiOutputRegressor
對(duì)于每一個(gè)目標(biāo)可以訓(xùn)練出一個(gè)回歸器,所以它無法利用目標(biāo)之間的相關(guān)度信息。
支持多類-多輸出分類的分類器:
sklearn.tree.DecisionTreeClassifier
sklearn.tree.ExtraTreeClassifier
sklearn.ensemble.ExtraTreesClassifier
sklearn.neighbors.KNeighborsClassifier
sklearn.neighbors.RadiusNeighborsClassifier
sklearn.ensemble.RandomForestClassifier
X = dataset.drop(['Adj Close', 'Open'], axis=1)
Y = dataset[['Adj Close', 'Open']]
from sklearn.multioutput import MultiOutputRegressor
from sklearn.svm import LinearSVR
model = LinearSVR()
wrapper = MultiOutputRegressor(model)
wrapper.fit(X, Y)
data_in = [[23.98, 22.91, 7.00, 7.00,
1.62, 1.62, 4.27, 4.25]]
yhat = wrapper.predict(data_in)
print(yhat[0])
> >> [16.72625136 16.72625136]
wrapper.score(X, Y)
多輸出K近鄰回歸
多輸出K近鄰回歸可以不使用MultiOutputRegressor
作為外包裝器,直接使用KNeighborsRegressor
便可以實(shí)現(xiàn)多輸出回歸。
X = dataset.drop(['Adj Close', 'Open'], axis=1)
Y = dataset[['Adj Close', 'Open']]
from sklearn.neighbors import KNeighborsRegressor
model = KNeighborsRegressor()
model.fit(X, Y)
data_in = [[23.98, 22.91, 7.00, 7.00,
1.62, 1.62, 4.27, 4.25]]
yhat = model.predict(data_in)
print(yhat[0])
> >> [2.34400001 2.352 ]
model.score(X, Y)
> >> 0.7053689393640217
決策樹回歸
決策樹是一種樹狀結(jié)構(gòu),她的每一個(gè)葉子結(jié)點(diǎn)對(duì)應(yīng)著一個(gè)分類,非葉子結(jié)點(diǎn)對(duì)應(yīng)著在某個(gè)屬性上的劃分,根據(jù)樣本在該屬性上的不同取值降氣劃分成若干個(gè)子集。
基本原理
數(shù)模型通過遞歸切割的方法來尋找最佳分類標(biāo)準(zhǔn),進(jìn)而最終形成規(guī)則。CATA樹,對(duì)回歸樹用平方誤差最小化準(zhǔn)則,進(jìn)行特征選擇,生成二叉樹。
CATA回歸樹的生成
在訓(xùn)練數(shù)據(jù)集所在的空間中,遞歸地將每個(gè)空間區(qū)域劃分為兩個(gè)子區(qū)域,并決定每個(gè)子區(qū)域上的輸出值,生產(chǎn)二叉樹。
選擇最優(yōu)切分變量 和最優(yōu)切分點(diǎn) ,求解
遍歷 ,對(duì)固定的切分變量 掃描切分點(diǎn) ,使得上式達(dá)到最小值的對(duì) ,不斷循環(huán)直至滿足條件停止。
X = dataset.drop(['Adj Close', 'Close'], axis=1)
y = dataset['Adj Close']
# 劃分訓(xùn)練集和測(cè)試集略
# 模型實(shí)例化
from sklearn.tree import DecisionTreeRegressor
regressor = DecisionTreeRegressor()
# 訓(xùn)練模型
regressor.fit(X_train, y_train)
# 回歸預(yù)測(cè)
y_pred = regressor.predict(X_test)
df = pd.DataFrame({'Actual':y_test, 'Predicted':y_pred})
print(df.head(2))
Actual Predicted
Date
2017-08-09 12.83 12.63
2017-11-14 11.12 11.20
模型評(píng)價(jià)
from sklearn import metrics
# 平均絕對(duì)誤差
print(metrics.mean_absolute_error(
y_test, y_pred))
# 均方差
print(metrics.mean_squared_error(
y_test, y_pred))
# 均方根誤差
print(np.sqrt(
metrics.mean_squared_error(
y_test, y_pred)))
0.0924680893617
0.0226966010212
0.1506539114039
交叉驗(yàn)證
from sklearn.model_selection import cross_val_score
dt_fit = regressor.fit(X_train, y_train)
dt_scores = cross_val_score(
dt_fit, X_train, y_train, cv = 5)
print("Mean cross validation score: {}".format(np.mean(dt_scores)))
print("Score without cv: {}".format(dt_fit.score(X_train, y_train)))
Mean cross validation score: 0.99824909037
Score without cv: 1.0
R2
from sklearn.metrics import r2_score
print('r2 score:', r2_score(y_test, dt_fit.predict(X_test)))
print('Accuracy Score:', dt_fit.score(X_test, y_test))
r2 score: 0.9989593390532074
Accuracy Score: 0.9989593390532074
多輸出決策樹回歸
多輸出回歸是根據(jù)輸入預(yù)測(cè)兩個(gè)或多個(gè)數(shù)字輸出。在多輸出回歸中,通常,輸出依賴于輸入并且彼此依賴。這意味著輸出經(jīng)常不是彼此獨(dú)立的,可能需要一個(gè)模型來預(yù)測(cè)兩個(gè)輸出在一起或每個(gè)輸出取決于其他輸出。
一個(gè)示例說明決策樹多輸出回歸(Decision Tree for Multioutput Regression)。
X = dataset.drop(['Adj Close', 'Open'], axis=1)
Y = dataset[['Adj Close', 'Open']]
from sklearn.tree import DecisionTreeRegressor
model = DecisionTreeRegressor()
model.fit(X, Y)
# 統(tǒng)計(jì)值
# dataset.describe()
# 根據(jù)統(tǒng)計(jì)信息輸入data_in
data_in = [23.98, 22.91, 7.00, 7.00, 1.62, 1.62, 4.27, 4.25]
yhat = model.predict([data_in])
# 預(yù)測(cè)值
print(yhat[0])
print(model.score(X, Y))
[15.64999962 16.64999962]
1
集成算法回歸
裝袋法
裝袋法 (Bagging)的核?思想是構(gòu)建多個(gè) 相互獨(dú)?的評(píng)估器 ,然后對(duì)其預(yù)測(cè)進(jìn)?平均或多數(shù)表決原則來決定集成評(píng)估器的結(jié)果。裝袋法的代表模型就是隨機(jī)森林。
個(gè)體學(xué)習(xí)器間不存在強(qiáng)依賴關(guān)系、可同時(shí)生成的并行化方法。
提升法
提升法(Boosting)中,基評(píng)估器是相關(guān)的,是按順序??構(gòu)建的。其核?思想是結(jié)合弱評(píng)估器的?量?次次對(duì)難以評(píng)估的樣本進(jìn)?預(yù)測(cè),從?構(gòu)成?個(gè)強(qiáng)評(píng)估器。提升法的代表模型Adaboost和梯度提升樹GBDT。
個(gè)體學(xué)習(xí)器間存在強(qiáng)依賴關(guān)系、必須串行生成的序列化方法。
AdaBoost 回歸
AdaBoost Regressor 自適應(yīng)增強(qiáng)回歸
通過提高那些被前一輪基學(xué)習(xí)器錯(cuò)誤分類的樣本的權(quán)值,降低那些被正確分類的樣本的權(quán)值來改變訓(xùn)練樣本分布。并對(duì)所有基學(xué)習(xí)器采用加權(quán)結(jié)合,增大分類誤差小的基學(xué)習(xí)器的權(quán)值,減少分類誤差率大的基學(xué)習(xí)器的權(quán)值。
理論上的AdaBoost可以使用任何算法作為基學(xué)習(xí)器,但一般來說,使用最廣泛的AdaBoost的弱學(xué)習(xí)器是決策樹和神經(jīng)網(wǎng)絡(luò)。
AdaBoost的核心原則是在反復(fù)修改的數(shù)據(jù)版本上擬合一系列弱學(xué)習(xí)者(即比隨機(jī)猜測(cè)略好一點(diǎn)的模型,如小決策樹)。他們所有的預(yù)測(cè)然后通過加權(quán)多數(shù)投票(或總和)合并產(chǎn)生最終的預(yù)測(cè)。
每次所謂的增強(qiáng)迭代的數(shù)據(jù)修改包括對(duì)每個(gè)訓(xùn)練樣本應(yīng)用權(quán)重。
- 最初,這些權(quán)重都被設(shè)置為,所以第一步僅僅是在原始數(shù)據(jù)上訓(xùn)練一個(gè)能力較弱的學(xué)習(xí)器。
- 對(duì)于每一次連續(xù)迭代,樣本權(quán)值被單獨(dú)修改,學(xué)習(xí)算法被重新應(yīng)用到重新加權(quán)的數(shù)據(jù)。
- 在給定的步驟中,那些被前一步引入的增強(qiáng)模型錯(cuò)誤預(yù)測(cè)的訓(xùn)練例子的權(quán)重增加,而那些被正確預(yù)測(cè)的訓(xùn)練例子的權(quán)重減少。
- 隨著迭代的進(jìn)行,難以預(yù)測(cè)的例子受到越來越大的影響。因此,每一個(gè)隨后的弱學(xué)習(xí)器都被迫將注意力集中在前一個(gè)學(xué)習(xí)器錯(cuò)過的例子上。
基分類器 在加權(quán)數(shù)據(jù)集上的分類誤差率等于被 誤分類樣本的權(quán)重之和。
Adaboost基本性質(zhì)
能在學(xué)習(xí)過程中不斷減少訓(xùn)練誤差,即在訓(xùn)練數(shù)據(jù)集上的訓(xùn)練誤差率。且誤差率是以指數(shù)數(shù)率下降的。
X = dataset[['Open', 'High', 'Low', 'Volume']].values
y = dataset['Buy_Sell'].values
# 劃分訓(xùn)練集與測(cè)試集略
from sklearn.ensemble import AdaBoostClassifier
ada = AdaBoostClassifier(n_estimators=180, random_state=0)
ada.fit(X_train, y_train)
y_pred_proba = ada.predict_proba(X_test)[:,1]
ada.feature_importances_
array([ 0.18888889, 0.15 ,
0.26666667, 0.39444444])
模型評(píng)價(jià)
ada.predict(X_test)
ada.score(X, y)
from sklearn.metrics import roc_auc_score
ada_roc_auc = roc_auc_score(y_test, y_pred_proba)
print('ROC AUC score: {:.2f}'.format(ada_roc_auc))
梯度提升決策樹回歸
GBDT(Gradient Boosting Decision Tree) 又叫 MART(Multiple Additive Regression Tree),是一種迭代的決策樹算法,該算法由多棵決策樹組成,所有樹的結(jié)論累加起來做最終答案。它在被提出之初就和SVM一起被認(rèn)為是泛化能力較強(qiáng)的算法。
提升樹是迭代多棵回歸樹來共同決策。當(dāng)采用平方誤差損失函數(shù)時(shí),每一棵回歸樹學(xué)習(xí)的是之前所有樹的結(jié)論和殘差,擬合得到一個(gè)當(dāng)前的殘差回歸樹,殘差的意義如公式:殘差 = 真實(shí)值 - 預(yù)測(cè)值 。提升樹即是整個(gè)迭代過程生成的回歸樹的累加。
提升樹利用加法模型和前向分步算法實(shí)現(xiàn)學(xué)習(xí)的優(yōu)化過程。當(dāng)損失函數(shù)時(shí)平方損失和指數(shù)損失函數(shù)時(shí),每一步的優(yōu)化很簡(jiǎn)單,如平方損失函數(shù)學(xué)習(xí)殘差回歸樹。
簡(jiǎn)單解釋:每一次的計(jì)算是為了減少上一次的殘差,GBDT在殘差減少(負(fù)梯度)的方向上建立一個(gè)新的模型。
提升樹模型算法原理
我們利用平方誤差來表示損失函數(shù),其中每一棵回歸樹學(xué)習(xí)的是之前所有樹的結(jié)論和殘差 ,擬合得到一個(gè)當(dāng)前的殘差回歸樹。提升樹即是整個(gè)迭代過程生成的回歸樹的累加。
GBDT需要將多棵樹的得分累加得到最終的預(yù)測(cè)得分,且每一次迭代,都在現(xiàn)有樹的基礎(chǔ)上,增加一棵樹去擬合前面樹的預(yù)測(cè)結(jié)果與真實(shí)值之間的殘差。
梯度提升樹模型算法原理
采用向前分布算法,先確定初始提升樹,然后每一次提升都是靠上次的預(yù)測(cè)結(jié)果與訓(xùn)練數(shù)據(jù)中標(biāo)簽值作為新的訓(xùn)練數(shù)據(jù)進(jìn)行重新訓(xùn)練,利用損失函數(shù)的負(fù)梯度來擬合本輪損失函數(shù)的近似值,進(jìn)而擬合一個(gè)CART回歸樹。
對(duì)于梯度提升回歸樹來說,每個(gè)樣本的預(yù)測(cè)結(jié)果可以表示為所有樹上的結(jié)果的加權(quán)求和。
GBDT正則化
子采樣比例方法: subsample(子采樣),取值為(0,1],采用的不放回采樣。
定義步長v方法來防止過擬合: Shrinkage,即在每一輪迭代獲取最終學(xué)習(xí)器的時(shí)候按照一定的步長進(jìn)行更新。
GBDT分裂規(guī)則
利用來構(gòu)建Cart回歸樹的時(shí)候,GBDT分裂會(huì)選取使得誤差下降最多(如果cart樹采用的是均方差作為損失,那么就是最小均方差)的特征進(jìn)行分裂,如果這棵樹不能擬合好,那么就要通過負(fù)梯度計(jì)算出新的殘差向量來擬合新的Cart回歸樹。
GBDT如何做特征選擇
特征 的全局重要度通過特征 在單顆樹中的重要度的平均值來衡量。
其中, 是樹的數(shù)量。特征 在單顆樹中的重要度( 通過計(jì)算按這個(gè)特征i分裂之后損失的減少值 )的如下:
其中, 為樹的葉子節(jié)點(diǎn)數(shù)量, 即為樹的非葉子節(jié)點(diǎn)數(shù)量(構(gòu)建的樹都是具有左右孩子的二叉樹), 是和節(jié)點(diǎn) 相關(guān)聯(lián)的特征, 是節(jié)點(diǎn) 分裂之后平方損失的減少值。
優(yōu)點(diǎn)
- 相對(duì)少的調(diào)參時(shí)間情況下可以得到較高的準(zhǔn)確率。
- 可靈活處理各種類型數(shù)據(jù),包括連續(xù)值和離散值,使用范圍廣。
- 可使用一些健壯的損失函數(shù),對(duì)異常值的魯棒性較強(qiáng),比如Huber損失函數(shù)。
缺點(diǎn)
- 弱學(xué)習(xí)器之間存在依賴關(guān)系,難以并行訓(xùn)練數(shù)據(jù)。
- 需要先處理缺失值。
X = dataset[['Open', 'High', 'Low', 'Volume']].values
y = dataset['Adj Close'].values
# 劃分訓(xùn)練集與測(cè)試集略
from sklearn.ensemble import GradientBoostingRegressor
gb = GradientBoostingRegressor(max_depth=4,
n_estimators=200,
random_state=2)
# 用訓(xùn)練集訓(xùn)練數(shù)據(jù)
gb.fit(X_train, y_train)
# 預(yù)測(cè)測(cè)試集標(biāo)簽
y_pred = gb.predict(X_test)
from sklearn.metrics import mean_squared_error as MSE
# 計(jì)算 MSE
mse_test = MSE(y_test, y_pred)
# 計(jì)算 RMSE
rmse_test = mse_test**(1/2)
# 輸出 RMSE
print('Test set RMSE of gb: {:.3f}'.format(rmse_test))
模型提升
estimator_imp = tf.estimator.DNNRegressor(
feature_columns=feature_columns,
hidden_units=[300, 100],
dropout=0.3,
optimizer=tf.train.ProximalAdagradOptimizer(
learning_rate=0.01,
l1_regularization_strength=0.01,
l2_regularization_strength=0.01
))
estimator_imp.train(input_fn = train_input,steps=1000)
estimator_imp.evaluate(eval_input,steps=None)
{'average_loss': 6.139895,
'global_step': 1000,
'loss': 1442.8754}
隨機(jī)森林回歸
隨機(jī)森林采用決策樹作為弱分類器,在bagging的樣本隨機(jī)采樣基礎(chǔ)上,?加上了特征的隨機(jī)選擇。
當(dāng)前結(jié)點(diǎn)特征集合( 個(gè)特征),隨機(jī)選擇 個(gè)特征子集,再選擇最優(yōu)特征進(jìn)行劃分。 控制了隨機(jī)性的引入程度,推薦值:
對(duì)預(yù)測(cè)輸出進(jìn)行結(jié)合時(shí),分類任務(wù)——簡(jiǎn)單投票法;回歸任務(wù)——簡(jiǎn)單平均法
采用有交疊的采樣子集的目的
- 為集成中的個(gè)體學(xué)習(xí)器應(yīng)盡可能相互獨(dú)立,盡可能具有較大差異,以得到泛化能力強(qiáng)的集成。對(duì)訓(xùn)練樣本進(jìn)行采樣,得到不同的數(shù)據(jù)集。
- 如果采樣出的每個(gè)子集都完全不同,每個(gè)學(xué)習(xí)器只用到一小部分訓(xùn)練數(shù)據(jù),甚至不足以進(jìn)行有效學(xué)習(xí)。
- Bagging能不經(jīng)修改的用于多分類、回歸等任務(wù)。而Adaboost只適用二分類任務(wù)有 的袋外數(shù)據(jù)用于驗(yàn)證集。
算法
- 從樣本集N中有放回隨機(jī)采樣選出n個(gè)樣本。
- 從所有特征中隨機(jī)選擇k個(gè)特征,對(duì)選出的樣本利用這些特征建立決策樹(一般是CART方法)。
- 重復(fù)以上兩步m次,生成m棵決策樹,形成隨機(jī)森林,其中生成的決策樹不剪枝。
- 對(duì)于新數(shù)據(jù),經(jīng)過每棵決策樹投票分類。
隨機(jī)森林的優(yōu)點(diǎn)
- 決策樹選擇部分樣本及部分特征,一定程度上避免過擬合 。
- 決策樹隨機(jī)選擇樣本并隨機(jī)選擇特征,模型具有很好的抗噪能力,性能穩(wěn)定。
- 能夠處理高維度數(shù)據(jù),并且不用做特征選擇,能夠展現(xiàn)出哪些變量比較重要。
- 對(duì)缺失值不敏感,如果有很大一部分的特征遺失,仍可以維持準(zhǔn)確度。
- 訓(xùn)練時(shí)樹與樹之間是相互獨(dú)立的,訓(xùn)練速度快,容易做成并行化方法。
- 隨機(jī)森林有袋外數(shù)據(jù)obb,不需要單獨(dú)劃分交叉驗(yàn)證集。
隨機(jī)森林的缺點(diǎn)
- 可能有很多相似決策樹,掩蓋真實(shí)結(jié)果。
- 對(duì)小數(shù)據(jù)或低維數(shù)據(jù)可能不能產(chǎn)生很好分類。
- 產(chǎn)生眾多決策樹,算法較慢。
X = dataset.drop(['Adj Close', 'Close'], axis=1)
y = dataset['Adj Close']
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, random_state=42)
# 數(shù)據(jù)標(biāo)準(zhǔn)化
scaler = StandardScaler().fit(X_train)
X_train_scaled = pd.DataFrame(scaler.transform(X_train), index=X_train.index.values, columns=X_train.columns.values)
X_test_scaled = pd.DataFrame(scaler.transform(X_test), index=X_test.index.values, columns=X_test.columns.values)
# PCA降維
from sklearn.decomposition import PCA
pca = PCA()
pca.fit(X_train)
cpts = pd.DataFrame(pca.transform(X_train))
x_axis = np.arange(1, pca.n_components_+1)
# 標(biāo)準(zhǔn)化后的降維
pca_scaled = PCA()
pca_scaled.fit(X_train_scaled)
cpts_scaled = pd.DataFrame(pca.transform(X_train_scaled))
模型建立與評(píng)價(jià)
from sklearn.ensemble import RandomForestRegressor
rf = RandomForestRegressor(n_estimators=500, oob_score=True, random_state=0)
rf.fit(X_train, y_train)
from sklearn.metrics import r2_score
from scipy.stats import spearmanr, pearsonr
predicted_train = rf.predict(X_train)
predicted_test = rf.predict(X_test)
test_score = r2_score(y_test, predicted_test)
spearman = spearmanr(y_test, predicted_test)
pearson = pearsonr(y_test, predicted_test)
print('Out-of-bag R-2 score estimate:', rf.oob_score_)
print('Test data R-2 score:', test_score)
print('Test data Spearman correlation:',spearman[0])
print('Test data Pearson correlation:',pearson[0])
Out-of-bag R-2 score estimate: 0.99895617164
Test data R-2 score: 0.999300318737
Test data Spearman correlation: 0.999380233068
Test data Pearson correlation: 0.999650364791
多輸出隨機(jī)森林回歸
X = dataset.drop(['Adj Close', 'Open'], axis=1)
Y = dataset[['Adj Close', 'Open']]
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor()
model.fit(X, Y)
data_in = [[23.98, 22.91, 7.00, 7.00, 1.62, 1.62, 4.27, 4.25]]
yhat = model.predict(data_in)
model.score(X, Y)
print(yhat[0])
[10.96199994 10.57600012]
XGBoost回歸
XGBoost是boosting算法的其中一種。Boosting算法的思想是將許多弱分類器集成在一起形成一個(gè)強(qiáng)分類器。因?yàn)閄GBoost是一種提升樹模型,所以它是將許多樹模型集成在一起,形成一個(gè)很強(qiáng)的分類器。而所用到的樹模型則是CART回歸樹模型。
回歸樹的生成步驟如下
- 從根節(jié)點(diǎn)開始分裂。
- 節(jié)點(diǎn)分裂之前,計(jì)算所有可能的特征及它們所有可能的切分點(diǎn)分裂后的平方誤差(結(jié)構(gòu)分?jǐn)?shù)之差)。
- 如果所有的平方誤差均相同或減小值小于某一閾值,或者節(jié)點(diǎn)包含的樣本數(shù)小于某一閾值,則分裂停止;否則,選擇使平方誤差最小的特征和切分點(diǎn)作為最優(yōu)特征和最優(yōu)切分點(diǎn)進(jìn)行分裂,并生成兩個(gè)子節(jié)點(diǎn)。
- 對(duì)于每一個(gè)新生成的子節(jié)點(diǎn),遞歸執(zhí)行步驟2和步驟3,直到滿足停止條件。
算法原理
不斷地添加樹,不斷地進(jìn)行特征分裂來生長一棵樹,每次添加一個(gè)樹,其實(shí)是學(xué)習(xí)一個(gè)新函數(shù),去擬合上次預(yù)測(cè)的殘差
當(dāng)我們訓(xùn)練完成得到k棵樹,我們要預(yù)測(cè)一個(gè)樣本的分?jǐn)?shù),其實(shí)就是根據(jù)這個(gè)樣本的特征,在每棵樹中會(huì)落到對(duì)應(yīng)的一個(gè)葉子節(jié)點(diǎn),每個(gè)葉子節(jié)點(diǎn)就對(duì)應(yīng)一個(gè)分?jǐn)?shù)
最后只需要將每棵樹對(duì)應(yīng)的分?jǐn)?shù)加起來就是該樣本的預(yù)測(cè)值。
XGB vs GBDT 核心區(qū)別:求解預(yù)測(cè)值的方式不同
GBDT中 預(yù)測(cè)值是由所有弱分類器上的預(yù)測(cè)結(jié)果的加權(quán)求和 ,其中每個(gè)樣本上的預(yù)測(cè)結(jié)果就是樣本所在的葉子節(jié)點(diǎn)的均值。
而XGBT中的 預(yù)測(cè)值是所有弱分類器上的葉子權(quán)重直接求和得到。 這個(gè)葉子權(quán)重就是所有在這個(gè)葉子節(jié)點(diǎn)上的樣本在這一棵樹上的回歸取值,用或者來表示,其中表示第棵決策樹, 表示樣本對(duì)應(yīng)的特征向量
目標(biāo)函數(shù)
第一項(xiàng)是衡量我們的偏差,模型越不準(zhǔn)確,第一項(xiàng)就會(huì)越大。第二項(xiàng)是衡量我們的方差,模型越復(fù)雜,模型的學(xué)習(xí)就會(huì)越具體,到不同數(shù)據(jù)集上的表現(xiàn)就會(huì)差異巨大,方差就會(huì)越大。
代碼實(shí)現(xiàn)
X = dataset[['Open', 'High', 'Low', 'Volume']].values
y = dataset['Adj Close'].values
from xgboost import XGBRegressor
xgb = XGBRegressor(max_depth=5, learning_rate=0.01, n_estimators=2000, colsample_bytree=0.1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)
xgb.fit(X_train,y_train)
y_pred = xgb.predict(X_test)
xgb.score(X_test, y_test)
人工神經(jīng)網(wǎng)絡(luò)
深度神經(jīng)網(wǎng)絡(luò)(DNN)回歸器
- 3層: 輸入、隱藏和輸出
- 特征: 輸入數(shù)據(jù)到網(wǎng)絡(luò)(特征)
- 標(biāo)簽: 網(wǎng)絡(luò)輸出(標(biāo)簽)
- 損失函數(shù): 用于估計(jì)學(xué)習(xí)階段的性能的度量
- 優(yōu)化器: 通過更新網(wǎng)絡(luò)中的知識(shí)來提高學(xué)習(xí)效果
數(shù)據(jù)準(zhǔn)備
X = dataset.drop(['Adj Close', 'Close'], axis=1)
y = dataset['Adj Close']
# 數(shù)據(jù)劃分略
y_train = y_train.astype(int)
y_test = y_test.astype(int)
batch_size =len(X_train)
數(shù)據(jù)轉(zhuǎn)換
## 數(shù)據(jù)歸一化
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
# Train
X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))
# test
X_test_scaled = scaler.fit_transform(X_test.astype(np.float64))
tensorflow結(jié)構(gòu)
import tensorflow as tf
feature_columns = [tf.feature_column.numeric_column('x', shape=X_train_scaled.shape[1:])]
建模
estimator = tf.estimator.DNNRegressor(
feature_columns=feature_columns,
hidden_units=[300, 100])
# 訓(xùn)練模型
train_input = tf.estimator.inputs.numpy_input_fn(
x={"x": X_train_scaled},
y=y_train,
batch_size=50,
shuffle=False,
num_epochs=None)
estimator.train(input_fn = train_input,steps=1000)
eval_input = tf.estimator.inputs.numpy_input_fn(
x={"x": X_test_scaled},
y=y_test,
shuffle=False,
batch_size=X_test_scaled.shape[0],
num_epochs=1)
estimator.evaluate(eval_input,steps=None)
>> >
{'average_loss': 6.4982734,
'global_step': 1000,
'loss': 1527.0942}
好了今天的總結(jié)就到這里,沒看夠到我們后面再見~
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4344瀏覽量
62813 -
模型
+關(guān)注
關(guān)注
1文章
3279瀏覽量
48978 -
機(jī)器學(xué)習(xí)
+關(guān)注
關(guān)注
66文章
8428瀏覽量
132850 -
Adaboost算法
+關(guān)注
關(guān)注
0文章
5瀏覽量
1345
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論