【问题标题】:Regarding featuretools, the rank results are wrong关于特征工具,排名结果是错误的
【发布时间】:2021-09-18 15:03:45
【问题描述】:

使用 Featuretools,我想将某个特征的值转换为排名。

这将是确切的问题。如果有人可以帮助我,请回答。

首先,下面的代码使用pandas的rank函数并显示结果。我相信这个结果是正确的。

import pandas as pd
df = pd.DataFrame({'col1': [50, 80, 100, 80,90,100,150],
                   'col2': [0.3, 0.05, 0.1, 0.1,0.4,0.7,0.9]})
print(df.rank(method="dense",ascending=True))

但是,当我创建自定义原语并运行以下代码时,结果会有所不同。为什么会这样?如果我的代码有误,请修复我的代码。非常感谢您的帮助。

from featuretools.primitives import TransformPrimitive
from featuretools.variable_types import Numeric
import pandas as pd

class Rank(TransformPrimitive):
    name = 'rank'
    input_types = [Numeric]
    return_type = Numeric

    def get_function(self):
        def rank(column):
            return column.rank(method="dense",ascending=True)     
        return rank

df = pd.DataFrame({'col1': [50, 80, 100, 80,90,100,150],
                   'col2': [0.3, 0.05, 0.1, 0.1,0.4,0.7,0.9]})

import featuretools as ft
es = ft.EntitySet(id="test_es",     
                  entities=None,
                  relationships=None)

es.entity_from_dataframe(entity_id="data",
                         dataframe=df,
                         index="index",
                         variable_types=None,
                         make_index=True,
                         time_index=None,
                         secondary_time_index=None,
                         already_sorted=False)

feature_matrix, feature_defs = ft.dfs(entities=None,
                                      relationships=None,
                                      entityset=es,  
                                      target_entity="data", 
                                      cutoff_time=None,
                                      instance_ids=None,
                                      agg_primitives=None, 
                                      trans_primitives=[Rank], 
                                      groupby_trans_primitives=None, 
                                      allowed_paths=None,
                                      max_depth=2,
                                      ignore_entities=None, 
                                      ignore_variables=None, 
                                      primitive_options=None, 
                                      seed_features=None, 
                                      drop_contains=None,
                                      drop_exact=None,
                                      where_primitives=None,
                                      max_features=-1,
                                      cutoff_time_in_index=False,
                                      save_progress=None,
                                      features_only=False,
                                      training_window=None,
                                      approximate=None,
                                      chunk_size=None,
                                      n_jobs=-1,
                                      dask_kwargs=None,
                                      verbose=False,
                                      return_variable_types=None,
                                      progress_callback=None,     
                                      include_cutoff_time=False)
feature_matrix 

这是结果。

enter image description here

但是,当我尝试以下代码时,我能够获得正确的数据。 为什么答案不同?

import pandas as pd
df = pd.DataFrame({'col1': [50, 80, 100, 80,90,100,150],
                   'col2': [0.3, 0.05, 0.1, 0.1,0.4,0.7,0.9]})
print(df.rank(method="dense",ascending=True))


pd.set_option('display.max_columns', 2000)

  
import featuretools as ft
es = ft.EntitySet()
es.entity_from_dataframe(entity_id='data',
                         dataframe=df,
                         index='index')

fm, fd = ft.dfs(entityset=es,
            target_entity='data',
            trans_primitives=[Rank])
fm

【问题讨论】:

    标签: python featuretools


    【解决方案1】:

    新答案: 根据您更新的代码,出现问题是因为您正在设置njobs=-1。当您这样做时,Featuretools 在幕后将特征矩阵的计算分配给多个工作人员。在此过程中,Featuretools 正在分解数据帧以计算工作人员之间的转换特征值并将片段发送给每个工作人员。

    这会导致您定义的Rank 原语出现问题,因为此原语需要所有数据都存在才能获得正确答案。对于这种情况,您需要在定义原语时设置uses_full_entity=True,以在调用原语函数计算特征值时强制特征工具包含所有数据。

    如果你更新Rank原语定义如下,你会得到正确答案:

    class Rank(TransformPrimitive):
        name = 'rank'
        input_types = [Numeric]
        return_type = Numeric
        uses_full_entity = True
    
        def get_function(self):
            def rank(column):
                return column.rank(method="dense",ascending=True)     
            return rank
    

    旧答案: 在您定义的自定义原语函数中,您传递给rank 的参数与您在DataFrame 上直接调用rank 时使用的参数不同。

    直接在 DataFrame 上调用时,您使用以下参数:

    .rank(method="min", ascending=False, numeric_only=True)
    

    在自定义原始函数中,您使用不同的值:

    .rank(method="dense", ascending=True) 
    

    如果您更新原始函数以使用相同的参数,您从 Featuretools 获得的结果应该与直接在 DataFrame 上调用 rank 时获得的结果相匹配。

    【讨论】:

    • 对不起。我犯了一个粗心的错误,问错了问题。上面我写了一个新代码,请检查一下
    • 我看不出你的代码有什么不同。你改变了什么?
    • 对不起,我的问题已被自动删除。我更新了我的问题。请再次检查。
    • 我已更新答案以反映更新后的问题。
    • 我能够确认。非常感谢您的善意和支持。
    猜你喜欢
    • 2019-01-30
    • 2020-12-14
    • 2018-12-13
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 2016-09-12
    • 2019-07-09
    • 1970-01-01
    相关资源
    最近更新 更多