Advertisement

sklearn(9):天池蒸汽项目预测

阅读量:

整体思路

  • 导入数据后,将训练集和测试集粘合
  • 特征搜索,通过观察每个特征下训练集和测试集的数据的取值范围以及分布情况,将分布不均匀的特征项删除
  • 特征相关性处理:将每一个特征与训练集的目标值计算相关性,删除相关性低且分布不均匀的特征,note:可以通过生成heatmap的方式观察每个特征与目标值之间的相关性或相关系数
  • 数据处理:对数据进行归一化,并使用boxcox方法使每一个特征下的数据集更加正态分布化
  • 使用ridge回归算法训练测试集,将异常点(噪声)删除,提高测试准确度
  • 算法模型的建立:通过字典建立尽可能多地预测模型观测训练集在每一个模型下的r2和mse从而减少那些对于该数据集预测不准确的模型,保留那些r2较大,mse较小的值。
  • 用保留下的算法模型fit训练集对测试集的特征数据集进行预测,将每一组预测值添加到列表中,并去列表下所有预测值的平均数。
  • 储存预测值

其他可能减小MSE的方法

  • 将每个算法预测出的值作为新特征加入到原始数据集和测试集中。
  • 将预测值通过数学计算变得更加拟合正态分布。
  • 对预测模型的超参数进行调参。

代码1:使用标准化进行预测

