本文是对kaggle比赛的总结贴,主要是对已有的方法进行尝试。比赛网址为https://www.kaggle.com/c/LANL-Earthquake-Prediction。
部分内容参考了如何在Kaggle首战中进入前10%
本次比赛是采用的实验室的模拟地震的数据,我们需要根据现有的数据预测还有多长时间会发生下一次地震,本次比赛用的是kaggle的kernel来写代码(类似于jupyter的运行环境,可以避免自己配置本地环境的烦恼),训练数据比较大,有2GB,在普通的PC机上估计读数据都挺费劲的,申请的kernel里面有16g的内存,未加任何参数的的读取方式直接就占满内存,重启kernel了,所以读取数据的时候做了一下简单的处理,后续会整理一个python处理大数据文件的方法。
一般的机器学习系统构建过程包括下面几部分:
数据的可视化,数据的处理,特征的选取或组合,模型的构建,模型的训练,交叉验证,模型的融合等。
数据的可视化主要是为了初步了解数据的一些基本特征,方便后续的数据处理过程。为此,我们首先读取数据,并且采用16位的方式读取。
# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load in
import gc
import os
import time
import logging
import datetime
import warnings
import numpy as np
import pandas as pd
import seaborn as sns
import xgboost as xgb
import lightgbm as lgb
from scipy import stats
from scipy.signal import hann
from tqdm import tqdm_notebook
import matplotlib.pyplot as plt
from scipy.signal import hilbert
from scipy.signal import convolve
from sklearn.svm import NuSVR, SVR
from catboost import CatBoostRegressor
from sklearn.kernel_ridge import KernelRidge
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import mean_absolute_error
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import KFold,StratifiedKFold, RepeatedKFold
warnings.filterwarnings("ignore")
import os
print(os.listdir("../input"))
# Any results you write to the current directory are saved as output.
%%time
train = pd.read_csv('../input/train.csv', dtype={'acoustic_data': np.int16, 'time_to_failure': np.float32})
我们首先来看一下数据的规模有多大,方便后期的模型选择。
print("Train: rows:{} cols:{}".format(train.shape[0], train.shape[1]))
数据量比较大,有6亿多行记录,但是一共只有两列,让我们再看一下具体的数据是什么,我们先用train.head()
来看一下训练数据的一些基本特征和标签
pd.options.display.precision = 15
train.head(10)
然后可以看到下面的这张图,只有一个特征和一个输出,acoustic_data
是实验室测得的声音的数据,time_to_failure
就是还有多长时间会发生地震,直觉不应该是这么简单的,所以我们需要多看一些数据或者画出更多的数据。
我们来对数据进行采样,画出1%的采样数据看看整体数据的趋势是什么样子的
train_acoustic_data_small = train['acoustic_data'].values[::100]
train_time_to_failure_small = train['time_to_failure'].values[::100]
fig, ax1 = plt.subplots(figsize=(16, 8))
plt.title("Trends of acoustic_data and time_to_failure. 2% of data (sampled)")
plt.plot(train_acoustic_data_small, color='b')
ax1.set_ylabel('acoustic_data', color='b')
plt.legend(['acoustic_data'])
ax2 = ax1.twinx()
plt.plot(train_time_to_failure_small, color='g')
ax2.set_ylabel('time_to_failure', color='g')
plt.legend(['time_to_failure'], loc=(0.875, 0.9))
plt.grid(False)
del train_acoustic_data_small
del train_time_to_failure_small
这样就清楚多了,可以看出来,每一次较尖锐的波峰之后,time就降为0,说明发生了地震了,这可以为之后的预测问题提供一个很好的依据。下面我们来仔细的看一下前2000万(大约是1/30的数据量)的数据是什么样子的。
train_acoustic_data_small = train['acoustic_data'].values[0:20000000]
train_time_to_failure_small = train['time_to_failure'].values[0:20000000]
fig, ax1 = plt.subplots(figsize=(16, 8))
plt.title("Trends of acoustic_data and time_to_failure. 2% of data (sampled)")
plt.plot(train_acoustic_data_small, color='b')
ax1.set_ylabel('acoustic_data', color='b')
plt.legend(['acoustic_data'])
ax2 = ax1.twinx()
plt.plot(train_time_to_failure_small, color='g')
ax2.set_ylabel('time_to_failure', color='g')
plt.legend(['time_to_failure'], loc=(0.875, 0.9))
plt.grid(False)
del train_acoustic_data_small
del train_time_to_failure_small
train_acoustic_data_small = train['acoustic_data'].values[0:1000]
train_time_to_failure_small = train['time_to_failure'].values[0:1000]
fig, ax1 = plt.subplots(figsize=(16, 8))
plt.title("Trends of acoustic_data and time_to_failure. 2% of data (sampled)")
plt.plot(train_acoustic_data_small, color='b')
ax1.set_ylabel('acoustic_data', color='b')
plt.legend(['acoustic_data'])
ax2 = ax1.twinx()
plt.plot(train_time_to_failure_small, color='g')
ax2.set_ylabel('time_to_failure', color='g')
plt.legend(['time_to_failure'], loc=(0.875, 0.9))
plt.grid(False)
del train_acoustic_data_small
del train_time_to_failure_small
接下来让我们来看看这些数据有没有缺失,毕竟处理一些缺失值和异常值还是挺麻烦的。
stats = []
for col in train.columns:
stats.append((col, train[col].isnull().sum() * 100 / train.shape[0]))
stats_df = pd.DataFrame(stats, columns=['column', 'percentage of missing'])
stats_df
del stats
del stats_df
可以看到数据非常好,没有缺失值,我们接下来就开始做特征工程了。
只有一列输入信号和一列目标值,是不是我们的特征工程就不用做了,很显然不是。接下来我们需要仔细的看看这一列输入信号究竟是什么含义了。实际上来说,要想有一个好的预测结果,要对特征和特征之间的组合有明确的认识,如果有相关的背景知识是最好的。如果直接从原始特征出发的话,也会有结果,但准确率应该不会特别高。
我们来看一下这一列输入信号的背景。https://www.nature.com/articles/ncomms11104.pdf是这个地震模拟实验的详细介绍,基本原理如下:
好像没有获得什么有用的信息,提供的训练集是周期性的数据,而测试集大多是非周期性的数据。这时候就需要各显神通,开始组合特征了。我们先看看测试集的数据。
test_path = "../input/test/"
test_files = os.listdir("../input/test")
fig, ax = plt.subplots(4,1, figsize=(20,25))
for n in range(4):
seg = pd.read_csv(test_path + test_files[n])
ax[n].plot(seg.acoustic_data.values, c="mediumseagreen")
ax[n].set_xlabel("Index")
ax[n].set_ylabel("Signal")
ax[n].set_ylim([-300, 300])
ax[n].set_title("Test {}".format(test_files[n]));
测试数据的前四个看起来和训练集的数据看起来很不一样,每一个信号一共是150000个样本点,特征处理实际上是最考验选手的功底的,我们接下来构造一些统计学上的特征。我们把训练数据划分成和测试集一样的维度,看看能划分成多少个。
rows = 150000
segments = int(np.floor(train.shape[0] / rows))
print("Number of segments: ", segments)
一共有4194个,然后我们来定义一些有用的函数
def add_trend_feature(arr, abs_values=False):
idx = np.array(range(len(arr)))
if abs_values:
arr = np.abs(arr)
lr = LinearRegression()
lr.fit(idx.reshape(-1, 1), arr)
return lr.coef_[0]
def classic_sta_lta(x, length_sta, length_lta):
sta = np.cumsum(x ** 2)
# Convert to float
sta = np.require(sta, dtype=np.float)
# Copy for LTA
lta = sta.copy()
# Compute the STA and the LTA
sta[length_sta:] = sta[length_sta:] - sta[:-length_sta]
sta /= length_sta
lta[length_lta:] = lta[length_lta:] - lta[:-length_lta]
lta /= length_lta
# Pad zeros
sta[:length_lta - 1] = 0
# Avoid division by zero by setting zero values to tiny float
dtiny = np.finfo(0.0).tiny
idx = lta < dtiny
lta[idx] = dtiny
return sta / lta
处理一下训练数据
train_X = pd.DataFrame(index=range(segments), dtype=np.float64)
train_y = pd.DataFrame(index=range(segments), dtype=np.float64, columns=['time_to_failure'])
total_mean = train['acoustic_data'].mean()
total_std = train['acoustic_data'].std()
total_max = train['acoustic_data'].max()
total_min = train['acoustic_data'].min()
total_sum = train['acoustic_data'].sum()
total_abs_sum = np.abs(train['acoustic_data']).sum()
def create_features(seg_id, seg, X):
xc = pd.Series(seg['acoustic_data'].values)
zc = np.fft.fft(xc)
X.loc[seg_id, 'mean'] = xc.mean()
X.loc[seg_id, 'std'] = xc.std()
X.loc[seg_id, 'max'] = xc.max()
X.loc[seg_id, 'min'] = xc.min()
#FFT transform values
realFFT = np.real(zc)
imagFFT = np.imag(zc)
X.loc[seg_id, 'Rmean'] = realFFT.mean()
X.loc[seg_id, 'Rstd'] = realFFT.std()
X.loc[seg_id, 'Rmax'] = realFFT.max()
X.loc[seg_id, 'Rmin'] = realFFT.min()
X.loc[seg_id, 'Imean'] = imagFFT.mean()
X.loc[seg_id, 'Istd'] = imagFFT.std()
X.loc[seg_id, 'Imax'] = imagFFT.max()
X.loc[seg_id, 'Imin'] = imagFFT.min()
X.loc[seg_id, 'Rmean_last_5000'] = realFFT[-5000:].mean()
X.loc[seg_id, 'Rstd__last_5000'] = realFFT[-5000:].std()
X.loc[seg_id, 'Rmax_last_5000'] = realFFT[-5000:].max()
X.loc[seg_id, 'Rmin_last_5000'] = realFFT[-5000:].min()
X.loc[seg_id, 'Rmean_last_15000'] = realFFT[-15000:].mean()
X.loc[seg_id, 'Rstd_last_15000'] = realFFT[-15000:].std()
X.loc[seg_id, 'Rmax_last_15000'] = realFFT[-15000:].max()
X.loc[seg_id, 'Rmin_last_15000'] = realFFT[-15000:].min()
X.loc[seg_id, 'mean_change_abs'] = np.mean(np.diff(xc))
X.loc[seg_id, 'mean_change_rate'] = np.mean(np.nonzero((np.diff(xc) / xc[:-1]))[0])
X.loc[seg_id, 'abs_max'] = np.abs(xc).max()
X.loc[seg_id, 'abs_min'] = np.abs(xc).min()
X.loc[seg_id, 'std_first_50000'] = xc[:50000].std()
X.loc[seg_id, 'std_last_50000'] = xc[-50000:].std()
X.loc[seg_id, 'std_first_10000'] = xc[:10000].std()
X.loc[seg_id, 'std_last_10000'] = xc[-10000:].std()
X.loc[seg_id, 'avg_first_50000'] = xc[:50000].mean()
X.loc[seg_id, 'avg_last_50000'] = xc[-50000:].mean()
X.loc[seg_id, 'avg_first_10000'] = xc[:10000].mean()
X.loc[seg_id, 'avg_last_10000'] = xc[-10000:].mean()
X.loc[seg_id, 'min_first_50000'] = xc[:50000].min()
X.loc[seg_id, 'min_last_50000'] = xc[-50000:].min()
X.loc[seg_id, 'min_first_10000'] = xc[:10000].min()
X.loc[seg_id, 'min_last_10000'] = xc[-10000:].min()
X.loc[seg_id, 'max_first_50000'] = xc[:50000].max()
X.loc[seg_id, 'max_last_50000'] = xc[-50000:].max()
X.loc[seg_id, 'max_first_10000'] = xc[:10000].max()
X.loc[seg_id, 'max_last_10000'] = xc[-10000:].max()
X.loc[seg_id, 'max_to_min'] = xc.max() / np.abs(xc.min())
X.loc[seg_id, 'max_to_min_diff'] = xc.max() - np.abs(xc.min())
X.loc[seg_id, 'count_big'] = len(xc[np.abs(xc) > 500])
X.loc[seg_id, 'sum'] = xc.sum()
X.loc[seg_id, 'mean_change_rate_first_50000'] = np.mean(np.nonzero((np.diff(xc[:50000]) / xc[:50000][:-1]))[0])
X.loc[seg_id, 'mean_change_rate_last_50000'] = np.mean(np.nonzero((np.diff(xc[-50000:]) / xc[-50000:][:-1]))[0])
X.loc[seg_id, 'mean_change_rate_first_10000'] = np.mean(np.nonzero((np.diff(xc[:10000]) / xc[:10000][:-1]))[0])
X.loc[seg_id, 'mean_change_rate_last_10000'] = np.mean(np.nonzero((np.diff(xc[-10000:]) / xc[-10000:][:-1]))[0])
X.loc[seg_id, 'q95'] = np.quantile(xc, 0.95)
X.loc[seg_id, 'q99'] = np.quantile(xc, 0.99)
X.loc[seg_id, 'q05'] = np.quantile(xc, 0.05)
X.loc[seg_id, 'q01'] = np.quantile(xc, 0.01)
X.loc[seg_id, 'abs_q95'] = np.quantile(np.abs(xc), 0.95)
X.loc[seg_id, 'abs_q99'] = np.quantile(np.abs(xc), 0.99)
X.loc[seg_id, 'abs_q05'] = np.quantile(np.abs(xc), 0.05)
X.loc[seg_id, 'abs_q01'] = np.quantile(np.abs(xc), 0.01)
X.loc[seg_id, 'trend'] = add_trend_feature(xc)
X.loc[seg_id, 'abs_trend'] = add_trend_feature(xc, abs_values=True)
X.loc[seg_id, 'abs_mean'] = np.abs(xc).mean()
X.loc[seg_id, 'abs_std'] = np.abs(xc).std()
X.loc[seg_id, 'mad'] = xc.mad()
X.loc[seg_id, 'kurt'] = xc.kurtosis()
X.loc[seg_id, 'skew'] = xc.skew()
X.loc[seg_id, 'med'] = xc.median()
X.loc[seg_id, 'Hilbert_mean'] = np.abs(hilbert(xc)).mean()
X.loc[seg_id, 'Hann_window_mean'] = (convolve(xc, hann(150), mode='same') / sum(hann(150))).mean()
X.loc[seg_id, 'classic_sta_lta1_mean'] = classic_sta_lta(xc, 500, 10000).mean()
X.loc[seg_id, 'classic_sta_lta2_mean'] = classic_sta_lta(xc, 5000, 100000).mean()
X.loc[seg_id, 'classic_sta_lta3_mean'] = classic_sta_lta(xc, 3333, 6666).mean()
X.loc[seg_id, 'classic_sta_lta4_mean'] = classic_sta_lta(xc, 10000, 25000).mean()
X.loc[seg_id, 'Moving_average_700_mean'] = xc.rolling(window=700).mean().mean(skipna=True)
X.loc[seg_id, 'Moving_average_1500_mean'] = xc.rolling(window=1500).mean().mean(skipna=True)
X.loc[seg_id, 'Moving_average_3000_mean'] = xc.rolling(window=3000).mean().mean(skipna=True)
X.loc[seg_id, 'Moving_average_6000_mean'] = xc.rolling(window=6000).mean().mean(skipna=True)
ewma = pd.Series.ewm
X.loc[seg_id, 'exp_Moving_average_300_mean'] = (ewma(xc, span=300).mean()).mean(skipna=True)
X.loc[seg_id, 'exp_Moving_average_3000_mean'] = ewma(xc, span=3000).mean().mean(skipna=True)
X.loc[seg_id, 'exp_Moving_average_30000_mean'] = ewma(xc, span=6000).mean().mean(skipna=True)
no_of_std = 2
X.loc[seg_id, 'MA_700MA_std_mean'] = xc.rolling(window=700).std().mean()
X.loc[seg_id,'MA_700MA_BB_high_mean'] = (X.loc[seg_id, 'Moving_average_700_mean'] + no_of_std * X.loc[seg_id, 'MA_700MA_std_mean']).mean()
X.loc[seg_id,'MA_700MA_BB_low_mean'] = (X.loc[seg_id, 'Moving_average_700_mean'] - no_of_std * X.loc[seg_id, 'MA_700MA_std_mean']).mean()
X.loc[seg_id, 'MA_400MA_std_mean'] = xc.rolling(window=400).std().mean()
X.loc[seg_id,'MA_400MA_BB_high_mean'] = (X.loc[seg_id, 'Moving_average_700_mean'] + no_of_std * X.loc[seg_id, 'MA_400MA_std_mean']).mean()
X.loc[seg_id,'MA_400MA_BB_low_mean'] = (X.loc[seg_id, 'Moving_average_700_mean'] - no_of_std * X.loc[seg_id, 'MA_400MA_std_mean']).mean()
X.loc[seg_id, 'MA_1000MA_std_mean'] = xc.rolling(window=1000).std().mean()
X.loc[seg_id, 'iqr'] = np.subtract(*np.percentile(xc, [75, 25]))
X.loc[seg_id, 'q999'] = np.quantile(xc,0.999)
X.loc[seg_id, 'q001'] = np.quantile(xc,0.001)
X.loc[seg_id, 'ave10'] = stats.trim_mean(xc, 0.1)
for windows in [10, 100, 1000]:
x_roll_std = xc.rolling(windows).std().dropna().values
x_roll_mean = xc.rolling(windows).mean().dropna().values
X.loc[seg_id, 'ave_roll_std_' + str(windows)] = x_roll_std.mean()
X.loc[seg_id, 'std_roll_std_' + str(windows)] = x_roll_std.std()
X.loc[seg_id, 'max_roll_std_' + str(windows)] = x_roll_std.max()
X.loc[seg_id, 'min_roll_std_' + str(windows)] = x_roll_std.min()
X.loc[seg_id, 'q01_roll_std_' + str(windows)] = np.quantile(x_roll_std, 0.01)
X.loc[seg_id, 'q05_roll_std_' + str(windows)] = np.quantile(x_roll_std, 0.05)
X.loc[seg_id, 'q95_roll_std_' + str(windows)] = np.quantile(x_roll_std, 0.95)
X.loc[seg_id, 'q99_roll_std_' + str(windows)] = np.quantile(x_roll_std, 0.99)
X.loc[seg_id, 'av_change_abs_roll_std_' + str(windows)] = np.mean(np.diff(x_roll_std))
X.loc[seg_id, 'av_change_rate_roll_std_' + str(windows)] = np.mean(np.nonzero((np.diff(x_roll_std) / x_roll_std[:-1]))[0])
X.loc[seg_id, 'abs_max_roll_std_' + str(windows)] = np.abs(x_roll_std).max()
X.loc[seg_id, 'ave_roll_mean_' + str(windows)] = x_roll_mean.mean()
X.loc[seg_id, 'std_roll_mean_' + str(windows)] = x_roll_mean.std()
X.loc[seg_id, 'max_roll_mean_' + str(windows)] = x_roll_mean.max()
X.loc[seg_id, 'min_roll_mean_' + str(windows)] = x_roll_mean.min()
X.loc[seg_id, 'q01_roll_mean_' + str(windows)] = np.quantile(x_roll_mean, 0.01)
X.loc[seg_id, 'q05_roll_mean_' + str(windows)] = np.quantile(x_roll_mean, 0.05)
X.loc[seg_id, 'q95_roll_mean_' + str(windows)] = np.quantile(x_roll_mean, 0.95)
X.loc[seg_id, 'q99_roll_mean_' + str(windows)] = np.quantile(x_roll_mean, 0.99)
X.loc[seg_id, 'av_change_abs_roll_mean_' + str(windows)] = np.mean(np.diff(x_roll_mean))
X.loc[seg_id, 'av_change_rate_roll_mean_' + str(windows)] = np.mean(np.nonzero((np.diff(x_roll_mean) / x_roll_mean[:-1]))[0])
X.loc[seg_id, 'abs_max_roll_mean_' + str(windows)] = np.abs(x_roll_mean).max()
# iterate over all segments
for seg_id in tqdm_notebook(range(segments)):
seg = train.iloc[seg_id*rows:seg_id*rows+rows]
create_features(seg_id, seg, train_X)
train_y.loc[seg_id, 'time_to_failure'] = seg['time_to_failure'].values[-1]
然后进行一下标准化
scaler = StandardScaler()
scaler.fit(train_X)
scaled_train_X = pd.DataFrame(scaler.transform(train_X), columns=train_X.columns)
再对测试数据集进行处理
submission = pd.read_csv('../input/sample_submission.csv', index_col='seg_id')
test_X = pd.DataFrame(columns=train_X.columns, dtype=np.float64, index=submission.index)
for seg_id in tqdm_notebook(test_X.index):
seg = pd.read_csv('../input/test/' + seg_id + '.csv')
create_features(seg_id, seg, test_X)
scaled_test_X = pd.DataFrame(scaler.transform(test_X), columns=test_X.columns)
建立5折的交叉验证
n_fold = 5
folds = KFold(n_splits=n_fold, shuffle=True, random_state=42)
train_columns = scaled_train_X.columns.values
选用lightGBM和xgboost做模型组合
params = {'num_leaves': 51,
'min_data_in_leaf': 10,
'objective':'regression',
'max_depth': -1,
'learning_rate': 0.001,
"boosting": "gbdt",
"feature_fraction": 0.91,
"bagging_freq": 1,
"bagging_fraction": 0.91,
"bagging_seed": 42,
"metric": 'mae',
"lambda_l1": 0.1,
"verbosity": -1,
"nthread": -1,
"random_state": 42}
oof = np.zeros(len(scaled_train_X))
predictions = np.zeros(len(scaled_test_X))
feature_importance_df = pd.DataFrame()
#run model
for fold_, (trn_idx, val_idx) in enumerate(folds.split(scaled_train_X,train_y.values)):
strLog = "fold {}".format(fold_)
print(strLog)
X_tr, X_val = scaled_train_X.iloc[trn_idx], scaled_train_X.iloc[val_idx]
y_tr, y_val = train_y.iloc[trn_idx], train_y.iloc[val_idx]
model = lgb.LGBMRegressor(**params, n_estimators = 20000, n_jobs = -1)
model.fit(X_tr,
y_tr,
eval_set=[(X_tr, y_tr), (X_val, y_val)],
eval_metric='mae',
verbose=1000,
early_stopping_rounds=500)
oof[val_idx] = model.predict(X_val, num_iteration=model.best_iteration_)
#feature importance
fold_importance_df = pd.DataFrame()
fold_importance_df["Feature"] = train_columns
fold_importance_df["importance"] = model.feature_importances_[:len(train_columns)]
fold_importance_df["fold"] = fold_ + 1
feature_importance_df = pd.concat([feature_importance_df, fold_importance_df], axis=0)
#predictions
predictions += model.predict(scaled_test_X, num_iteration=model.best_iteration_) / folds.n_splits
xgb_params = {'eta': 0.03,
'max_depth': 9,
'subsample': 0.85,
'objective': 'reg:linear',
'eval_metric': 'mae',
'silent': True,
'nthread': 4}
oof_xgb = np.zeros(len(scaled_train_X))
predictions_xgb = np.zeros(len(scaled_test_X))
for fold_, (trn_idx, val_idx) in enumerate(folds.split(scaled_train_X, train_y.values)):
strLog = "fold {}".format(fold_))
print(strLog)
X_train, X_valid = scaled_train_X.iloc[trn_idx], scaled_train_X.iloc[val_idx]
y_train, y_valid = train_y.iloc[trn_idx], train_y.iloc[val_idx]
train_data = xgb.DMatrix(data=X_train, label=y_train, feature_names=scaled_train_X.columns)
valid_data = xgb.DMatrix(data=X_valid, label=y_valid, feature_names=scaled_train_X.columns)
watchlist = [(train_data, 'train'), (valid_data, 'valid_data')]
model = xgb.train(dtrain=train_data, num_boost_round=20000, evals=watchlist, early_stopping_rounds=200, verbose_eval=500, params=xgb_params)
y_pred_valid = model.predict(xgb.DMatrix(X_valid, feature_names=scaled_train_X.columns), ntree_limit=model.best_ntree_limit)
y_pred = model.predict(xgb.DMatrix(scaled_test_X, feature_names=scaled_train_X.columns), ntree_limit=model.best_ntree_limit)
这里是做的模型的stack。
train_stack = np.vstack([oof, oof_xgb]).transpose()
train_stack = pd.DataFrame(train_stack, columns = ['lgb', 'xgb'])
test_stack = np.vstack([predictions, y_pred]).transpose()
test_stack = pd.DataFrame(test_stack)
folds_stack = RepeatedKFold(n_splits=5, n_repeats=2, random_state=4590)
oof_stack = np.zeros(train_stack.shape[0])
predictions = np.zeros(test_stack.shape[0])
for fold_, (trn_idx, val_idx) in enumerate(folds_stack.split(train_stack,train_y.values)):
print("fold {}".format(fold_))
trn_data, trn_y = train_stack.iloc[trn_idx], train_y.iloc[trn_idx]
val_data, val_y = train_stack.iloc[val_idx], train_y.iloc[val_idx]
clf_3 = BayesianRidge()
clf_3.fit(trn_data, trn_y)
oof_stack[val_idx] = clf_3.predict(val_data)
predictions += clf_3.predict(test_stack) / 10
submission['time_to_failure'] = predictions
print(submission.head())
submission.to_csv('submission.csv')
比赛采用的是均方差的判断标准,还算不错的成绩。