【问题标题】:Pyspark random forest feature importance mapping after column transformations列变换后的 Pyspark 随机森林特征重要性映射
【发布时间】:2018-11-28 23:02:02
【问题描述】:

我正在尝试使用列名绘制某些基于树的模型的特征重要性。我正在使用 Pyspark。

因为我也有文本分类变量和数字变量,所以我不得不使用类似这样的管道方法 -

  1. 使用字符串索引器来索引字符串列
  2. 对所有列使用一个热编码器
  3. 使用向量组装器创建包含特征向量的特征列

    来自docs 的一些示例代码,用于步骤 1、2、3 -

    from pyspark.ml import Pipeline
    from pyspark.ml.feature import OneHotEncoderEstimator, StringIndexer, 
    VectorAssembler
    categoricalColumns = ["workclass", "education", "marital_status", 
    "occupation", "relationship", "race", "sex", "native_country"]
     stages = [] # stages in our Pipeline
     for categoricalCol in categoricalColumns:
        # Category Indexing with StringIndexer
        stringIndexer = StringIndexer(inputCol=categoricalCol, 
        outputCol=categoricalCol + "Index")
        # Use OneHotEncoder to convert categorical variables into binary 
        SparseVectors
        # encoder = OneHotEncoderEstimator(inputCol=categoricalCol + "Index", 
        outputCol=categoricalCol + "classVec")
        encoder = OneHotEncoderEstimator(inputCols= 
        [stringIndexer.getOutputCol()], outputCols=[categoricalCol + "classVec"])
        # Add stages.  These are not run here, but will run all at once later on.
        stages += [stringIndexer, encoder]
    
    numericCols = ["age", "fnlwgt", "education_num", "capital_gain", 
    "capital_loss", "hours_per_week"]
    assemblerInputs = [c + "classVec" for c in categoricalColumns] + numericCols
    assembler = VectorAssembler(inputCols=assemblerInputs, outputCol="features")
    stages += [assembler]
    
    # Create a Pipeline.
    pipeline = Pipeline(stages=stages)
    # Run the feature transformations.
    #  - fit() computes feature statistics as needed.
    #  - transform() actually transforms the features.
    pipelineModel = pipeline.fit(dataset)
    dataset = pipelineModel.transform(dataset)
    
  4. 最终训练模型

    在训练和评估之后,我可以使用“model.featureImportances”来获得特征排名,但是我没有获得特征/列名,而只是特征编号,像这样 -

    print dtModel_1.featureImportances
    
    (38895,[38708,38714,38719,38720,38737,38870,38894],[0.0742343395738,0.169404823667,0.100485791055,0.0105823115814,0.0134236162982,0.194124862158,0.437744255667])
    

如何将其映射回初始列名和值?这样我就可以绘图了?**

【问题讨论】:

    标签: apache-spark pyspark apache-spark-sql apache-spark-mllib


    【解决方案1】:

    通过user6910411将元数据提取为shown here

    attrs = sorted(
        (attr["idx"], attr["name"]) for attr in (chain(*dataset
            .schema["features"]
            .metadata["ml_attr"]["attrs"].values())))
    

    并结合特征重要性:

    [(name, dtModel_1.featureImportances[idx])
     for idx, name in attrs
     if dtModel_1.featureImportances[idx]]
    

    【讨论】:

    • 是的,我实际上能够弄清楚。我的做法略有不同,我创建了一个带有 idx 和特征名称的 pandas 数据框,然后转换为一个广播变量的字典。 code
    • pandasDF = pd.DataFrame(dataset.schema["features"].metadata["ml_attr"]["attrs"]["binary"]+dataset.schema["features"].metadata["ml_attr"]["attrs"]["numeric"]).sort_values("idx") feature_dict = dict(zip(pandasDF["idx"],pandasDF["name"])) feature_dict_broad = sc.broadcast(feature_dict)
    【解决方案2】:

    转换后的数据集元数据具有所需的属性。这是一个简单的方法 -

    1. 创建一个 pandas 数据框(通常特征列表不会很大,因此存储 pandas DF 不会出现内存问题)

      pandasDF = pd.DataFrame(dataset.schema["features"].metadata["ml_attr"] 
      ["attrs"]["binary"]+dataset.schema["features"].metadata["ml_attr"]["attrs"]["numeric"]).sort_values("idx")
      
    2. 然后创建一个广播字典来映射。在分布式环境中广播是必要的。

      feature_dict = dict(zip(pandasDF["idx"],pandasDF["name"])) 
      
      feature_dict_broad = sc.broadcast(feature_dict)
      

    【讨论】:

    • 当我这样做时,它不会显示我的数字列名称,它只是说“numeric_feature_1”、“numeric_feature_2”......我对我的数字变量进行了一些转换。这会让它们消失吗?
    【解决方案3】:

    在创建汇编程序时,您使用了变量列表 (assemblerInputs)。顺序保存在“特征”变量中。所以只需做一个 Pandas DataFrame:

    features_imp_pd = (
         pd.DataFrame(
           dtModel_1.featureImportances.toArray(), 
           index=assemblerInputs, 
           columns=['importance'])
    )
    

    【讨论】:

      猜你喜欢
      • 2017-06-13
      • 2015-05-12
      • 2021-05-09
      • 2021-08-29
      • 2019-06-17
      • 2021-05-13
      • 1970-01-01
      • 2020-05-26
      • 2017-10-21
      相关资源
      最近更新 更多