复制代码
    import numpy as np
    import pandas as pd
    import  matplotlib.pyplot as plt
    import seaborn as sns
    from sklearn.linear_model import LinearRegression,Lasso,Ridge,RidgeCV,ElasticNet
    from sklearn.neighbors import KNeighborsRegressor
    from sklearn.ensemble import GradientBoostingRegressor,RandomForestRegressor,AdaBoostRegressor,ExtraTreesRegressor
    from xgboost import XGBRegressor
    from lightgbm import LGBMRegressor
    from sklearn.svm import SVR
    from sklearn.metrics import mean_squared_error
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import MinMaxScaler,StandardScaler,PolynomialFeatures,minmax_scale
    import warnings
    from scipy import stats
    warnings.filterwarnings("ignore")
    
    #数据聚合
    train=pd.read_csv("zhengqi_train.txt",sep="\t")
    test=pd.read_csv("zhengqi_test.txt",sep="\t")
    train["origin"]="train"
    test["origin"]="test"
    
    
    data_all=pd.concat([train,test])
    #print(data_all.shape) #(4813, 40)
    #print(data_all.head())
    
    '''特征探索'''
    #38个特征,将一些不重要的特征删除
    #特征分布情况,训练和测试数据特征分布不均匀,删除
    '''
    plt.figure(figsize=(9,6))
    for i,col in enumerate(data_all.columns[:-2]):
    #密度图
    cond_train=data_all["origin"]=="train" #检索属于训练集的
    train_col=data_all[col][cond_train] #取出训练集的每一列
    cond_test = data_all["origin"] == "test"
    test_col = data_all[col][cond_test]
    # axes=plt.subplot(38,1,i+1)
    ax=sns.kdeplot(train_col,shade=True)
    sns.kdeplot(test_col,shade=True,ax=ax)
    plt.legend(["train","test"])
    plt.xlabel(col)
    plt.show()
    plt.figure(figsize=(9,6))
    for col in data_all.columns[:-2]:
    g=sns.FacetGrid(data_all,col="origin")
    g.map(sns.distplot,col) #distribute
    # plt.show()
    '''
    drop_labels=["V11","V17","V22","V5"]
    data_all=data_all.copy()
    data_all.drop(drop_labels,axis=1,inplace=True)
    print(data_all.shape)
    
    '''相关性系数'''
    #方差是协方差的一种特殊形式
    cov=data_all.cov() #协方差
    corr=data_all.corr()#相关系数
    
    #查看特征和目标值的相关系数
    cond=corr.loc["target"].abs()<0.1 #把特征与目标之间相关系数小于0.1的删除
    # print(corr.loc["target"].index[cond])
    #Index(['V14', 'V21', 'V25', 'V26', 'V32', 'V33', 'V34']
    
    '''通过与密度图做对比,删除v14,v21特征'''
    drop_labels_1=["V14","V21"]
    data_all.drop(drop_labels_1,axis=1,inplace=True)
    print(data_all.shape)
    
    '''热图'''
    # plt.figure(figsize=(20,16))
    # mcorr=train.corr()
    # mask=np.zeros_like(mcorr,dtype=np.bool)
    # mask[np.triu_indices_from(mask)]=True#对角线右侧设置为true
    # cmap=sns.diverging_palette(220,10,as_cmap=True)#给予颜色 colormap
    # g=sns.heatmap(mcorr,mask=mask,cmap=cmap,square=True,annot=True,fmt="0.2f")#生成热力图
    # plt.show()
    # print(mask)
    
    '''标准化操作,每一个特征的方差都变为0'''
    stand=StandardScaler()
    data=data_all.iloc[:,:-2]
    data2=stand.fit_transform(data)
    cols=data_all.columns
    data_all_std=pd.DataFrame(data2,columns=cols[:-2])
    data_all.index=np.arange(4813)
    data_all_std=pd.merge(data_all_std,data_all.iloc[:,-2:],right_index=True,left_index=True)
    # print(data_all_std.head())
    # # print(data_all_std.describe())
    
    '''使用不同的算法进行训练'''
    #异常值
    ridge=RidgeCV(alphas=[0.0001,0.001,0.01,0.1,0.2,0.5,1,2,3,5,10,20,30,50])
    condition=data_all_std["origin"]=="train"
    x_train=data_all_std[condition].iloc[:,:-2]
    y_train=data_all_std[condition]["target"]
    ridge.fit(x_train,y_train) #算法拟合数据和目标值的时候,训练集不可能完全拟合
    y_hat=ridge.predict(x_train)#预测值和真实值之间偏差如果特别大,可以作为异常值,3sigma准则
    
    result=(y_train-y_hat).abs()>y_train.std()
    print(result.sum()) #有38个异常值
    
    #画图
    '''
    plt.figure(figsize=(12,6))
    axes=plt.subplot(1,3,1)
    axes.scatter(y_train,y_hat)
    axes.scatter(y_train[result],y_hat[result],c="red",s=20)
    axes=plt.subplot(1,3,2)
    axes.scatter(y_train,y_train-y_hat)
    axes.scatter(y_train[result],(y_train-y_hat)[result],c="red",s=20)
    axes=plt.subplot(1,3,3)
    (y_train-y_hat).hist(bins=50,ax=axes)
    (y_train-y_hat)[result].plot.hist(bins=50,ax=axes,color="red")
    plt.show()
    '''
    
    '''将异常值点过滤'''
    drop_index=result[result].index#找到异常值的索引
    data_all_std.drop(drop_index,axis=0,inplace=True)
    #data_all_std (4813, 34)
    print(data_all_std.shape) #(4775, 34) 共删除了38个异常值点
    
    def detect_model(estimators,data):
    for key,estimators in estimators.items():
        estimators.fit(data[0],data[2])
        y_=estimators.predict(data[1])
        mse=mean_squared_error(data[3],y_)
        print("----------MSE%s"%(key),mse)
        r2=estimators.score(data[1],data[3])
        print("----------R2%s" % (key), r2)
        print("\n")
    
    X=data_all_std[data_all_std["origin"]=="train"].iloc[:,:-2]
    Y=data_all_std[data_all_std["origin"]=="train"]["target"]
    data_use=train_test_split(X,Y,test_size=0.2)
    estimators={}
    '''
    estimators["knn"]=KNeighborsRegressor()
    estimators["linear"]=LinearRegression()
    estimators["ridge"]=Ridge()
    estimators["lasso"]=Lasso()
    estimators["elasticNet"]=ElasticNet()
    estimators["forest"]=RandomForestRegressor()
    estimators["gbdt"]=GradientBoostingRegressor()
    estimators["ada"]=AdaBoostRegressor()
    estimators["Extra"]=ExtraTreesRegressor()
    estimators["svm_rbf"]=SVR(kernel="rbf")
    estimators["svm_poly"]=SVR(kernel="poly")
    estimators["LGB"]=LGBMRegressor()
    estimators["xgboost"]=XGBRegressor()
    detect_model(estimators,data_use)
    '''
    
    #对于测试数据而言,KNN,lasso,elasticnet,svm_poly的mse过于大,所以删掉
    estimators["linear"]=LinearRegression()
    estimators["ridge"]=Ridge()
    estimators["forest"]=RandomForestRegressor()
    estimators["gbdt"]=GradientBoostingRegressor()
    estimators["ada"]=AdaBoostRegressor()
    estimators["Extra"]=ExtraTreesRegressor()
    estimators["svm_rbf"]=SVR(kernel="rbf")
    estimators["LGB"]=LGBMRegressor()
    estimators["xgboost"]=XGBRegressor()
    cond2=data_all_std["origin"]=="train"
    xtrain=data_all_std[cond2].iloc[:,:-2]
    ytrain=data_all_std[cond2]["target"]
    print(xtrain.shape)
    print(ytrain.shape)
    
    cond3=data_all_std["origin"]=="test"
    xtest=data_all_std[cond3].iloc[:,:-2]
    print(xtest.shape)
    
    
    predict1=[]
    #将每个算法对于训练集和测试集的预测作为特征加入到训练集和测试集作为新的特征
    #最终预测加入测试集,集成算法,将每个算法的结果合并
    # for key,model in estimators.items():
    #     model.fit(xtrain,ytrain)
    #     y_predict_train=model.predict(xtrain)
    #     xtrain[key]=y_predict_train
    #     y_predict=model.predict(xtest)
    #     # print(y_predict.shape)
    #     xtest[key]=y_predict#将预测值作为新的特征,让算法进行再学习
    
    #最终预测加入测试集,集成算法,将每个算法的结果合并
    for key,model in estimators.items():
    model.fit(xtrain,ytrain)
    y_estimate=model.predict(xtest)
    predict1.append(y_estimate)
    
    y_final=np.mean(predict1,axis=0)
    # print(y_final)
    # y_final+=np.random.randint(1925)*0.1
    pd.Series(y_final).to_csv("./天池蒸汽项目预测值",index=False)
    sns.distplot(y_final)
    plt.show()
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

