首页 > 编程知识 正文

随机缺失和非随机缺失,随机森林回归结果不理想

时间:2023-05-04 08:53:29 阅读:153191 作者:780

% matplotlibinlineaxdxmtortnumpyasnpaxdxmtortpandasaspdfromsklearn.treeaxdxmtortdecisiontreeclassifierfromsklearn.ensemble asetsaxdxmtortload _ winefromsklearn.model _ selectionaxdxmtorttrain _ test _ splitfromsk OSS _ val _ score wine=load y test=train _ test _ split (wine.data, 要与wine.data进行比较test_size=0.3 ) clf=decisiontreeclassifier (random _ state=0) rcf=randomforestclassifier ) random ytrain ) rcf_score=rcf.score(xtest,ytest )打印(' singletree : { }.format ) ) ) singletree3360

循环10次,每次交叉检查10次,共计100次clf_CVS=[]rcf_CVS=[] forIinrange(10 ) : clf=decisiontreeclassifier ) (rcf=randomforestclassifier ) ) randomforestclassifier wine.data,data cv=10 ).mean (RCF _ cv=cross _ val _ score (RCF,wine.data,wine.target,cv=10 ).mean ) 11 ),rcf_cvs,color='black ',label='forest ' ) plt.legend ) (plt.show ) ) ) )。

#随机森林优于决策树,且各个决策树的涨落和随机森林的涨落桂金基本相同#随机森林n_estimators学习曲线rcf_CVS=[] forIinrange(200 ) : RCF=randomforestclassifier (n _ estimators RCF _ CVS=cross _ val _ score (RCF,wine.data ) )

axdxmtortnumpyasnpaxdxmtortpandasaspdaxdxmtortmatplotlib.pyplotaspltfromsklearn.datasetsaxdxmtortload _ bostonfromsklearn sembleaxdxmtortrandomforestregressorfromsklearn.model _ selectionaxdxmtortcross _ val _ selection dataset.data.shape #。 y_full=dataset.data,dataset.targetn _ samples=x _ full.shape [0] n _ features=x _ full.shape [1] # 这里假设为50%。 这是总共3289个数据丢失RNG=NP.random.randomstate(0) missing _ rate=0.5n _ missing _ samples=int ) #np.floor ) n _ n 所有数据都随机分布在数据集中每行的各列中,但缺少的数据需要行索引和列索引。 如果可以创建包含介于0到506之间的3289个行索引和介于0到13之间的3289个列索引的数组,则#使用索引可以是数据的任意3289个

位置赋空值#然后我们用0,均值和随机森林来填写这些缺失值,然后查看回归的结果如何missing_features = rng.randint(0,n_features,n_missing_samples)missing_samples = rng.randint(0,n_samples,n_missing_samples)#missing_samples = rng.choice(dataset.data.shape[0],n_missing_samples,replace=False)#我们现在采样了3289个数据,远远超过我们的样本量506,所以我们使用随机抽取的函数randint。但如果我们需要#的数据量小于我们的样本量506,那我们可以采用np.random.choice来抽样,choice会随机抽取不重复的随机数,#因此可以帮助我们让数据更加分散,确保数据不会集中在一些行中X_missing = X_full.copy()y_missing = y_full.copy()X_missing[missing_samples,missing_features] = np.nanX_missing = pd.DataFrame(X_missing)#转换成DataFrame是为了后续方便各种操作,numpy对矩阵的运算速度快到拯救人生,但是在索引等功能上却不如#pandas来得好用#使用随机森林进行填充缺失值#1使用均值进行填补from sklearn.axdxmtute axdxmtort SaxdxmtleImputeraxdxmt_mean=SaxdxmtleImputer(missing_values=np.nan,strategy="mean")X_missing_mean=axdxmt_mean.fit_transform(X_missing)#返回训练好的特征举证,是array类型

