Sklearn: aplicação de redução de complexidade de custo junto com pipeline

Oct 18 2020

Eu tenho um conjunto de dados com variáveis ​​categóricas. Eu defini um algoritmo de árvore de decisão e transformei essas colunas em um equivalente numérico usando uma funcionalidade de codificação ativa em sklearn:

Criar objeto classificador de árvore de decisão:

clf2 = DecisionTreeClassifier(criterion = 'entropy')
pipe = make_pipeline(column_trans, clf2)            # (1)
pipe.fit(X_train2,y_train2)

Onde:

column_trans = make_column_transformer(
            (OneHotEncoder(),['ShelveLoc','Urban','US']),
             remainder = 'passthrough')

Agora, quando construí a árvore de decisão sem usar sklearn, mas usando pandas diretamente para codificação de recursos categóricos, fui capaz de encontrar os candidatos adequados para alfa para podar a árvore de decisão por

path = clf.cost_complexity_pruning_path(X_train, y_train)
ccp_alphas = path.ccp_alphas
ccp_alphas = ccp_alphas[:-1] #remove max value of alpha

onde, como agora, dado que meu modelo está embutido no argumento de tubo em (1) quando tento encontrar alfas candidatos

path = pipe.cost_complexity_pruning_path(X_train2, y_train2)

Recebo uma mensagem de erro dizendo que o tubo não tem o atributo denominado poda de complexidade de custo . e olhando para todos os atributos disponíveis para tubulação, não consigo encontrar poda de complexidade de custo também.

Só é possível fazer a poda de complexidade de custo se você estiver construindo o modelo sem usar a funcionalidade de tubo no Sklearn?

Respostas

1 BenReiniger Oct 19 2020 at 08:06

Pipelines-se geralmente não carregam os métodos e atributos do estimador final, além do básico, como predict, predict_proba, transform. Se precisar acessar o método de uma etapa, você deve acessar a própria etapa usando um dos seguintes:

pipe[-1]
pipe['decisiontreeclassifier']
pipe.named_steps['decisiontreeclassifier']

No entanto, neste caso é um pouco mais complicado, porque cost_complexity_pruning_pathprecisa do conjunto de dados X, y, mas você precisa do transformador do pipeline para aplicá-lo primeiro. É um pouco complicado, mas acho que deve funcionar e é relativamente simples:

pipe[-1].cost_complexity_pruning_path(
    pipe[:-1].transform(X),
    y,
)

(Observe que pipe[-1]é o estimador final no pipeline e pipe[:-1]está em todas as etapas, exceto a última.)

Codeman340 Oct 19 2020 at 03:56

Tive a primeira chance de pensar em uma solução alternativa, embora seja feio e não tenha escala:

alpha_candidates = (np.arange(0.0,0.5, 0.001)).tolist()
alpha_accuracy_list = []
# Create Decision Tree classifer object
for i in alpha_candidates:
    clf2_entropy_alpha = DecisionTreeClassifier(criterion = 'entropy', ccp_alpha= i,random_state=42)
    pipe = make_pipeline(column_trans, clf2_entropy_alpha)
    pipe.fit(X_train2,y_train2)
    y_pred2_entropy_alpha = pipe.predict(X_test2)
    alpha_accuracy = [i, metrics.accuracy_score(y_test2, y_pred2_entropy_alpha)] 
    alpha_accuracy_list.append(alpha_accuracy)

Pensamentos?