代码2:使用归一化+boxcox方法进行预测

复制代码
    import numpy as np
    import pandas as pd
    import  matplotlib.pyplot as plt
    import seaborn as sns
    from sklearn.linear_model import LinearRegression,Lasso,Ridge,RidgeCV,ElasticNet
    from sklearn.neighbors import KNeighborsRegressor
    from sklearn.ensemble import GradientBoostingRegressor,RandomForestRegressor,AdaBoostRegressor,ExtraTreesRegressor
    from xgboost import XGBRegressor
    from lightgbm import LGBMRegressor
    from sklearn.svm import SVR
    from sklearn.metrics import mean_squared_error
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import MinMaxScaler,StandardScaler,PolynomialFeatures
    import warnings
    from scipy import stats
    warnings.filterwarnings("ignore")
    
    #数据聚合
    train=pd.read_csv("zhengqi_train.txt",sep="\t")
    test=pd.read_csv("zhengqi_test.txt",sep="\t")
    train["origin"]="train"
    test["origin"]="test"
    
    
    data_all=pd.concat([train,test])
    #print(data_all.shape) #(4813, 40)
    #print(data_all.head())
    
    '''特征探索'''
    #38个特征,将一些不重要的特征删除
    #特征分布情况,训练和测试数据特征分布不均匀,删除
    '''
    plt.figure(figsize=(9,6))
    for i,col in enumerate(data_all.columns[:-2]):
    #密度图
    cond_train=data_all["origin"]=="train" #检索属于训练集的
    train_col=data_all[col][cond_train] #取出训练集的每一列
    cond_test = data_all["origin"] == "test"
    test_col = data_all[col][cond_test]
    # axes=plt.subplot(38,1,i+1)
    ax=sns.kdeplot(train_col,shade=True)
    sns.kdeplot(test_col,shade=True,ax=ax)
    plt.legend(["train","test"])
    plt.xlabel(col)
    plt.show()
    plt.figure(figsize=(9,6))
    for col in data_all.columns[:-2]:
    g=sns.FacetGrid(data_all,col="origin")
    g.map(sns.distplot,col) #distribute
    # plt.show()
    '''
    drop_labels=["V11","V17","V22","V5"]
    data_all=data_all.copy()
    data_all.drop(drop_labels,axis=1,inplace=True)
    print(data_all.shape)
    
    '''相关性系数'''
    #方差是协方差的一种特殊形式
    cov=data_all.cov() #协方差
    corr=data_all.corr()#相关系数
    
    #查看特征和目标值的相关系数
    cond=corr.loc["target"].abs()<0.1 #把特征与目标之间相关系数小于0.1的删除
    # print(corr.loc["target"].index[cond])
    #Index(['V14', 'V21', 'V25', 'V26', 'V32', 'V33', 'V34']
    
    '''通过与密度图做对比,删除v14,v21特征'''
    drop_labels_1=["V14","V21"]
    data_all.drop(drop_labels_1,axis=1,inplace=True)
    print(data_all.shape)
    
    '''热图'''
    # plt.figure(figsize=(20,16))
    # mcorr=train.corr()
    # mask=np.zeros_like(mcorr,dtype=np.bool)
    # mask[np.triu_indices_from(mask)]=True#对角线右侧设置为true
    # cmap=sns.diverging_palette(220,10,as_cmap=True)#给予颜色 colormap
    # g=sns.heatmap(mcorr,mask=mask,cmap=cmap,square=True,annot=True,fmt="0.2f")#生成热力图
    # plt.show()
    # print(mask)
    
    '''标准化操作,每一个特征的方差都变为0'''
    stand=StandardScaler()
    data=data_all.iloc[:,:-2]
    data2=stand.fit_transform(data)
    
    '''对数据进行归一化'''
    data111=data_all.iloc[:,:-2]
    MinMaxScaler=MinMaxScaler()
    data3=MinMaxScaler.fit_transform(data111)
    data_all_norm=pd.DataFrame(data3,columns=data_all.columns[:-2])
    data_all_norm=pd.merge(data_all_norm,data_all.iloc[:,-2:],left_index=True,right_index=True)
    
    
    def minmax_scale(data):
    return (data-data.min())/(data.max()-data.min())
    
    '''
    #check effect of Box-cox transforms on distributions of continious variables
    fcols=6
    frows=len(data_all_norm.columns[:10])
    plt.figure(figsize=(4*fcols,4*frows))
    i=0
    for col in data_all_norm.columns[:10]:
    dat=data_all_norm[[col,"target"]].dropna()
    
    i+=1
    plt.subplot(frows,fcols,i)
    sns.displot(dat[col])
    plt.title(col+"original")
    plt.xlabel("")
    #第二个图,skew统计分析中一个属性
    # skewness偏斜系数,对正态分布的度量
    i+=1
    plt.subplot(frows,fcols,i)
    _=stats.probplot(dat[col],plot=plt)
    plt.title('skew='+'{:.4f}'.format(stats.skew(dat[col])))
    plt.xlabel('')
    plt.ylabel('')
    
    #   散点图
    i+=1
    plt.subplot(frows, fcols, i)
    #     plt.plot(dat[var], dat['target'],'.',alpha=0.5)
    plt.scatter(dat[col], dat['target'], alpha=0.5)
    #计算相关性系数
    plt.title('corr=' + '{:.2f}'.format(np.corrcoef(dat[col], dat['target'])[0][1]))
    
    #     !!!对数据进行了处理!!!
    #   数据分布图distribution
    i+=1
    plt.subplot(frows,fcols,i)
    trans_var, lambda_var = stats.boxcox(dat[col].dropna()+1)
    trans_var = minmax_scale(trans_var)
    sns.distplot(trans_var , fit=stats.norm)
    plt.title(col+' Tramsformed')
    plt.xlabel('')
    #     偏斜度
    i+=1
    plt.subplot(frows,fcols,i)
    _=stats.probplot(trans_var, plot=plt)
    plt.title('skew='+'{:.4f}'.format(stats.skew(trans_var)))
    plt.xlabel('')
    plt.ylabel('')
    
    #     散点图
    i+=1
    plt.subplot(frows,fcols,i)
    plt.plot(trans_var, dat['target'],'.',alpha=0.5)
    plt.title('corr='+'{:.2f}'.format(np.corrcoef(trans_var,dat['target'])[0][1]))
    plt.show()
    '''
    
    '''将数据进行box-cox转换,对每一列进行转换,再归一化'''
    #boxcox的目的:将数据变得更加正态分布化
    for col in data_all_norm.columns[:-2]:
    boxcox,maglog=stats.boxcox(data_all_norm[col]+1) #保证计算中没有0
    data_all_norm[col]=minmax_scale(boxcox)
    
    '''使用不同的算法进行训练'''
    #异常值
    ridge=RidgeCV(alphas=[0.0001,0.001,0.01,0.1,0.2,0.5,1,2,3,5,10,20,30,50])
    condition=data_all_norm["origin"]=="train"
    x_train=data_all_norm[condition].iloc[:,:-2]
    y_train=data_all_norm[condition]["target"]
    ridge.fit(x_train,y_train) #算法拟合数据和目标值的时候,训练集不可能完全拟合
    y_hat=ridge.predict(x_train)#预测值和真实值之间偏差如果特别大,可以作为异常值,3sigma准则
    
    result=(y_train-y_hat).abs()>y_train.std()
    print(result.sum()) #有42个异常值
    
    #画图
    
    plt.figure(figsize=(12,6))
    axes=plt.subplot(1,3,1)
    axes.scatter(y_train,y_hat)
    axes.scatter(y_train[result],y_hat[result],c="red",s=20)
    axes=plt.subplot(1,3,2)
    axes.scatter(y_train,y_train-y_hat)
    axes.scatter(y_train[result],(y_train-y_hat)[result],c="red",s=20)
    axes=plt.subplot(1,3,3)
    (y_train-y_hat).hist(bins=50,ax=axes)
    (y_train-y_hat)[result].plot.hist(bins=50,ax=axes,color="red")
    plt.show()
    
    
    '''将异常值点过滤'''
    drop_index=result[result].index#找到异常值的索引
    data_all_norm.drop(drop_index,axis=0,inplace=True)
    #data_all_std (4813, 34)
    print(data_all_norm.shape) #(4775, 34) 共删除了38个异常值点
    
    def detect_model(estimators,data):
    for key,estimators in estimators.items():
        estimators.fit(data[0],data[2])
        y_=estimators.predict(data[1])
        mse=mean_squared_error(data[3],y_)
        print("----------MSE%s"%(key),mse)
        r2=estimators.score(data[1],data[3])
        print("----------R2%s" % (key), r2)
        print("\n")
    
    X=data_all_norm[data_all_norm["origin"]=="train"].iloc[:,:-2]
    Y=data_all_norm[data_all_norm["origin"]=="train"]["target"]
    data_use=train_test_split(X,Y,test_size=0.2)
    estimators={}
    
    
    #对于测试数据而言,KNN,lasso,elasticnet,svm_poly的mse过于大,所以删掉
    estimators["linear"]=LinearRegression()
    estimators["ridge"]=Ridge()
    estimators["forest"]=RandomForestRegressor(n_estimators=300)
    estimators["gbdt"]=GradientBoostingRegressor(n_estimators=300)
    estimators["ada"]=AdaBoostRegressor(n_estimators=300)
    estimators["Extra"]=ExtraTreesRegressor(n_estimators=300)
    estimators["svm_rbf"]=SVR(kernel="rbf")
    estimators["LGB"]=LGBMRegressor(n_estimators=300)
    estimators["xgboost"]=XGBRegressor(n_estimators=300)
    cond2=data_all_norm["origin"]=="train"
    xtrain=data_all_norm[cond2].iloc[:,:-2]
    ytrain=data_all_norm[cond2]["target"]
    print(xtrain.shape)
    print(ytrain.shape)
    
    cond3=data_all_norm["origin"]=="test"
    xtest=data_all_norm[cond3].iloc[:,:-2]
    print(xtest.shape)
    
    
    predict1=[]
    #将每个算法对于训练集和测试集的预测作为特征加入到训练集和测试集作为新的特征
    #最终预测加入测试集,集成算法,将每个算法的结果合并
    # for key,model in estimators.items():
    #     model.fit(xtrain,ytrain)
    #     y_predict_train=model.predict(xtrain)
    #     xtrain[key]=y_predict_train
    #     y_predict=model.predict(xtest)
    #     # print(y_predict.shape)
    #     xtest[key]=y_predict#将预测值作为新的特征,让算法进行再学习
    
    #最终预测加入测试集,集成算法,将每个算法的结果合并
    for key,model in estimators.items():
    model.fit(xtrain,ytrain)
    y_estimate=model.predict(xtrain)
    predict1.append(y_estimate)
    
    y_final=np.mean(predict1,axis=0)
    mse=mean_squared_error(ytrain,y_final)
    print(mse)
    # print(y_final)
    # y_final+=np.random.randint(1925)*0.1
    pd.Series(y_final).to_csv("./天池蒸汽项目预测值222",index=False)
    # sns.distplot(y_final) 观测分布
    # plt.show()
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

全部评论 (0)

还没有任何评论哟~