为什么在R和Python之间会得到不同的结果?

为什么在R和Python之间会得到不同的结果?,python,r,scikit-learn,Python,R,Scikit Learn,我试图比较使用R和Python的随机森林模型的结果。我正在比较的模型性能的关键度量是AUC(ROC曲线下的面积)。原因是AUC值代表预测值的分布(即概率)。我确实发现了R和Python之间AUC值的一些显著差异。我确实读了一些关于堆栈溢出的相关问题和答案,这些问题和答案是关于R和Python之间的差异的。然而,我觉得我的问题应该与那些不同 我试图在R和Python中保持一些关键的超参数不变。它们是: 在R中设置ntree等于Python中的n\u估计量 将R中的mtry设置为Python中的ma

我试图比较使用R和Python的随机森林模型的结果。我正在比较的模型性能的关键度量是AUC(ROC曲线下的面积)。原因是AUC值代表预测值的分布(即概率)。我确实发现了R和Python之间AUC值的一些显著差异。我确实读了一些关于堆栈溢出的相关问题和答案,这些问题和答案是关于R和Python之间的差异的。然而,我觉得我的问题应该与那些不同

我试图在R和Python中保持一些关键的超参数不变。它们是:

  • 在R中设置
    ntree
    等于Python中的
    n\u估计量
  • 将R中的
    mtry
    设置为Python中的
    max\u features
  • 将R中的
    nodesize
    设置为Python中的
    min\u samples\u leaf
  • 在R和Python中将类权重设置为默认值。在R中,默认值为
    NULL
    。在Python中,默认值是
    None
  • 将R中的样本大小设置为等于训练数据中的总行数,这是Python中的默认设置
  • 将R中的
    replace
    设置为Python中的
    bootstrap
    ,即两者都是
    True
    或都是
    False
  • 该问题是一个两类分类问题,有86个预测因子。每个预测器要么是连续的,要么是布尔的。R中没有使用因子型预测因子。训练数据中有2008个观察值,测试数据中有335个观察值。两个数据中的应答率相同,即79.7%

    结果如下:

    R中的模型1结果
    培训\u auc=0.9249080
    测试\u auc=0.6308934

    R模式2的结果
    training\u auc=0.9245665
    test\u auc=0.6364838

    Python中的模型1结果
    training\u auc=0.80515863
    test\u auc=0.62194316

    Python中的模型2结果
    training\u auc=0.86075733
    test\u auc=0.6152362

    您可以发现R和Python在模型2中(非自举采样)的AUC值的差异小于模型1(自举采样),尤其是在训练数据上的AUC值

    我的问题是:

    • 为什么即使我在R和Python中设置了相同的超参数,训练数据的AUC也会有如此巨大的差异

    • 我是否遗漏了任何重要参数?或者我的R或Python代码中有错误吗

    • 如何在R中使用
      classwt
      ,在Python中如何使用
      classu-weight

    随机森林模型的R码
    这可能更适合于代码审查……您如何确保差异不是由于随机性造成的?你查过AUC的分布了吗?@Heroka谢谢你的回复!欢迎并感谢您提出任何更具体的建议。@DavidH感谢您的评论。我确实在r和python中重新运行了几次模型。我每次都会更改随机种子数。但新的AUC值非常接近您在我的文章中看到的值。这意味着R和Python之间的差异可能不是由ramdomness造成的。任何其他见解或建议都将受到欢迎和赞赏。你确定R中随机森林中的树分裂标准是“基尼”而不是熵吗?随机森林是最基本的树集成方法之一。您应该首先验证树是以相同的方式构建的。为此,您可以:1/不引导2/不在列上采样(mtry),3/只适合一棵树。请参见此级别的结果是否相似。
    library(randomForest)
    library(glmnet)
    setwd("D:/Project Files2/Python Efficiency/test RF using another dataset")
    
    #read in data for training and data for testing
    X_train01 <- read.csv("X_train_0.csv",header=FALSE)
    y_train01 <- read.csv("y_train_0.csv",header=FALSE)
    colnames(y_train01) <- "response"
    
    X_test01 <- read.csv("X_test_0.csv",header=FALSE)
    y_test01 <- read.csv("y_test_0.csv", header=FALSE)
    colnames(y_test01) <- "response"
    
    #define a function for RF
    run_quick_rf4 <- function(X_train01,y_train01, X_test01, y_test01, ntree, mtry, nodesize, maxnodes=NULL, replace=TRUE, classwt=NULL, rnd_seed= 12345){
    
      set.seed(rnd_seed)
      rf_model <- randomForest(x=X_train01,y=as.factor(y_train01[,1]),
                               ntree=ntree,
                               mtry= mtry,
                               nodesize= nodesize,
                               maxnodes= maxnodes,
                               replace = replace,
                               sampsize = nrow(X_train01),
                               classwt = classwt
      )
      train01_pred <- predict(rf_model, X_train01, type='prob')
      train01_auc <- auc(y_train01[,1], train01_pred[,2])
    
      test01_pred <- predict(rf_model, X_test01, type='prob')
      test01_auc <- auc(y_test01[,1],test01_pred[,2])
      auc_outcome<- c(train01_auc, test01_auc)
      names(auc_outcome)<- c("training_auc", "test_auc")
      return(auc_outcome)
    }
    #>>>>>>>>>>>>>>>>>>>>>>>>>End of this function>>>>>>>>>>>>>>>>>>
    
    #run random forest models with parameters set.
    
    #Model 1
    run_quick_rf4(X_train01, y_train01, X_test01, y_test01, 500, 20, 20, maxnodes=NULL, replace=TRUE, classwt=NULL, rnd_seed= 12345)
    
    #Model 2
    run_quick_rf4(X_train01, y_train01, X_test01, y_test01, 500, 20, 20, maxnodes=NULL, replace=FALSE, classwt=NULL, rnd_seed= 12345)
    
    import numpy as np
    from sklearn import cross_validation
    from sklearn.metrics import roc_auc_score
    from sklearn.ensemble import RandomForestClassifier
    import datetime
    import os
    #change work directory
    os.chdir("D:/yxue/Uplift_Gilenya/followup/Data")
    
    # only specify sample weight
    def run_quick_RF_final(file_counter, n_estimators, max_features, min_samples_leaf, max_leaf_nodes=None, class_weight={0: 1, 1: 1}, s_wt={0:1, 1:1}, bootstrap=True, random_seed=4568):
    
        x_train_file = 'X_train_%d.csv' %(file_counter)
        y_train_file = 'y_train_%d.csv' %(file_counter)
        x_test_file = 'X_test_%d.csv' %(file_counter)
        y_test_file = 'y_test_%d.csv' %(file_counter)
    
        X_train = np.loadtxt(x_train_file, delimiter=',', skiprows=0)
        y_train = np.loadtxt(y_train_file, delimiter=',', skiprows=0) 
    
        X_test = np.loadtxt(x_test_file, delimiter=',', skiprows=0)
        y_test = np.loadtxt(y_test_file, delimiter=',', skiprows=0) 
    
        rf_model = RandomForestClassifier()
        rf_model.set_params(n_estimators=n_estimators, max_features=max_features, min_samples_leaf=min_samples_leaf, max_leaf_nodes=max_leaf_nodes, class_weight=class_weight, criterion='gini', bootstrap=bootstrap, random_state=random_seed)
    
        if s_wt != None:
            sample_wt = np.ones((len(y_train),), dtype=np.float64)
            sample_wt[y_train == 0] = float(s_wt[0])
            sample_wt[y_train == 1] = float(s_wt[1])
        else:
            sample_wt = s_wt
    
        #print np.bincount(sample_wt)
        rf_model.fit(X_train, y_train, sample_weight=sample_wt)
    
        pred_train = rf_model.predict_proba(X_train)
        train_auc = roc_auc_score(y_train,pred_train[:, 1])
    
        pred_test =  rf_model.predict_proba(X_test)
        test_auc = roc_auc_score(y_test, pred_test[:, 1])
    
        auc_outcome = np.array([train_auc, test_auc])
    
        return auc_outcome
    
    # run random forest model. the parameter setting is same as in R
    # Model 1
    run_quick_RF_final(0, 500, 20, 20, max_leaf_nodes=None, class_weight=None, s_wt=None, bootstrap=True, random_seed=4568)
    
    # Model 2
    run_quick_RF_final(0, 500, 20, 20, max_leaf_nodes=None, class_weight=None, s_wt=None, bootstrap=False, random_seed=4568)