from sklearn import datasets
from sklearn.ensemble import RandomForestClassifier, ExtraTreesClassifier, GradientBoostingClassifier
from sklearn.model_selection import train_test_split
from sklearn.cross_validation import StratifiedKFold
import numpy as np
from sklearn.metrics import roc_auc_score
from sklearn.datasets.samples_generator import make_blobs
import matplotlib.pyplot as plt

def data_show(X,y):
    plt.scatter(X[:,0],X[:,1],c=y)
    plt.show()


def blend(X,X_predict,y,y_predict):
    '''5折'''
    # n_flods = 5
    # skf = list(StratifiedKFold(y, n_folds=n_flods))
    '''切分训练数据集为d1,d2两部分'''
    X_d1, X_d2, y_d1, y_d2 = train_test_split(X, y, test_size=0.5, random_state=2017)

    dataset_d1 = np.zeros((X_d2.shape[0],len(clfs)))
    dataset_d2 = np.zeros((X_predict.shape[0],len(clfs)))

    for j,clf in enumerate(clfs):
        '''依次训练各个单模型'''
        # print(j, clf)
        '''使用第1个部分作为预测，第2部分来训练模型，获得其预测的输出作为第2部分的新特征。'''
        # X_train, y_train, X_test, y_test = X[train], y[train], X[test], y[test]
        clf.fit(X_d1,y_d1)
        y_submission = clf.predict_proba(X_d2)[:, 1]
        dataset_d1[:,j] = y_submission
        '''对于测试集，直接用这k个模型的预测值作为新的特征。'''
        dataset_d2[:, j] = clf.predict_proba(X_predict)[:, 1]
        print("val auc Score: %f" % roc_auc_score(y_predict, dataset_d2[:, j]))

    '''使用模型融合'''
    clf = GradientBoostingClassifier(learning_rate=0.2,subsample=0.5,max_depth=6,n_estimators=30)
    clf.fit(dataset_d1,y_d2)
    y_submission = clf.predict_proba(dataset_d2)[:,1]
    print("Linear stretch of predictions to [0,1]")
    y_submission = (y_submission - y_submission.min()) / (y_submission.max() - y_submission.min())
    print("blend result")
    print("val auc Score: %f" % (roc_auc_score(y_predict, y_submission)))


if __name__ == "__main__":
    data, target = make_blobs(n_samples=50000, centers=2, random_state=0, cluster_std=0.60)
    # data_show(data,target)#查看数据分布
    '''模型融合中使用到的各个单模型'''
    clfs = [RandomForestClassifier(n_estimators=5, n_jobs=-1, criterion='gini'),
            RandomForestClassifier(n_estimators=5, n_jobs=-1, criterion='entropy'),
            ExtraTreesClassifier(n_estimators=5, n_jobs=-1, criterion='gini'),
            ExtraTreesClassifier(n_estimators=5, n_jobs=-1, criterion='entropy'),
            GradientBoostingClassifier(learning_rate=0.05, subsample=0.5, max_depth=6, n_estimators=5)]

    X,X_predict,y,y_predict = train_test_split(data,target,test_size=0.33,random_state=2017)
    blend(X,X_predict,y,y_predict)

