保存的随机森林模型在同一数据集上产生不同的结果

J·本德

使用保存在磁盘上的随机森林模型并使用完全相同的数据集进行预测时,无法再现结果。换句话说,每次我预测数据集BI获得不同的结果时,我都会使用数据集A训练模型并将其保存在本地计算机上,然后将其加载并用于预测数据集B。

我知道随机森林分类器涉及的随机性,但是据我所知,这种随机性是在训练期间进行的,一旦创建了模型,则如果您使用相同的数据进行预测,则预测不应更改。

训练脚本具有以下结构:

df_train = spark.read.format("csv") \
      .option('header', 'true') \
      .option('inferSchema', 'true') \
      .option('delimiter', ';') \
      .load("C:\2020_05.csv") 

#The problem seems to be related to the StringIndexer/One-Hot Encoding
#If I remove all categorical variables the results can be reproduced
categorical_variables = []
for variable in df_train.dtypes:
    if variable[1] == 'string' :
       categorical_variables.append(variable[0])

indexers = [StringIndexer(inputCol=col, outputCol=col+"_indexed") for col in categorical_variables]

for indexer in indexers:
    df_train =indexer.fit(df_train).transform(df_train)
    df_train = df_train.drop(indexer.getInputCol())
      
indexed_cols = []
for variable in df_train.columns:
    if variable.endswith("_indexed"):
        indexed_cols.append(variable)

encoders = []
for variable in indexed_cols:
    inputCol = variable
    outputCol = variable.replace("_indexed", "_encoded")
    one_hot_encoder_estimator_train = OneHotEncoderEstimator(inputCols=[inputCol], outputCols=[outputCol])

    encoder_model_train = one_hot_encoder_estimator_train.fit(df_train)
    df_train = encoder_model_train.transform(df_train)
    df_train = df_train.drop(inputCol)


inputCols = [x for x in df_train.columns if x != "id" and x != "churn"]

vector_assembler_train = VectorAssembler(
      inputCols=inputCols,
      outputCol='features',
      handleInvalid='keep'
)

df_train = vector_assembler_train.transform(df_train)

df_train = df_train.select('churn', 'features', 'id')

df_train_1 = df_train.filter(df_train['churn'] == 0).sample(withReplacement=False, fraction=0.3, seed=7)
df_train_2 = df_train.filter(df_train['churn'] == 1).sample(withReplacement=True, fraction=20.0, seed=7)
df_train = df_train_1.unionAll(df_train_2) 

rf = RandomForestClassifier(labelCol="churn", featuresCol="features")
  paramGrid = ParamGridBuilder() \
      .addGrid(rf.numTrees, [100]) \
      .addGrid(rf.maxDepth, [15]) \
      .addGrid(rf.maxBins, [32]) \
      .addGrid(rf.featureSubsetStrategy, ['onethird']) \
      .addGrid(rf.subsamplingRate, [1.0])\
      .addGrid(rf.minInfoGain, [0.0])\
      .addGrid(rf.impurity, ['gini']) \
      .addGrid(rf.minInstancesPerNode, [1]) \
      .addGrid(rf.seed, [10]) \
  .build()



  evaluator = BinaryClassificationEvaluator(
      labelCol="churn")

  crossval = CrossValidator(estimator=rf,
                            estimatorParamMaps=paramGrid,
                            evaluator=evaluator,
                            numFolds=3)
  model = crossval.fit(df_train)
  model.save("C:/myModel")

测试脚本如下:

df_test = spark.read.format("csv") \
      .option('header', 'true') \
      .option('inferSchema', 'true') \
      .option('delimiter', ';') \
      .load("C:\2020_06.csv")
  
#The problem seems to be related to the StringIndexer/One-Hot Encoding
#If I remove all categorical variables the results can be reproduced
categorical_variables = []
for variable in df_test.dtypes:
    if variable[1] == 'string' :
       categorical_variables.append(variable[0])

indexers = [StringIndexer(inputCol=col, outputCol=col+"_indexed") for col in categorical_variables]

for indexer in indexers:
    df_test =indexer.fit(df_test).transform(df_test)
    df_test = df_test.drop(indexer.getInputCol())
      
indexed_cols = []
for variable in df_test.columns:
    if variable.endswith("_indexed"):
        indexed_cols.append(variable)

encoders = []
for variable in indexed_cols:
    inputCol = variable
    outputCol = variable.replace("_indexed", "_encoded")
    one_hot_encoder_estimator_test = OneHotEncoderEstimator(inputCols=[inputCol], outputCols=[outputCol])

    encoder_model_test= one_hot_encoder_estimator_test.fit(df_test)
    df_test= encoder_model_test.transform(df_test)
    df_test= df_test.drop(inputCol)


inputCols = [x for x in df_test.columns if x != "id" and x != "churn"]

vector_assembler_test = VectorAssembler(
      inputCols=inputCols,
      outputCol='features',
      handleInvalid='keep'
)

df_test = vector_assembler_test.transform(df_test)

df_test = df_test.select('churn', 'features', 'id')


model = CrossValidatorModel.load("C:/myModel")

result = model.transform(df_test)

areaUnderROC = evaluator.evaluate(result)

tp = result.filter("prediction == 1.0 AND churn == 1").count()
tn = result.filter("prediction == 0.0 AND churn == 0").count()
fp = result.filter("prediction == 1.0 AND churn == 0").count()
fn = result.filter("prediction == 0.0 AND churn == 1").count()

