混合密度網(wǎng)絡(luò)(MDN)進(jìn)行多元回歸詳解和代碼示例(2)
兩個(gè)模型都沒(méi)有成功的主要原因是:對(duì)于同一個(gè) X 值存在多個(gè)不同的 y 值……更具體地說(shuō),對(duì)于同一個(gè) X 似乎存在不止一個(gè)可能的 y 分布?;貧w模型只是試圖找到最小化誤差的最優(yōu)函數(shù),并沒(méi)有考慮到密度的混合,所以 中間的那些X沒(méi)有唯一的Y解,它們有兩種可能的解,所以導(dǎo)致了以上的問(wèn)題。
現(xiàn)在讓我們嘗試一個(gè) MDN 模型,這里已經(jīng)實(shí)現(xiàn)了一個(gè)快速且易于使用的“fit-predict”、“sklearn alike”自定義 python MDN 類(lèi)。如果您想自己使用它,這是 python 代碼的鏈接(請(qǐng)注意:這個(gè) MDN 類(lèi)是實(shí)驗(yàn)性的,尚未經(jīng)過(guò)廣泛測(cè)試):https://github.com/CoteDave/blog/blob/master/Made%20easy/MDN%20regression/mdn_model.py
為了能夠使用這個(gè)類(lèi),有 sklearn、tensorflow probability、Tensorflow < 2、umap 和 hdbscan(用于自定義可視化類(lèi) 功能)。
EPOCHS = 10000
BATCH_SIZE=len(X)
model = MDN(n_mixtures = -1,
dist = 'laplace',
input_neurons = 1000,
hidden_neurons = [25],
gmm_boost = False,
optimizer = 'adam',
learning_rate = 0.001,
early_stopping = 250,
tf_mixture_family = True,
input_activation = 'relu',
hidden_activation = 'leaky_relu')
model.fit(X, y, epochs = EPOCHS, batch_size = BATCH_SIZE)
類(lèi)的參數(shù)總結(jié)如下:
n_mixtures:MDN 使用的分布混合數(shù)。如果設(shè)置為 -1,它將使用高斯混合模型 (GMM) 和 X 和 y 上的 HDBSCAN 模型“自動(dòng)”找到最佳混合數(shù)。
dist:在混合中使用的分布類(lèi)型。目前,有兩種選擇;“正常”或“拉普拉斯”。(基于一些實(shí)驗(yàn),拉普拉斯分布比正態(tài)分布更好的結(jié)果)。
input_neurons:在MDN的輸入層中使用的神經(jīng)元數(shù)量
hidden_neurons:MDN的 隱藏層架構(gòu)。每個(gè)隱藏層的神經(jīng)元列表。此參數(shù)使您能夠選擇隱藏層的數(shù)量和每個(gè)隱藏層的神經(jīng)元數(shù)量。
gmm_boost:布爾值。如果設(shè)置為 True,將向數(shù)據(jù)集添加簇特征。
optimizer:要使用的優(yōu)化算法。
learning_rate:優(yōu)化算法的學(xué)習(xí)率
early_stopping:避免訓(xùn)練時(shí)過(guò)擬合。當(dāng)指標(biāo)在給定數(shù)量的時(shí)期內(nèi)沒(méi)有變化時(shí),此觸發(fā)器將決定何時(shí)停止訓(xùn)練。
tf_mixture_family:布爾值。如果設(shè)置為 True,將使用 tf_mixture 系列(推薦):Mixture 對(duì)象實(shí)現(xiàn)批量混合分布。
input_activation:輸入層的激活函數(shù)
hidden_activation:隱藏層的激活函數(shù)
現(xiàn)在 MDN 模型已經(jīng)擬合了數(shù)據(jù),從混合密度分布中采樣并繪制概率密度函數(shù):
model.plot_distribution_fit(n_samples_batch = 1)
我們的 MDN 模型非常適合真正的一般分布!下面將最終的混合分布分解為每個(gè)分布,看看它的樣子:
model.plot_all_distribution_fit(n_samples_batch = 1)
使用學(xué)習(xí)到的混合分布再次采樣一些 Y 數(shù)據(jù),生成的樣本與真實(shí)樣本進(jìn)行對(duì)比:
model.plot_samples_vs_true(X, y, alpha = 0.2)
與實(shí)際的數(shù)據(jù)非常接近,如果,給定 X還可以生成多批樣本以生成分位數(shù)、均值等統(tǒng)計(jì)信息:
generated_samples = model.sample_from_mixture(X, n_samples_batch = 10)
generated_samples
繪制每個(gè)學(xué)習(xí)分布的平均值,以及它們各自的混合權(quán)重 (pi):
plt.scatter(X, y, alpha = 0.2)
model.plot_predict_dist(X, with_weights = True, size = 250)
有每個(gè)分布的均值和標(biāo)準(zhǔn)差,還可以繪制帶有完整不確定性;假設(shè)我們以 95% 的置信區(qū)間繪制平均值:
plt.scatter(X, y, alpha = 0.2)
model.plot_predict_dist(X, q = 0.95, with_weights = False)
將分布混合在一起,當(dāng)對(duì)同一個(gè) X 有多個(gè) y 分布時(shí),我們使用最高 Pi 參數(shù)值選擇最可能的混合:
Y_preds = 對(duì)于每個(gè) X,選擇具有最大概率/權(quán)重(Pi 參數(shù))的分布的 Y 均值
plt.scatter(X, y, alpha = 0.3)
model.plot_predict_best(X)
這種方式表現(xiàn)得并不理想,因?yàn)樵跀?shù)據(jù)中顯然有兩個(gè)不同的簇重疊,密度幾乎相等。使得誤差將高于標(biāo)準(zhǔn)回歸模型。這也意味著數(shù)據(jù)集中可能缺少一個(gè)可以幫助避免集群在更高維度上重疊重要特征。
我們還可以選擇使用 Pi 參數(shù)和所有分布的均值混合分布:
· Y_preds = (mean_1 * Pi1) + (mean_2 * Pi2)
plt.scatter(X, y, alpha = 0.3)
model.plot_predict_mixed(X)
如果我們添加 95 置信區(qū)間:
這個(gè)選項(xiàng)提供了與非線(xiàn)性回歸模型幾乎相同的結(jié)果,混合所有內(nèi)容以最小化點(diǎn)和函數(shù)之間的距離。在這個(gè)非常特殊的情況下,我最喜歡的選擇是假設(shè)在數(shù)據(jù)的某些區(qū)域,X 有多個(gè) Y,而在其他區(qū)域;僅使用其中一種混合。:
例如,當(dāng) X = 0 時(shí),每種混合可能有兩種不同的 Y 解。當(dāng) X = -1.5 時(shí),混合 1 中存在唯一的 Y 解決方案。根據(jù)用例或業(yè)務(wù)上下文,當(dāng)同一個(gè) X 存在多個(gè)解決方案時(shí),可以觸發(fā)操作或決策。
這個(gè)選項(xiàng)得含義是當(dāng)存在重疊分布時(shí)(如果兩個(gè)混合概率都 >= 給定概率閾值),行將被復(fù)制:
plt.scatter(X, y, alpha = 0.3)
model.plot_predict_with_overlaps(X)
使用 95% 置信區(qū)間:
數(shù)據(jù)集行從 2500 增加到了 4063,最終預(yù)測(cè)數(shù)據(jù)集如下所示:
在這個(gè)數(shù)據(jù)表中,當(dāng) X = -0.276839 時(shí),Y 可以是 1.43926(混合_0 的概率為 0.351525),但也可以是 -0.840593(混合_1 的概率為 0.648475)。
具有多個(gè)分布的實(shí)例還提供了重要信息,即數(shù)據(jù)中正在發(fā)生某些事情,并且可能需要更多分析??赡苁且恍?shù)據(jù)質(zhì)量問(wèn)題,或者可能表明數(shù)據(jù)集中缺少一個(gè)重要特征!
“交通場(chǎng)景預(yù)測(cè)是可以使用混合密度網(wǎng)絡(luò)的一個(gè)很好的例子。在交通場(chǎng)景預(yù)測(cè)中,我們需要一個(gè)可以表現(xiàn)出的行為分布——例如,一個(gè)代理可以左轉(zhuǎn)、右轉(zhuǎn)或直行。因此,混合密度網(wǎng)絡(luò)可用于表示它學(xué)習(xí)的每個(gè)混合中的“行為”,其中行為由概率和軌跡組成((x,y)坐標(biāo)在未來(lái)某個(gè)時(shí)間范圍內(nèi))。
示例2:具有MDN 的多變量回歸
最后MDN 在多元回歸問(wèn)題上表現(xiàn)良好嗎?
我們將使用以下的數(shù)據(jù)集:
年齡:主要受益人的年齡
性別:保險(xiǎn)承包商性別,女,男
bmi:體重指數(shù),提供對(duì)身體的了解,相對(duì)于身高相對(duì)較高或較低的體重,使用身高與體重之比的體重客觀(guān)指數(shù)(kg / m ^ 2),理想情況下為18.5到24.9
子女:健康保險(xiǎn)覆蓋的子女人數(shù)/受撫養(yǎng)人人數(shù)
吸煙者:吸煙
地區(qū):受益人在美國(guó)、東北、東南、西南、西北的居住區(qū)。
費(fèi)用:由健康保險(xiǎn)計(jì)費(fèi)的個(gè)人醫(yī)療費(fèi)用。這是我們要預(yù)測(cè)的目標(biāo)
問(wèn)題陳述是:能否準(zhǔn)確預(yù)測(cè)保險(xiǎn)費(fèi)用(收費(fèi))?
現(xiàn)在,讓我們導(dǎo)入數(shù)據(jù)集:
"""
#################
# 2-IMPORT DATA #
#################
"""
dataset = pd.read_csv('insurance_clean.csv', sep = ';')
##### BASIC FEATURE ENGINEERING
dataset['age2'] = dataset['age'] * dataset['age']
dataset['BMI30'] = np.where(dataset['bmi'] > 30, 1, 0)
dataset['BMI30_SMOKER'] = np.where((dataset['bmi'] > 30) & (dataset['smoker_yes'] == 1), 1, 0)
"""
######################
# 3-DATA PREPARATION #
######################
"""
###### SPLIT TRAIN TEST
from sklearn.model_selection import train_test_split
X = dataset[dataset.columns.difference(['charges'])]
y = dataset[['charges']]
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.25,
stratify = X['smoker_yes'],
random_state=0)
test_index = y_test.index.values
train_index = y_train.index.values
features = X.columns.tolist()
##### FEATURE SCALING
from sklearn.preprocessing import StandardScaler
x_scaler = StandardScaler()
y_scaler = StandardScaler()
X_train = x_scaler.fit_transform(X_train)
#X_calib = x_scaler.transform(X_calib)
X_test = x_scaler.transform(X_test)
y_train = y_scaler.fit_transform(y_train)
#y_calib = y_scaler.transform(y_calib)
y_test = y_scaler.transform(y_test)
y_test_scaled = y_test.copy()
數(shù)據(jù)準(zhǔn)備完整可以開(kāi)始訓(xùn)練了
EPOCHS = 10000
BATCH_SIZE=len(X_train)
model = MDN(n_mixtures = -1, #-1
dist = 'laplace',
input_neurons = 1000, #1000
hidden_neurons = [], #25
gmm_boost = False,
optimizer = 'adam',
learning_rate = 0.0001, #0.00001
early_stopping = 200,
tf_mixture_family = True,
input_activation = 'relu',
hidden_activation = 'leaky_relu')
model.fit(X_train, y_train, epochs = EPOCHS, batch_size = BATCH_SIZE)
訓(xùn)練完成后使用“最佳混合概率(Pi 參數(shù))策略”預(yù)測(cè)測(cè)試數(shù)據(jù)集并繪制結(jié)果(y_pred vs y_test):
y_pred = model.predict_best(X_test, q = 0.95, y_scaler = y_scaler)
model.plot_pred_fit(y_pred, y_test, y_scaler = y_scaler)
model.plot_pred_vs_true(y_pred, y_test, y_scaler = y_scaler)
R2 為 89.09,MAE 為 882.54,MDN太棒了,讓我們繪制擬合分布與真實(shí)分布的圖來(lái)進(jìn)行對(duì)比:
model.plot_distribution_fit(n_samples_batch = 1)
幾乎一模一樣!分解混合模型,看看什么情況:
一共混合了六種不同的分布。
從擬合的混合模型生成多變量樣本(應(yīng)用 PCA 以在 2D 中可視化結(jié)果):
model.plot_samples_vs_true(X_test, y_test, alpha = 0.35, y_scaler = y_scaler)
生成的樣本與真實(shí)樣本非常接近!如果我們?cè)敢?,還可以從每個(gè)分布中進(jìn)行預(yù)測(cè):
y_pred_dist = model.predict_dist(X_test, q = 0.95, y_scaler = y_scaler)
y_pred_dist
總結(jié)
與線(xiàn)性或非線(xiàn)性經(jīng)典 ML 模型相比,MDN 在單變量回歸數(shù)據(jù)集中表現(xiàn)出色,其中兩個(gè)簇相互重疊,并且 X 可能有多個(gè) Y 輸出。
MDN 在多元回歸問(wèn)題上也做得很好,可以與 XGBoost 等流行模型競(jìng)爭(zhēng)
MDN 是 ML 中的一款出色且獨(dú)特的工具,可以解決其他模型無(wú)法解決的特定問(wèn)題(能夠從混合分布中獲得的數(shù)據(jù)中學(xué)習(xí))
隨著 MDN 學(xué)習(xí)分布,還可以通過(guò)預(yù)測(cè)計(jì)算不確定性或從學(xué)習(xí)的分布中生成新樣本
本文的代碼非常的多,這里是完整的notebook,可以直接下載運(yùn)行:
https://github.com/CoteDave/blog/blob/master/Made%20easy/MDN%20regression/Made%20easy%20-%20MDN%20regression.ipynb
*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。
電子鎮(zhèn)流器相關(guān)文章:電子鎮(zhèn)流器工作原理
色差儀相關(guān)文章:色差儀原理