woodpecker/sklearn/decisiontree/decision_tree_structure_classifier.py
def show_decision_tree_splits_prediction(self, sample, bins=10, figsize=(10, 5)):
        """Visual interpretation of features space splits for a specified sample prediction.

        Show feature space splits for the tree nodes involved in prediction path for sample parameter.
        It is useful to

        :param figsize: tuple of int
            The figure size to be displayed
        :param bins: int
            Number of bins from histogram
        :param sample: array of doubles, shape[features]
            The array of features values
        """

        self._calculate_leaf_nodes()

        if len(self.split_node_samples) == 0:
            self._calculate_split_node_samples(self.train_dataset)

        print(list(zip(self.features, sample)))
        print()

        node_indicator = self.tree.decision_path([sample])
        node_index = node_indicator.indices[node_indicator.indptr[0]:
                                            node_indicator.indptr[1]]

        for node_id in node_index:
            if sample[self.feature[node_id]] <= self.threshold[node_id]:
                threshold_sign = "<="
            else:
                threshold_sign = ">"

            split_sample = self.train_dataset.iloc[self.split_node_samples[node_id]]

            plt.figure(figsize=figsize)
            sample_size = f"sample size {len(split_sample)}"
            class_0_size = len(split_sample.query(f'{self.target} == 0'))
            class_1_size = len(split_sample.query(f'{self.target} == 1'))
            sample_size_distribution = f"({class_0_size}/{class_1_size})"

            if self.is_leaf[node_id]:
                plt.title(
                    f"Node {node_id}, "
                    f"{sample_size}{sample_size_distribution}, "
                    f"impurity {round(self.impurity[node_id], 2)}")
            else:
                feature_split_name = f"{self.features[self.feature[node_id]]}({sample[self.feature[node_id]]})"
                plt.title(
                    f"Node {node_id}, "
                    f"{feature_split_name} {threshold_sign} {self.threshold[node_id]}, "
                    f"{sample_size}{sample_size_distribution}, "
                    f"impurity {round(self.impurity[node_id], 2)}")

            max_range = split_sample[self.features[self.feature[node_id]]].max()
            min_range = split_sample[self.features[self.feature[node_id]]].min()

            plt.hist(split_sample.query(f"{self.target} == 0")[self.features[self.feature[node_id]]],
                     label=f"{self.target} 0", bins=bins, range=(min_range, max_range))
            plt.hist(split_sample.query(f"{self.target} == 1")[self.features[self.feature[node_id]]],
                     alpha=0.8, label=f"{self.target} 1", bins=bins, range=(min_range, max_range))

            if not self.is_leaf[node_id]:
                plt.axvline(self.threshold[node_id], c="red",
                            label=f"{self.features[self.feature[node_id]]} = {self.threshold[node_id]}")

            plt.xlabel(f"{self.features[self.feature[node_id]]} range of values", fontsize=14)
            plt.ylabel(f"node examples", fontsize=14)
            plt.legend()
            plt.show()
Visual interpretation of features space splits for a specified sample prediction.

        Show feature space splits for the tree nodes involved in prediction path for sample parameter.
        It is useful to

        :param figsize: tuple of int
            The figure size to be displayed
        :param bins: int
            Number of bins from histogram
        :param sample: array of doubles, shape[features]
            The array of features values
        
Visual interpretation of features space splits for a specified sample prediction.
Show feature space splits for the tree nodes involved in prediction path for sample parameter.
It is useful to
Visual interpretation of features space splits for a specified sample prediction . Show feature space splits for the tree nodes involved in prediction path for sample parameter . It is useful to
def show_decision_tree_splits_prediction(self, sample, bins=10, figsize=(10, 5)):
        self._calculate_leaf_nodes()
        if len(self.split_node_samples) == 0:
            self._calculate_split_node_samples(self.train_dataset)
        print(list(zip(self.features, sample)))
        print()
        node_indicator = self.tree.decision_path([sample])
        node_index = node_indicator.indices[node_indicator.indptr[0]:
                                            node_indicator.indptr[1]]
        for node_id in node_index:
            if sample[self.feature[node_id]] <= self.threshold[node_id]:
                threshold_sign = "<="
            else:
                threshold_sign = ">"
            split_sample = self.train_dataset.iloc[self.split_node_samples[node_id]]
            plt.figure(figsize=figsize)
            sample_size = f"sample size {len(split_sample)}"
            class_0_size = len(split_sample.query(f'{self.target} == 0'))
            class_1_size = len(split_sample.query(f'{self.target} == 1'))
            sample_size_distribution = f"({class_0_size}/{class_1_size})"
            if self.is_leaf[node_id]:
                plt.title(
                    f"Node {node_id}, "
                    f"{sample_size}{sample_size_distribution}, "
                    f"impurity {round(self.impurity[node_id], 2)}")
            else:
                feature_split_name = f"{self.features[self.feature[node_id]]}({sample[self.feature[node_id]]})"
                plt.title(
                    f"Node {node_id}, "
                    f"{feature_split_name} {threshold_sign} {self.threshold[node_id]}, "
                    f"{sample_size}{sample_size_distribution}, "
                    f"impurity {round(self.impurity[node_id], 2)}")
            max_range = split_sample[self.features[self.feature[node_id]]].max()
            min_range = split_sample[self.features[self.feature[node_id]]].min()
            plt.hist(split_sample.query(f"{self.target} == 0")[self.features[self.feature[node_id]]],
                     label=f"{self.target} 0", bins=bins, range=(min_range, max_range))
            plt.hist(split_sample.query(f"{self.target} == 1")[self.features[self.feature[node_id]]],
                     alpha=0.8, label=f"{self.target} 1", bins=bins, range=(min_range, max_range))
            if not self.is_leaf[node_id]:
                plt.axvline(self.threshold[node_id], c="red",
                            label=f"{self.features[self.feature[node_id]]} = {self.threshold[node_id]}")
            plt.xlabel(f"{self.features[self.feature[node_id]]} range of values", fontsize=14)
            plt.ylabel(f"node examples", fontsize=14)
            plt.legend()
            plt.show()