axdxmt_mean=SaxdxmtleImputer(missing_values=np.nan,strategy="constant",fill_value=0)#用0进行填充X_missing_0=axdxmt_mean.fit_transform(X_missing)#返回训练好的特征举证,是array类型 #接下来使用随机森林填充'''使用随机森林回归填补缺失值任何回归都是从特征矩阵中学习,然后求解连续型标签y的过程,之所以能够实现这个过程,是因为回归算法认为,特征矩阵和标签之前存在着某种联系。实际上,标签和特征是可以相互转换的,比如说,在一个“用地区,环境,附近学校数量”预测“房价”的问题中,我们既可以用“地区”,“环境”,“附近学校数量”的数据来预测“房价”,也可以反过来,用“环境”,“附近学校数量”和“房价”来预测“地区”。而回归填补缺失值,正是利用了这种思想。对于一个有n个特征的数据来说,其中特征T有缺失值,我们就把特征T当作标签,其他的n-1个特征和原本的标签组成新的特征矩阵。那对于T来说,它没有缺失的部分,就是我们的Y_test,这部分数据既有标签也有特征,而它缺失的部分,只有特征没有标签,就是我们需要预测的部分。特征T不缺失的值对应的其他n-1个特征 + 本来的标签:X_train特征T不缺失的值:Y_train特征T缺失的值对应的其他n-1个特征 + 本来的标签:X_test特征T缺失的值:未知,我们需要预测的Y_test这种做法,对于某一个特征大量缺失,其他特征却很完整的情况,非常适用。那如果数据中除了特征T之外,其他特征也有缺失值怎么办?答案是遍历所有的特征,从缺失最少的开始进行填补(因为填补缺失最少的特征所需要的准确信息最少)。填补一个特征时,先将其他特征的缺失值用0代替,每完成一次回归预测,就将预测值放到原本的特征矩阵中,再继续填补下一个特征。每一次填补完毕,有缺失值的特征会减少一个,所以每次循环后,需要用0来填补的特征就越来越少。当进行到最后一个特征时(这个特征应该是所有特征中缺失值最多的),已经没有任何的其他特征需要用0来进行填补了,而我们已经使用回归为其他特征填补了大量有效信息,可以用来填补缺失最多的特征。遍历所有的特征后,数据就完整,不再有缺失值了''' X_missing_reg = X_missing.copy()sortindex = np.argsort(X_missing_reg.isnull().sum(axis=0)).valuesfor i in sortindex: #构建我们的新特征矩阵和新标签 df = X_missing_reg fillc = df.iloc[:,i] df = pd.concat([df.iloc[:,df.columns != i],pd.DataFrame(y_full)],axis=1)#在新特征矩阵中,对含有缺失值的列,进行0的填补 df_0 =SaxdxmtleImputer(missing_values=np.nan, strategy='constant',fill_value=0).fit_transform(df)#找出我们的训练集和测试集 Ytrain = fillc[fillc.notnull()] Ytest = fillc[fillc.isnull()] Xtrain = df_0[Ytrain.index,:] Xtest = df_0[Ytest.index,:]#用随机森林回归来填补缺失值 rfc = RandomForestRegressor(n_estimators=100) rfc = rfc.fit(Xtrain, Ytrain) Ypredict = rfc.predict(Xtest)#将填补好的特征返回到我们的原始的特征矩阵中 X_missing_reg.loc[X_missing_reg.iloc[:,i].isnull(),i] = Ypredict #对所有数据进行建模,取得MSE结果X = [X_full,X_missing_mean,X_missing_0,X_missing_reg]mse = []std = []for x in X: estimator = RandomForestRegressor(random_state=0, n_estimators=100) scores = cross_val_score(estimator,x,y_full,scoring='neg_mean_squared_error',cv=5).mean() mse.append(scores * -1)

