ある数値を予測するコンペの問題をPythonでやってます。

与えられた訓練データから使えそうな特徴量だけを取り出し、同様にテストデータから訓練データと同じ特徴量を取り出しました。

https://www.kaggle.com/serigne/stacked-regressions-top-4-on-leaderboard/notebook
上記を参考にして、取り出したデータをもとにLASSO Regression、Elastic Net Regression、Kernel Ridge Regression、Gradient Boosting Regression、XGBoost、LightGBMで予測値を出し、それぞれの予測値も特徴量として追加しました。

それらの特徴量をもとに訓練7:評価3に分割し、学習させたところ、R2Scoreが0.85, train lossが0.1378、validation lossが0.1248 程になりました。
この学習器でテストデータを予測したのですが、R2Scoreは0.55になりました。

訓練データとテストデータの特徴量はどれもstats.shapiro()を使うとp値が0か限りなく0に近くなり、正規分布であると思います。
訓練データで目的の値にしたものも同様でした。
また、最大値、最小値にも差はほぼありませんでした。

訓練(評価)データとテストデータで評価結果が異なる理由が知りたいです。
また、交差検証以外で汎化性能を上げる方法が知りたいです。
以下はあってるかわかりませんが交差検証したコードです。

X = train[cat_vars+cont_vars+['xgb', 'lgb', 'stacked', 'ensemble']]
y = train[['Score']]

X_train, X_test, Y_train, Y_test = train_test_split(X, y, train_size = 0.7, test_size = 0.3, random_state = 0)
lr = LinearRegression()
kf = KFold(n_splits = 5,shuffle = True,random_state = 1)
lr.fit(X, y)
splitter = kf.split(X,y)
print(cross_val_score(lr,X,y,cv = splitter, scoring='r2'))

結果

[0.888343 0.885379 0.891729 0.881329 0.899762]