def show_decision_tree_splits_prediction ( self , sample , bins = 10 , figsize = ( 10 , 5 ) ) : self . _calculate_leaf_nodes ( ) if len ( self . split_node_samples ) == 0 : self . _calculate_split_node_samples ( self . train_dataset ) print ( list ( zip ( self . features , sample ) ) ) print ( ) node_indicator = self . tree . decision_path ( [ sample ] ) node_index = node_indicator . indices [ node_indicator . indptr [ 0 ] : node_indicator . indptr [ 1 ] ] for node_id in node_index : if sample [ self . feature [ node_id ] ] <= self . threshold [ node_id ] : threshold_sign = "<=" else : threshold_sign = ">" split_sample = self . train_dataset . iloc [ self . split_node_samples [ node_id ] ] plt . figure ( figsize = figsize ) sample_size = f"sample size {len(split_sample)}" class_0_size = len ( split_sample . query ( f'{self.target} == 0' ) ) class_1_size = len ( split_sample . query ( f'{self.target} == 1' ) ) sample_size_distribution = f"({class_0_size}/{class_1_size})" if self . is_leaf [ node_id ] : plt . title ( f"Node {node_id}, " f"{sample_size}{sample_size_distribution}, " f"impurity {round(self.impurity[node_id], 2)}" ) else : feature_split_name = f"{self.features[self.feature[node_id]]}({sample[self.feature[node_id]]})" plt . title ( f"Node {node_id}, " f"{feature_split_name} {threshold_sign} {self.threshold[node_id]}, " f"{sample_size}{sample_size_distribution}, " f"impurity {round(self.impurity[node_id], 2)}" ) max_range = split_sample [ self . features [ self . feature [ node_id ] ] ] . max ( ) min_range = split_sample [ self . features [ self . feature [ node_id ] ] ] . min ( ) plt . hist ( split_sample . query ( f"{self.target} == 0" ) [ self . features [ self . feature [ node_id ] ] ] , label = f"{self.target} 0" , bins = bins , range = ( min_range , max_range ) ) plt . hist ( split_sample . query ( f"{self.target} == 1" ) [ self . features [ self . feature [ node_id ] ] ] , alpha = 0.8 , label = f"{self.target} 1" , bins = bins , range = ( min_range , max_range ) ) if not self . is_leaf [ node_id ] : plt . axvline ( self . threshold [ node_id ] , c = "red" , label = f"{self.features[self.feature[node_id]]} = {self.threshold[node_id]}" ) plt . xlabel ( f"{self.features[self.feature[node_id]]} range of values" , fontsize = 14 ) plt . ylabel ( f"node examples" , fontsize = 14 ) plt . legend ( ) plt . show ( )
Visual interpretation of features space splits for a specified sample prediction.
Visual interpretation of features space splits for a specified sample prediction .
"""Visual interpretation of features space splits for a specified sample prediction.

        Show feature space splits for the tree nodes involved in prediction path for sample parameter.
        It is useful to

        :param figsize: tuple of int
            The figure size to be displayed
        :param bins: int
            Number of bins from histogram
        :param sample: array of doubles, shape[features]
            The array of features values
        """
self
sample
array of doubles, shape[features]
The array of features values
array of doubles shape [ features ] The array of features values
bins
int
Number of bins from histogram
int Number of bins from histogram
figsize
tuple of int
The figure size to be displayed
tuple of int The figure size to be displayed