x_labels = ['Full data','Zero Imputation','Mean Imputation','Regressor Imputation']colors = ['r', 'g', 'b', 'orange']plt.figure(figsize=(12, 6))ax = plt.subplot(111)for i in np.arange(len(mse)): ax.barh(i, mse[i],color=colors[i], alpha=0.6, align='center')ax.set_title('Imputation Techniques with Boston Data')ax.set_xlim(left=np.min(mse) * 0.9,right=np.max(mse) * 1.1)ax.set_yticks(np.arange(len(mse)))ax.set_xlabel('MSE')ax.set_yticklabels(x_labels)plt.show()


发现,回归填充效果最好

#随机森林在乳腺癌数据集上的调参from sklearn.datasets axdxmtort load_breast_cancerfrom sklearn.ensemble axdxmtort RandomForestClassifierfrom sklearn.model_selection axdxmtort cross_val_scorefrom sklearn.model_selection axdxmtort train_test_splitaxdxmtort matplotlib.pyplot as pltfrom sklearn.model_selection axdxmtort GridSearchCVbc=load_breast_cancer()X=bc.datay=bc.targetrcf=RandomForestClassifier(random_state=0)#生成固定的一片森林,里面的树是不同的cross_val_score(rcf,X,y,cv=10).mean() #接下来画出n_estimators的学习曲线scores=[]for i in range(0,200,10): rcf=RandomForestClassifier(n_estimators=i+1,random_state=0) sc=cross_val_score(rcf,X,y,cv=10).mean() scores.append(sc)print(max(scores),(scores.index(max(scores))*10)+1)plt.figure()plt.plot(range(1,201,10),scores)#注意这里的range,要同样的维数plt.show()

#接下来细化学习曲线scores=[]for i in range(100,150): rcf=RandomForestClassifier(n_estimators=i,random_state=0) sc=cross_val_score(rcf,X,y,cv=10).mean() scores.append(sc)print(max(scores),100+scores.index(max(scores)))plt.figure()plt.plot(range(100,150),scores)plt.show()

'''"""有一些参数是没有参照的,很难说清一个范围,这种情况下我们使用学习曲线,看趋势从曲线跑出的结果中选取一个更小的区间,再跑曲线param_grid = {'n_estimators':np.arange(0, 200, 10)}param_grid = {'max_depth':np.arange(1, 20, 1)}param_grid = {'max_leaf_nodes':np.arange(25,50,1)}对于大型数据集,可以尝试从1000来构建,先输入1000,每100个叶子一个区间,再逐渐缩小范围有一些参数是可以找到一个范围的,或者说我们知道他们的取值和随着他们的取值,模型的整体准确率会如何变化,这样的参数我们就可以直接跑网格搜索param_grid = {'criterion':['gini', 'entropy']}param_grid = {'min_samples_split':np.arange(2, 2+20, 1)}param_grid = {'min_samples_leaf':np.arange(1, 1+10, 1)}param_grid = {'max_features':np.arange(5,30,1)}''' #首先调整max_depthparam_grid={"max_depth":np.arange(1,20,1)}rcf=RandomForestClassifier(n_estimators=110,random_state=0)gc=GridSearchCV(rcf,param_grid=param_grid,cv=10)gc.fit(X,y)

#限制了树的最大深度,模型未改变#调整max_features:是唯一能够将结果左推和右推的'''max_features是唯一一个即能够将模型往左(低方差高偏差)推,也能够将模型往右(高方差低偏差)推的参数。我们需要根据调参前,模型所在的位置(在泛化误差最低点的左边还是右边)来决定我们要将max_features往哪边调。现在模型位于图像左侧,我们需要的是更高的复杂度,因此我们应该把max_features往更大的方向调整,可用的特征越多,模型才会越复杂。max_features的默认最小值是sqrt(n_features),因此我们使用这个值作为调参范围的最小值'''param_grid={"max_features":np.arange(5,30,1)}rcf=RandomForestClassifier(n_estimators=110,random_state=0)gc=GridSearchCV(rcf,param_grid=param_grid,cv=10)gc.fit(X,y)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。