We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[FEAT] Support sklearn 0.23.2
Currently we only support sklearn versions >= 1.0. We need to try to support the 0.23.2 as it is widely used by many environments and frameworks.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `deepchecks/core/check_utils/whole_dataset_drift_utils.py`
Content:
```
1 # ----------------------------------------------------------------------------
2 # Copyright (C) 2021-2022 Deepchecks (https://www.deepchecks.com)
3 #
4 # This file is part of Deepchecks.
5 # Deepchecks is distributed under the terms of the GNU Affero General
6 # Public License (version 3 or later).
7 # You should have received a copy of the GNU Affero General Public License
8 # along with Deepchecks.  If not, see <http://www.gnu.org/licenses/>.
9 # ----------------------------------------------------------------------------
10 #
11 """Module containing common WholeDatasetDriftCheck (domain classifier drift) utils."""
12 
13 from typing import List
14 import warnings
15 
16 import numpy as np
17 import pandas as pd
18 from plotly.subplots import make_subplots
19 
20 from sklearn.pipeline import Pipeline
21 from sklearn.compose import ColumnTransformer
22 
23 with warnings.catch_warnings():
24     warnings.simplefilter('ignore')
25     from sklearn.experimental import enable_hist_gradient_boosting  # noqa # pylint: disable=unused-import
26 
27 from sklearn.ensemble import HistGradientBoostingClassifier
28 from sklearn.metrics import roc_auc_score
29 from sklearn.preprocessing import OrdinalEncoder
30 from sklearn.model_selection import train_test_split
31 import plotly.graph_objects as go
32 
33 from deepchecks.tabular import Dataset
34 from deepchecks.utils.distribution.plot import feature_distribution_traces, drift_score_bar_traces
35 from deepchecks.utils.distribution.rare_category_encoder import RareCategoryEncoder
36 from deepchecks.utils.features import N_TOP_MESSAGE, calculate_feature_importance_or_none
37 from deepchecks.utils.function import run_available_kwargs
38 from deepchecks.utils.strings import format_percent
39 from deepchecks.utils.typing import Hashable
40 
41 
42 def run_whole_dataset_drift(train_dataframe: pd.DataFrame, test_dataframe: pd.DataFrame,
43                             numerical_features: List[Hashable], cat_features: List[Hashable], sample_size: int,
44                             random_state: int, test_size: float, n_top_columns: int, min_feature_importance: float,
45                             max_num_categories_for_display: int, show_categories_by: str,
46                             min_meaningful_drift_score: float):
47     """Calculate whole dataset drift."""
48     domain_classifier = generate_model(numerical_features, cat_features, random_state)
49 
50     train_sample_df = train_dataframe.sample(sample_size, random_state=random_state)
51     test_sample_df = test_dataframe.sample(sample_size, random_state=random_state)
52 
53     # create new dataset, with label denoting whether sample belongs to test dataset
54     domain_class_df = pd.concat([train_sample_df, test_sample_df])
55     domain_class_labels = pd.Series([0] * len(train_sample_df) + [1] * len(test_sample_df))
56 
57     x_train, x_test, y_train, y_test = train_test_split(domain_class_df, domain_class_labels,
58                                                         stratify=domain_class_labels,
59                                                         random_state=random_state,
60                                                         test_size=test_size)
61 
62     domain_classifier = domain_classifier.fit(x_train, y_train)
63 
64     y_test.name = 'belongs_to_test'
65     domain_test_dataset = Dataset(pd.concat([x_test.reset_index(drop=True), y_test.reset_index(drop=True)], axis=1),
66                                   cat_features=cat_features, label='belongs_to_test')
67 
68     # calculate feature importance of domain_classifier, containing the information which features separate
69     # the dataset best.
70     fi, importance_type = calculate_feature_importance_or_none(
71         domain_classifier,
72         domain_test_dataset,
73         force_permutation=True,
74         permutation_kwargs={'n_repeats': 10, 'random_state': random_state, 'timeout': 120}
75     )
76 
77     fi = fi.sort_values(ascending=False) if fi is not None else None
78 
79     domain_classifier_auc = roc_auc_score(y_test, domain_classifier.predict_proba(x_test)[:, 1])
80     drift_score = auc_to_drift_score(domain_classifier_auc)
81 
82     values_dict = {
83         'domain_classifier_auc': domain_classifier_auc,
84         'domain_classifier_drift_score': drift_score,
85         'domain_classifier_feature_importance': fi.to_dict() if fi is not None else {},
86     }
87 
88     feature_importance_note = f"""
89     <span>
90     The percents of explained dataset difference are the importance values for the feature calculated
91     using `{importance_type}`.
92     </span><br><br>
93     """
94 
95     if fi is not None and drift_score > min_meaningful_drift_score:
96         top_fi = fi.head(n_top_columns)
97         top_fi = top_fi.loc[top_fi > min_feature_importance]
98     else:
99         top_fi = None
100 
101     if top_fi is not None and len(top_fi):
102         score = values_dict['domain_classifier_drift_score']
103 
104         displays = [feature_importance_note, build_drift_plot(score),
105                     '<h3>Main features contributing to drift</h3>',
106                     N_TOP_MESSAGE % n_top_columns]
107         displays += [display_dist(train_sample_df[feature], test_sample_df[feature], top_fi, cat_features,
108                                   max_num_categories_for_display, show_categories_by)
109                      for feature in top_fi.index]
110     else:
111         displays = None
112 
113     return values_dict, displays
114 
115 
116 def generate_model(numerical_columns: List[Hashable], categorical_columns: List[Hashable],
117                    random_state: int = 42) -> Pipeline:
118     """Generate the unfitted Domain Classifier model."""
119     categorical_transformer = Pipeline(
120         steps=[('rare', RareCategoryEncoder(254)),
121                ('encoder', run_available_kwargs(OrdinalEncoder, handle_unknown='use_encoded_value',
122                                                 unknown_value=np.nan,
123                                                 dtype=np.float64))]
124     )
125 
126     preprocessor = ColumnTransformer(
127         transformers=[
128             ('num', 'passthrough', numerical_columns),
129             ('cat', categorical_transformer, categorical_columns),
130         ]
131     )
132 
133     return Pipeline(
134         steps=[('preprocessing', preprocessor),
135                ('model', HistGradientBoostingClassifier(
136                    max_depth=2, max_iter=10, random_state=random_state,
137                    categorical_features=[False] * len(numerical_columns) + [True] * len(categorical_columns)
138                ))])
139 
140 
141 def auc_to_drift_score(auc: float) -> float:
142     """Calculate the drift score, which is 2*auc - 1, with auc being the auc of the Domain Classifier.
143 
144     Parameters
145     ----------
146     auc : float
147         auc of the Domain Classifier
148     """
149     return max(2 * auc - 1, 0)
150 
151 
152 def build_drift_plot(score):
153     """Build traffic light drift plot."""
154     bar_traces, x_axis, y_axis = drift_score_bar_traces(score)
155     x_axis['title'] = 'Drift score'
156     drift_plot = go.Figure(layout=dict(
157         title='Drift Score - Whole Dataset Total',
158         xaxis=x_axis,
159         yaxis=y_axis,
160         width=700,
161         height=200
162 
163     ))
164 
165     drift_plot.add_traces(bar_traces)
166     return drift_plot
167 
168 
169 def display_dist(train_column: pd.Series, test_column: pd.Series, fi_ser: pd.Series, cat_features,
170                  max_num_categories, show_categories_by):
171     """Display a distribution comparison plot for the given columns."""
172     column_name = train_column.name
173 
174     title = f'Feature: {column_name} - Explains {format_percent(fi_ser.loc[column_name])} of dataset difference'
175     dist_traces, xaxis_layout, yaxis_layout = \
176         feature_distribution_traces(train_column.dropna(),
177                                     test_column.dropna(),
178                                     column_name,
179                                     is_categorical=column_name in cat_features,
180                                     max_num_categories=max_num_categories,
181                                     show_categories_by=show_categories_by)
182 
183     all_categories = list(set(train_column).union(set(test_column)))
184     add_footnote = column_name in cat_features and len(all_categories) > max_num_categories
185 
186     if add_footnote:
187         fig = make_subplots(rows=2, cols=1, vertical_spacing=0.6, shared_yaxes=False, shared_xaxes=False,
188                             row_heights=[0.8, 0.2],
189                             subplot_titles=[title])
190 
191         fig.add_traces(dist_traces)
192 
193         param_to_print_dict = {
194             'train_largest': 'largest categories (by train)',
195             'test_largest': 'largest categories (by test)',
196             'largest_difference': 'largest difference between categories'
197         }
198         train_data_percents = dist_traces[0].y.sum()
199         test_data_percents = dist_traces[1].y.sum()
200 
201         fig.add_annotation(
202             x=0, y=-0.2, showarrow=False, xref='paper', yref='paper', xanchor='left',
203             text=f'* Showing the top {max_num_categories} {param_to_print_dict[show_categories_by]} out of '
204                  f'total {len(all_categories)} categories.'
205                  f'<br>Shown data is {format_percent(train_data_percents)} of train data and '
206                  f'{format_percent(test_data_percents)} of test data.'
207         )
208 
209     else:
210         fig = go.Figure()
211         fig.add_traces(dist_traces)
212 
213     layout = go.Layout(
214         title=title,
215         xaxis=xaxis_layout,
216         yaxis=yaxis_layout,
217         legend=dict(
218             title='Dataset',
219             yanchor='top',
220             y=0.9,
221             xanchor='left'),
222         width=700,
223         height=300
224     )
225 
226     fig.update_layout(layout)
227 
228     return fig
229
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/deepchecks/core/check_utils/whole_dataset_drift_utils.py b/deepchecks/core/check_utils/whole_dataset_drift_utils.py
--- a/deepchecks/core/check_utils/whole_dataset_drift_utils.py
+++ b/deepchecks/core/check_utils/whole_dataset_drift_utils.py
@@ -132,10 +132,11 @@
 
     return Pipeline(
         steps=[('preprocessing', preprocessor),
-               ('model', HistGradientBoostingClassifier(
-                   max_depth=2, max_iter=10, random_state=random_state,
-                   categorical_features=[False] * len(numerical_columns) + [True] * len(categorical_columns)
-               ))])
+               ('model', run_available_kwargs(HistGradientBoostingClassifier,
+                                              max_depth=2, max_iter=10, random_state=random_state,
+                                              categorical_features=[False] * len(numerical_columns)
+                                              + [True] * len(categorical_columns)
+                                              ))])
 
 
 def auc_to_drift_score(auc: float) -> float:

{"golden_diff": "diff --git a/deepchecks/core/check_utils/whole_dataset_drift_utils.py b/deepchecks/core/check_utils/whole_dataset_drift_utils.py\n--- a/deepchecks/core/check_utils/whole_dataset_drift_utils.py\n+++ b/deepchecks/core/check_utils/whole_dataset_drift_utils.py\n@@ -132,10 +132,11 @@\n \n     return Pipeline(\n         steps=[('preprocessing', preprocessor),\n-               ('model', HistGradientBoostingClassifier(\n-                   max_depth=2, max_iter=10, random_state=random_state,\n-                   categorical_features=[False] * len(numerical_columns) + [True] * len(categorical_columns)\n-               ))])\n+               ('model', run_available_kwargs(HistGradientBoostingClassifier,\n+                                              max_depth=2, max_iter=10, random_state=random_state,\n+                                              categorical_features=[False] * len(numerical_columns)\n+                                              + [True] * len(categorical_columns)\n+                                              ))])\n \n \n def auc_to_drift_score(auc: float) -> float:\n", "issue": "[FEAT] Support sklearn 0.23.2\nCurrently we only support sklearn versions >= 1.0. We need to try to support the 0.23.2 as it is widely used by many environments and frameworks.\n", "before_files": [{"content": "# ----------------------------------------------------------------------------\n# Copyright (C) 2021-2022 Deepchecks (https://www.deepchecks.com)\n#\n# This file is part of Deepchecks.\n# Deepchecks is distributed under the terms of the GNU Affero General\n# Public License (version 3 or later).\n# You should have received a copy of the GNU Affero General Public License\n# along with Deepchecks.  If not, see <http://www.gnu.org/licenses/>.\n# ----------------------------------------------------------------------------\n#\n\"\"\"Module containing common WholeDatasetDriftCheck (domain classifier drift) utils.\"\"\"\n\nfrom typing import List\nimport warnings\n\nimport numpy as np\nimport pandas as pd\nfrom plotly.subplots import make_subplots\n\nfrom sklearn.pipeline import Pipeline\nfrom sklearn.compose import ColumnTransformer\n\nwith warnings.catch_warnings():\n    warnings.simplefilter('ignore')\n    from sklearn.experimental import enable_hist_gradient_boosting  # noqa # pylint: disable=unused-import\n\nfrom sklearn.ensemble import HistGradientBoostingClassifier\nfrom sklearn.metrics import roc_auc_score\nfrom sklearn.preprocessing import OrdinalEncoder\nfrom sklearn.model_selection import train_test_split\nimport plotly.graph_objects as go\n\nfrom deepchecks.tabular import Dataset\nfrom deepchecks.utils.distribution.plot import feature_distribution_traces, drift_score_bar_traces\nfrom deepchecks.utils.distribution.rare_category_encoder import RareCategoryEncoder\nfrom deepchecks.utils.features import N_TOP_MESSAGE, calculate_feature_importance_or_none\nfrom deepchecks.utils.function import run_available_kwargs\nfrom deepchecks.utils.strings import format_percent\nfrom deepchecks.utils.typing import Hashable\n\n\ndef run_whole_dataset_drift(train_dataframe: pd.DataFrame, test_dataframe: pd.DataFrame,\n                            numerical_features: List[Hashable], cat_features: List[Hashable], sample_size: int,\n                            random_state: int, test_size: float, n_top_columns: int, min_feature_importance: float,\n                            max_num_categories_for_display: int, show_categories_by: str,\n                            min_meaningful_drift_score: float):\n    \"\"\"Calculate whole dataset drift.\"\"\"\n    domain_classifier = generate_model(numerical_features, cat_features, random_state)\n\n    train_sample_df = train_dataframe.sample(sample_size, random_state=random_state)\n    test_sample_df = test_dataframe.sample(sample_size, random_state=random_state)\n\n    # create new dataset, with label denoting whether sample belongs to test dataset\n    domain_class_df = pd.concat([train_sample_df, test_sample_df])\n    domain_class_labels = pd.Series([0] * len(train_sample_df) + [1] * len(test_sample_df))\n\n    x_train, x_test, y_train, y_test = train_test_split(domain_class_df, domain_class_labels,\n                                                        stratify=domain_class_labels,\n                                                        random_state=random_state,\n                                                        test_size=test_size)\n\n    domain_classifier = domain_classifier.fit(x_train, y_train)\n\n    y_test.name = 'belongs_to_test'\n    domain_test_dataset = Dataset(pd.concat([x_test.reset_index(drop=True), y_test.reset_index(drop=True)], axis=1),\n                                  cat_features=cat_features, label='belongs_to_test')\n\n    # calculate feature importance of domain_classifier, containing the information which features separate\n    # the dataset best.\n    fi, importance_type = calculate_feature_importance_or_none(\n        domain_classifier,\n        domain_test_dataset,\n        force_permutation=True,\n        permutation_kwargs={'n_repeats': 10, 'random_state': random_state, 'timeout': 120}\n    )\n\n    fi = fi.sort_values(ascending=False) if fi is not None else None\n\n    domain_classifier_auc = roc_auc_score(y_test, domain_classifier.predict_proba(x_test)[:, 1])\n    drift_score = auc_to_drift_score(domain_classifier_auc)\n\n    values_dict = {\n        'domain_classifier_auc': domain_classifier_auc,\n        'domain_classifier_drift_score': drift_score,\n        'domain_classifier_feature_importance': fi.to_dict() if fi is not None else {},\n    }\n\n    feature_importance_note = f\"\"\"\n    <span>\n    The percents of explained dataset difference are the importance values for the feature calculated\n    using `{importance_type}`.\n    </span><br><br>\n    \"\"\"\n\n    if fi is not None and drift_score > min_meaningful_drift_score:\n        top_fi = fi.head(n_top_columns)\n        top_fi = top_fi.loc[top_fi > min_feature_importance]\n    else:\n        top_fi = None\n\n    if top_fi is not None and len(top_fi):\n        score = values_dict['domain_classifier_drift_score']\n\n        displays = [feature_importance_note, build_drift_plot(score),\n                    '<h3>Main features contributing to drift</h3>',\n                    N_TOP_MESSAGE % n_top_columns]\n        displays += [display_dist(train_sample_df[feature], test_sample_df[feature], top_fi, cat_features,\n                                  max_num_categories_for_display, show_categories_by)\n                     for feature in top_fi.index]\n    else:\n        displays = None\n\n    return values_dict, displays\n\n\ndef generate_model(numerical_columns: List[Hashable], categorical_columns: List[Hashable],\n                   random_state: int = 42) -> Pipeline:\n    \"\"\"Generate the unfitted Domain Classifier model.\"\"\"\n    categorical_transformer = Pipeline(\n        steps=[('rare', RareCategoryEncoder(254)),\n               ('encoder', run_available_kwargs(OrdinalEncoder, handle_unknown='use_encoded_value',\n                                                unknown_value=np.nan,\n                                                dtype=np.float64))]\n    )\n\n    preprocessor = ColumnTransformer(\n        transformers=[\n            ('num', 'passthrough', numerical_columns),\n            ('cat', categorical_transformer, categorical_columns),\n        ]\n    )\n\n    return Pipeline(\n        steps=[('preprocessing', preprocessor),\n               ('model', HistGradientBoostingClassifier(\n                   max_depth=2, max_iter=10, random_state=random_state,\n                   categorical_features=[False] * len(numerical_columns) + [True] * len(categorical_columns)\n               ))])\n\n\ndef auc_to_drift_score(auc: float) -> float:\n    \"\"\"Calculate the drift score, which is 2*auc - 1, with auc being the auc of the Domain Classifier.\n\n    Parameters\n    ----------\n    auc : float\n        auc of the Domain Classifier\n    \"\"\"\n    return max(2 * auc - 1, 0)\n\n\ndef build_drift_plot(score):\n    \"\"\"Build traffic light drift plot.\"\"\"\n    bar_traces, x_axis, y_axis = drift_score_bar_traces(score)\n    x_axis['title'] = 'Drift score'\n    drift_plot = go.Figure(layout=dict(\n        title='Drift Score - Whole Dataset Total',\n        xaxis=x_axis,\n        yaxis=y_axis,\n        width=700,\n        height=200\n\n    ))\n\n    drift_plot.add_traces(bar_traces)\n    return drift_plot\n\n\ndef display_dist(train_column: pd.Series, test_column: pd.Series, fi_ser: pd.Series, cat_features,\n                 max_num_categories, show_categories_by):\n    \"\"\"Display a distribution comparison plot for the given columns.\"\"\"\n    column_name = train_column.name\n\n    title = f'Feature: {column_name} - Explains {format_percent(fi_ser.loc[column_name])} of dataset difference'\n    dist_traces, xaxis_layout, yaxis_layout = \\\n        feature_distribution_traces(train_column.dropna(),\n                                    test_column.dropna(),\n                                    column_name,\n                                    is_categorical=column_name in cat_features,\n                                    max_num_categories=max_num_categories,\n                                    show_categories_by=show_categories_by)\n\n    all_categories = list(set(train_column).union(set(test_column)))\n    add_footnote = column_name in cat_features and len(all_categories) > max_num_categories\n\n    if add_footnote:\n        fig = make_subplots(rows=2, cols=1, vertical_spacing=0.6, shared_yaxes=False, shared_xaxes=False,\n                            row_heights=[0.8, 0.2],\n                            subplot_titles=[title])\n\n        fig.add_traces(dist_traces)\n\n        param_to_print_dict = {\n            'train_largest': 'largest categories (by train)',\n            'test_largest': 'largest categories (by test)',\n            'largest_difference': 'largest difference between categories'\n        }\n        train_data_percents = dist_traces[0].y.sum()\n        test_data_percents = dist_traces[1].y.sum()\n\n        fig.add_annotation(\n            x=0, y=-0.2, showarrow=False, xref='paper', yref='paper', xanchor='left',\n            text=f'* Showing the top {max_num_categories} {param_to_print_dict[show_categories_by]} out of '\n                 f'total {len(all_categories)} categories.'\n                 f'<br>Shown data is {format_percent(train_data_percents)} of train data and '\n                 f'{format_percent(test_data_percents)} of test data.'\n        )\n\n    else:\n        fig = go.Figure()\n        fig.add_traces(dist_traces)\n\n    layout = go.Layout(\n        title=title,\n        xaxis=xaxis_layout,\n        yaxis=yaxis_layout,\n        legend=dict(\n            title='Dataset',\n            yanchor='top',\n            y=0.9,\n            xanchor='left'),\n        width=700,\n        height=300\n    )\n\n    fig.update_layout(layout)\n\n    return fig\n", "path": "deepchecks/core/check_utils/whole_dataset_drift_utils.py"}], "after_files": [{"content": "# ----------------------------------------------------------------------------\n# Copyright (C) 2021-2022 Deepchecks (https://www.deepchecks.com)\n#\n# This file is part of Deepchecks.\n# Deepchecks is distributed under the terms of the GNU Affero General\n# Public License (version 3 or later).\n# You should have received a copy of the GNU Affero General Public License\n# along with Deepchecks.  If not, see <http://www.gnu.org/licenses/>.\n# ----------------------------------------------------------------------------\n#\n\"\"\"Module containing common WholeDatasetDriftCheck (domain classifier drift) utils.\"\"\"\n\nfrom typing import List\nimport warnings\n\nimport numpy as np\nimport pandas as pd\nfrom plotly.subplots import make_subplots\n\nfrom sklearn.pipeline import Pipeline\nfrom sklearn.compose import ColumnTransformer\n\nwith warnings.catch_warnings():\n    warnings.simplefilter('ignore')\n    from sklearn.experimental import enable_hist_gradient_boosting  # noqa # pylint: disable=unused-import\n\nfrom sklearn.ensemble import HistGradientBoostingClassifier\nfrom sklearn.metrics import roc_auc_score\nfrom sklearn.preprocessing import OrdinalEncoder\nfrom sklearn.model_selection import train_test_split\nimport plotly.graph_objects as go\n\nfrom deepchecks.tabular import Dataset\nfrom deepchecks.utils.distribution.plot import feature_distribution_traces, drift_score_bar_traces\nfrom deepchecks.utils.distribution.rare_category_encoder import RareCategoryEncoder\nfrom deepchecks.utils.features import N_TOP_MESSAGE, calculate_feature_importance_or_none\nfrom deepchecks.utils.function import run_available_kwargs\nfrom deepchecks.utils.strings import format_percent\nfrom deepchecks.utils.typing import Hashable\n\n\ndef run_whole_dataset_drift(train_dataframe: pd.DataFrame, test_dataframe: pd.DataFrame,\n                            numerical_features: List[Hashable], cat_features: List[Hashable], sample_size: int,\n                            random_state: int, test_size: float, n_top_columns: int, min_feature_importance: float,\n                            max_num_categories_for_display: int, show_categories_by: str,\n                            min_meaningful_drift_score: float):\n    \"\"\"Calculate whole dataset drift.\"\"\"\n    domain_classifier = generate_model(numerical_features, cat_features, random_state)\n\n    train_sample_df = train_dataframe.sample(sample_size, random_state=random_state)\n    test_sample_df = test_dataframe.sample(sample_size, random_state=random_state)\n\n    # create new dataset, with label denoting whether sample belongs to test dataset\n    domain_class_df = pd.concat([train_sample_df, test_sample_df])\n    domain_class_labels = pd.Series([0] * len(train_sample_df) + [1] * len(test_sample_df))\n\n    x_train, x_test, y_train, y_test = train_test_split(domain_class_df, domain_class_labels,\n                                                        stratify=domain_class_labels,\n                                                        random_state=random_state,\n                                                        test_size=test_size)\n\n    domain_classifier = domain_classifier.fit(x_train, y_train)\n\n    y_test.name = 'belongs_to_test'\n    domain_test_dataset = Dataset(pd.concat([x_test.reset_index(drop=True), y_test.reset_index(drop=True)], axis=1),\n                                  cat_features=cat_features, label='belongs_to_test')\n\n    # calculate feature importance of domain_classifier, containing the information which features separate\n    # the dataset best.\n    fi, importance_type = calculate_feature_importance_or_none(\n        domain_classifier,\n        domain_test_dataset,\n        force_permutation=True,\n        permutation_kwargs={'n_repeats': 10, 'random_state': random_state, 'timeout': 120}\n    )\n\n    fi = fi.sort_values(ascending=False) if fi is not None else None\n\n    domain_classifier_auc = roc_auc_score(y_test, domain_classifier.predict_proba(x_test)[:, 1])\n    drift_score = auc_to_drift_score(domain_classifier_auc)\n\n    values_dict = {\n        'domain_classifier_auc': domain_classifier_auc,\n        'domain_classifier_drift_score': drift_score,\n        'domain_classifier_feature_importance': fi.to_dict() if fi is not None else {},\n    }\n\n    feature_importance_note = f\"\"\"\n    <span>\n    The percents of explained dataset difference are the importance values for the feature calculated\n    using `{importance_type}`.\n    </span><br><br>\n    \"\"\"\n\n    if fi is not None and drift_score > min_meaningful_drift_score:\n        top_fi = fi.head(n_top_columns)\n        top_fi = top_fi.loc[top_fi > min_feature_importance]\n    else:\n        top_fi = None\n\n    if top_fi is not None and len(top_fi):\n        score = values_dict['domain_classifier_drift_score']\n\n        displays = [feature_importance_note, build_drift_plot(score),\n                    '<h3>Main features contributing to drift</h3>',\n                    N_TOP_MESSAGE % n_top_columns]\n        displays += [display_dist(train_sample_df[feature], test_sample_df[feature], top_fi, cat_features,\n                                  max_num_categories_for_display, show_categories_by)\n                     for feature in top_fi.index]\n    else:\n        displays = None\n\n    return values_dict, displays\n\n\ndef generate_model(numerical_columns: List[Hashable], categorical_columns: List[Hashable],\n                   random_state: int = 42) -> Pipeline:\n    \"\"\"Generate the unfitted Domain Classifier model.\"\"\"\n    categorical_transformer = Pipeline(\n        steps=[('rare', RareCategoryEncoder(254)),\n               ('encoder', run_available_kwargs(OrdinalEncoder, handle_unknown='use_encoded_value',\n                                                unknown_value=np.nan,\n                                                dtype=np.float64))]\n    )\n\n    preprocessor = ColumnTransformer(\n        transformers=[\n            ('num', 'passthrough', numerical_columns),\n            ('cat', categorical_transformer, categorical_columns),\n        ]\n    )\n\n    return Pipeline(\n        steps=[('preprocessing', preprocessor),\n               ('model', run_available_kwargs(HistGradientBoostingClassifier,\n                                              max_depth=2, max_iter=10, random_state=random_state,\n                                              categorical_features=[False] * len(numerical_columns)\n                                              + [True] * len(categorical_columns)\n                                              ))])\n\n\ndef auc_to_drift_score(auc: float) -> float:\n    \"\"\"Calculate the drift score, which is 2*auc - 1, with auc being the auc of the Domain Classifier.\n\n    Parameters\n    ----------\n    auc : float\n        auc of the Domain Classifier\n    \"\"\"\n    return max(2 * auc - 1, 0)\n\n\ndef build_drift_plot(score):\n    \"\"\"Build traffic light drift plot.\"\"\"\n    bar_traces, x_axis, y_axis = drift_score_bar_traces(score)\n    x_axis['title'] = 'Drift score'\n    drift_plot = go.Figure(layout=dict(\n        title='Drift Score - Whole Dataset Total',\n        xaxis=x_axis,\n        yaxis=y_axis,\n        width=700,\n        height=200\n\n    ))\n\n    drift_plot.add_traces(bar_traces)\n    return drift_plot\n\n\ndef display_dist(train_column: pd.Series, test_column: pd.Series, fi_ser: pd.Series, cat_features,\n                 max_num_categories, show_categories_by):\n    \"\"\"Display a distribution comparison plot for the given columns.\"\"\"\n    column_name = train_column.name\n\n    title = f'Feature: {column_name} - Explains {format_percent(fi_ser.loc[column_name])} of dataset difference'\n    dist_traces, xaxis_layout, yaxis_layout = \\\n        feature_distribution_traces(train_column.dropna(),\n                                    test_column.dropna(),\n                                    column_name,\n                                    is_categorical=column_name in cat_features,\n                                    max_num_categories=max_num_categories,\n                                    show_categories_by=show_categories_by)\n\n    all_categories = list(set(train_column).union(set(test_column)))\n    add_footnote = column_name in cat_features and len(all_categories) > max_num_categories\n\n    if add_footnote:\n        fig = make_subplots(rows=2, cols=1, vertical_spacing=0.6, shared_yaxes=False, shared_xaxes=False,\n                            row_heights=[0.8, 0.2],\n                            subplot_titles=[title])\n\n        fig.add_traces(dist_traces)\n\n        param_to_print_dict = {\n            'train_largest': 'largest categories (by train)',\n            'test_largest': 'largest categories (by test)',\n            'largest_difference': 'largest difference between categories'\n        }\n        train_data_percents = dist_traces[0].y.sum()\n        test_data_percents = dist_traces[1].y.sum()\n\n        fig.add_annotation(\n            x=0, y=-0.2, showarrow=False, xref='paper', yref='paper', xanchor='left',\n            text=f'* Showing the top {max_num_categories} {param_to_print_dict[show_categories_by]} out of '\n                 f'total {len(all_categories)} categories.'\n                 f'<br>Shown data is {format_percent(train_data_percents)} of train data and '\n                 f'{format_percent(test_data_percents)} of test data.'\n        )\n\n    else:\n        fig = go.Figure()\n        fig.add_traces(dist_traces)\n\n    layout = go.Layout(\n        title=title,\n        xaxis=xaxis_layout,\n        yaxis=yaxis_layout,\n        legend=dict(\n            title='Dataset',\n            yanchor='top',\n            y=0.9,\n            xanchor='left'),\n        width=700,\n        height=300\n    )\n\n    fig.update_layout(layout)\n\n    return fig\n", "path": "deepchecks/core/check_utils/whole_dataset_drift_utils.py"}]}