1
resposta

Erro ao plotar a árvore: NotFittedError

Olá

Estou utilizando os dados do Titanic da competição do Kaggle e ao tentar visualizar a árvore é disparado o seguinte erro:

NotFittedError: This Pipeline instance is not fitted yet. Call 'fit' with appropriate arguments before using this estimator.

Mas o fit do modelo foi realizado:

# Pipeline
pipe_decision_tree = Pipeline([('Ohe', OneHotEncoder(handle_unknown='ignore')),
                                                  ('MaxAbsScale', MaxAbsScaler()),
                                                  ('Model', DecisionTreeClassifier(random_state=93))])

# Treino, teste e acurácia
x = train.drop('Survived', axis=1)
y = train['Survived']
x_train, x_test, y_train, y_test = train_test_split(x, y, stratify=y, random_state=93)
model_decision_tree = pipe_decision_tree.fit(x_train, y_train)
print(f'Decision Tree Classifier Score: {round(model_decision_tree.score(x_test, y_test) * 100)}%')

# Árvore de decisão
features = x.columns
dot_data = export_graphviz(model_decision_tree, feature_names=features, 
                           filled=True, rounded=True)
grafico = graphviz.Source(dot_data)
grafico
1 resposta

Oii Marcos, tudo bem?

Desculpa a demora em te responder por aqui.

Para você conseguir fazer isso, vai precisar acessar o modelo no Pipeline. Para isso basta utilizar o atributo steps, e depois acessar o modelo que é o terceiro step, model_decision_tree.steps[2], isso vai retornar uma tupla com o nome do step e o objeto, como queremos o objeto podemos acessar o segundo valor model_decision_tree.steps[2][1] e pronto teremos o modelo treinado para utilizar no export_graphviz.

Outro problema que vai acontecer é com o parâmetro feature_names, já que você usou o OneHotEncoder, vai ter bem mais colunas / features que tinha inicialmente, então você vai precisar trocar a linha features = x.columns. Para verificar as novas features criadas, você vai precisar acessar o primeiro step e o segundo valor que vai ser o objeto do OneHotEnconder, agora que temos o objeto, você pode acessar o parâmetro .categories_.

Você pode fazer um código para colocar todos os valores em uma lista e utilizar um for para percorrer as 11 features que você tinha inicialmente e depois um segundo for para passar por cada possibilidade de valor e salvar tudo isso em uma lista.

features = [valor for features in model_decision_tree.steps[0][1].categories_ for valor in features]

Código completo:

# Pipeline
pipe_decision_tree = Pipeline([('Ohe', OneHotEncoder(handle_unknown='ignore')),
('MaxAbsScale', MaxAbsScaler()),
('Model', DecisionTreeClassifier(random_state=93))])

# Treino, teste e acurácia
x = train.drop('Survived', axis=1)
y = train['Survived']
x_train, x_test, y_train, y_test = train_test_split(x, y, stratify=y, random_state=93)
model_decision_tree = pipe_decision_tree.fit(x_train, y_train)
print(f'Decision Tree Classifier Score: {round(model_decision_tree.score(x_test, y_test) * 100)}%')

# Árvore de decisão
features = [valor for features in model_decision_tree.steps[0][1].categories_ for valor in features]
dot_data = export_graphviz(model_decision_tree.steps[2][1], feature_names=features, 
                           filled=True, rounded=True)
grafico = graphviz.Source(dot_data)
grafico

Espero ter ajudado! Qualquer outra dúvida pode nos chamar aqui no Fórum.

Bons estudos ^^