text_plain_output_2.png text_plain_output_1.png
from sklearn import metrics

from sklearn import model_selection

import numpy as np

import pandas as pd

import random

FOLDS = 10
df_train = pd.read_csv('../input/30-days-of-ml/train.csv')
kfold = model_selection.KFold(n_splits=FOLDS, shuffle=True, random_state=42)
df_train['fold'] = -1
for fold, (_, valid_idx) in enumerate(kfold.split(df_train)):
    df_train.loc[valid_idx, 'fold'] = fold
df_train.to_csv('folds.csv', index=False)

df_train = pd.read_csv('folds.csv')
df_test = pd.read_csv('../input/30-days-of-ml/test.csv')

cont_features = [f for f in df_train.columns.tolist() if f.startswith('cont')]
cat_features = [f for f in df_train.columns.tolist() if f.startswith('cat')]

dummies = pd.get_dummies(df_train[cat_features])
df_train[dummies.columns] = dummies.iloc[:len(df_train), :]
df_test[dummies.columns] = dummies.iloc[len(df_test):, :]

class Trainer(object):
    def __init__(self, df_train, df_test):
        self.df_train = df_train
        self.df_test = df_test
        self.predictions_valid = None
        self.predictions_test = None
    def fit(self, models):
        model_scores = dict()
        self.predictions_valid = dict()
        self.predictions_test = dict()
        for model_index in range(len(models)):
            model_scores.setdefault(model_index, [])
            self.predictions_valid.setdefault(model_index, dict())
            self.predictions_test.setdefault(model_index, [])
        self.preprocessed_data = dict()
        folds = df_train.fold.max() + 1
        for fold in range(folds):
            X_train_fold = self.df_train[self.df_train.fold != fold]
            X_valid_fold = self.df_train[self.df_train.fold == fold]
            valid_idx = X_valid_fold.id.values.tolist()
            y_train = X_train_fold.target
            y_valid = X_valid_fold.target
            for model_index, (preprocessor, features, model_fn) in enumerate(models):
                xtrain = X_train_fold[features]
                xvalid = X_valid_fold[features]
                xtest = self.df_test[features]
                preprocessor_id = f'{fold}_{id(preprocessor)}'
                if preprocessor_id not in self.preprocessed_data:
                    self.preprocessed_data[preprocessor_id] = {'X_train': preprocessor.fit_transform(xtrain, y_train), 'X_valid': preprocessor.transform(xvalid), 'X_test': preprocessor.transform(xtest)}
                X_train = self.preprocessed_data[preprocessor_id]['X_train']
                X_valid = self.preprocessed_data[preprocessor_id]['X_valid']
                X_test = self.preprocessed_data[preprocessor_id]['X_test']
                model = model_fn(fold)
                model.fit(X_train, y_train, early_stopping_rounds=100, eval_set=[(X_valid, y_valid)], verbose=False)
                yhat_valid = model.predict(X_valid)
                yhat_test = model.predict(X_test)
                self.predictions_valid[model_index].update(dict(zip(valid_idx, yhat_valid)))
                self.predictions_test[model_index].append(yhat_test)
                rmse = metrics.mean_squared_error(y_valid, yhat_valid, squared=False)
                model_scores[model_index].append(rmse)
        scores = []
        for index in range(len(models)):
            score = np.mean(model_scores[index])
            scores.append(score)
        self._save()
        return scores
    def _save(self):
        if self.predictions_valid is None:
            return
        for index in range(len(self.predictions_valid.keys())):
            model_id = random.randint(1000000000, 9999999999)
            df_predictions_valid = pd.DataFrame.from_dict(self.predictions_valid[index], orient='index').reset_index()
            df_predictions_valid.columns = ['id', f'predictions_{model_id}']
            df_predictions_valid.to_csv(f'predictions_train_model_{model_id}.csv', index=False)
            target = np.mean(np.column_stack(self.predictions_test[index]), axis=1)
            df_predictions_test = pd.DataFrame({'id': self.df_test.id, f'predictions_{model_id}': target})
            df_predictions_test.to_csv(f'predictions_test_model_{model_id}.csv', index=False)

blender = Blender(df_train, df_test)
blender.blend('submission.csv')