每次我运行测试脚本时,AUC和混淆矩阵总是不同的。我在Windows 10计算机上使用Spark 2.4.5和Python 3.7。任何建议或想法都非常感谢。

编辑:问题与StringIndexer /单热点编码步骤有关。当我只使用数字变量时,我可以重现结果。由于我无法解释为什么会发生,所以这个问题仍然悬而未决。

多维·乔尔(Dovi Joel)

以我的经验,此问题是因为您正在重新评估测试中的OneHotEncoder。

这是docs中的OneHotEncoding的工作方式

一种单编码器,将一类类别索引映射到一列二进制矢量,每行最多有一个单一的单值指示输入类别索引。例如,对于5个类别,输入值2.0将映射到[0.0、0.0、1.0、0.0]的输出向量。默认情况下不包括最后一个类别(可通过dropLast进行配置),因为它使向量条目的总和为1,因此线性相关。因此,输入值4.0映射为[0.0,0.0,0.0,0.0]。

因此,每次数据不同时(火车与测试自然是这种情况),一个热编码器在矢量中产生的值就不同。

您应该将OneHotEncoder和训练有素的模型一起添加到管道中,进行拟合然后保存,然后在测试中再次加载。这样,每次通过管道运行数据时,都可以确保将一个热编码值与相同值匹配。

有关保存和加载管道的更多详细信息,请参见文档

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

饼图布局在Firefox和Chrome上针对同一数据集产生不同的顺序

来自分类Dev

同一数组不同结果

来自分类Dev

解释随机森林模型结果

来自分类Dev

同一数据集的日期范围

来自分类Dev

同一数据集的日期范围

来自分类Dev

同一时间在同一数据库上执行相同查询,但结果不同??[大查询]

来自分类Dev

如何从不同页面抓取数据并分配给同一数据集?

来自分类Dev

在一个查询中显示来自同一数据集的不同值

来自分类Dev

有效/简单地对同一数据集的不同范围进行计数

来自分类Dev

小数精度沿同一数据集的工作方式不同

来自分类Dev

为什么在同一数据集上,准确性和validation_accuracy完全不同(没有规范化或丢失)?

来自分类Dev

R-在同一数据集上使用函数n次

来自分类Dev

在同一数据库上使用多个FluentMigrator程序集

来自分类Dev

在同一数据库上执行时,dblink会使用不同的会话吗?

来自分类Dev

在同一数据库上执行时,dblink使用不同的会话吗?

来自分类Dev

访问:同一数据库上的 2 个角色具有不同的角色

来自分类Dev

FusionCharts 无法在同一数据源上绘制不同的图表

来自分类Dev

随机森林模型中预测结果的差异

来自分类Dev

将不同设备上的同一应用程序连接到同一数据库

来自分类Dev

同一数据框中的多个线性模型

来自分类Dev

星火:在同一数据集排减值

来自分类Dev

Matplotlib同一数据集的多个比例

来自分类Dev

MongoDB:如何在同一数据库中搜索多个集合并返回混合结果集?

来自分类Dev

MongoDB:如何在同一数据库中搜索多个集合并返回混合结果集?

来自分类Dev

在同一模型中注释会产生意外结果

来自分类Dev

同一数据库上的 Asp.NET 和 Asp.NET Core Identity 模型

来自分类Dev

nmap -sn和-sL对同一主机产生不同的结果

来自分类Dev

如何在同一视图控制器上为不同的pickerview设置不同的数据集

来自分类Dev

从JS中的同一数组中获取两个不同的随机项

Related 相关文章

  1. 1

    饼图布局在Firefox和Chrome上针对同一数据集产生不同的顺序

  2. 2

    同一数组不同结果

  3. 3

    解释随机森林模型结果

  4. 4

    同一数据集的日期范围

  5. 5

    同一数据集的日期范围

  6. 6

    同一时间在同一数据库上执行相同查询,但结果不同??[大查询]

  7. 7

    如何从不同页面抓取数据并分配给同一数据集?

  8. 8

    在一个查询中显示来自同一数据集的不同值

  9. 9

    有效/简单地对同一数据集的不同范围进行计数

  10. 10

    小数精度沿同一数据集的工作方式不同

  11. 11

    为什么在同一数据集上,准确性和validation_accuracy完全不同(没有规范化或丢失)?

  12. 12

    R-在同一数据集上使用函数n次

  13. 13

    在同一数据库上使用多个FluentMigrator程序集

  14. 14

    在同一数据库上执行时,dblink会使用不同的会话吗?

  15. 15

    在同一数据库上执行时,dblink使用不同的会话吗?

  16. 16

    访问:同一数据库上的 2 个角色具有不同的角色

  17. 17

    FusionCharts 无法在同一数据源上绘制不同的图表

  18. 18

    随机森林模型中预测结果的差异

  19. 19

    将不同设备上的同一应用程序连接到同一数据库

  20. 20

    同一数据框中的多个线性模型

  21. 21

    星火:在同一数据集排减值

  22. 22

    Matplotlib同一数据集的多个比例

  23. 23

    MongoDB:如何在同一数据库中搜索多个集合并返回混合结果集?

  24. 24

    MongoDB:如何在同一数据库中搜索多个集合并返回混合结果集?

  25. 25

    在同一模型中注释会产生意外结果

  26. 26

    同一数据库上的 Asp.NET 和 Asp.NET Core Identity 模型

  27. 27

    nmap -sn和-sL对同一主机产生不同的结果

  28. 28

    如何在同一视图控制器上为不同的pickerview设置不同的数据集

  29. 29

    从JS中的同一数组中获取两个不同的随机项

热门标签

归档