Repository: deepchecks/deepchecks

Issue:
[FEAT] Add recommendation for explicitly defining categorical features in Dataset when displaying warning about features that were inferred automatically
**Is your feature request related to a problem? Please describe.**
When categorical features are automatically inferred, error message does not stat clearly (and recommend) to (and how) explicitly define them as categorical.

**Describe the solution you'd like**
add to the warning message displayed that it is recommended to explicitly define the list of categorical features, using the cat_features parameter during Dataset creation. Following is the method that implements this: https://github.com/deepchecks/deepchecks/blob/27a18f501df5e535940cdf61e58fd730725ae778/deepchecks/tabular/dataset.py#L538


Discussion:

Resolving patch:
diff --git a/deepchecks/tabular/dataset.py b/deepchecks/tabular/dataset.py
--- a/deepchecks/tabular/dataset.py
+++ b/deepchecks/tabular/dataset.py
@@ -566,21 +566,18 @@ def _infer_categorical_features(
             columns=columns
         )
 
+        message = ('It is recommended to initialize Dataset with categorical features by doing '
+                   '"Dataset(df, cat_features=categorical_list)". No categorical features were passed, therefore '
+                   'heuristically inferring categorical features in the data.\n'
+                   f'{len(categorical_columns)} categorical features were inferred')
+
         if len(categorical_columns) > 0:
-            columns = list(map(str, categorical_columns))[:7]
-            stringified_columns = ", ".join(columns)
-            if len(categorical_columns) < 7:
-                logger.warning(
-                    'Automatically inferred these columns as categorical features: %s. \n',
-                    stringified_columns
-                )
-            else:
-                logger.warning(
-                    'Some columns have been inferred as categorical features: '
-                    '%s. \n and more... \n For the full list '
-                    'of columns, use dataset.cat_features',
-                    stringified_columns
-                )
+            columns_to_print = categorical_columns[:7]
+            message += ': ' + ', '.join(list(map(str, columns_to_print)))
+            if len(categorical_columns) > len(columns_to_print):
+                message += '... For full list use dataset.cat_features'
+
+        logger.warning(message)
 
         return categorical_columns
 


Test patch:
diff --git a/tests/base/dataset_test.py b/tests/base/dataset_test.py
--- a/tests/base/dataset_test.py
+++ b/tests/base/dataset_test.py
@@ -9,10 +9,12 @@
 # ----------------------------------------------------------------------------
 #
 """Contains unit tests for the Dataset class."""
+import logging
 import typing as t
 
 import numpy as np
 import pandas as pd
+import pytest
 from sklearn.datasets import load_iris
 from sklearn.datasets import make_classification
 from hamcrest import (
@@ -20,9 +22,10 @@
     calling, raises, not_none, has_property, all_of, contains_exactly, has_item, has_length
 )
 
-from deepchecks.tabular.dataset import Dataset
+from deepchecks.tabular.dataset import Dataset, logger as ds_logger
 from deepchecks.tabular.utils.validation import ensure_dataframe_type
-from deepchecks.core.errors import DeepchecksValueError, DatasetValidationError
+from deepchecks.core.errors import DeepchecksValueError
+
 
 
 def assert_dataset(dataset: Dataset, args):
@@ -1035,4 +1038,22 @@ def random_classification_dataframe(n_samples=100, n_features=5) -> pd.DataFrame
     x, y, *_ = make_classification(n_samples=n_samples, n_features=n_features)
     df = pd.DataFrame(x,columns=[f'X{i}'for i in range(n_features)])
     df['target'] = y
-    return df
\ No newline at end of file
+    return df
+
+
+def test_cat_features_warning(iris, caplog):
+    # Test that warning is raised when cat_features is None
+    with caplog.at_level(logging.WARNING):
+        Dataset(iris)
+    assert_that(caplog.records, has_item(has_property('message',
+                    "It is recommended to initialize Dataset with categorical features by doing "
+                    "\"Dataset(df, cat_features=categorical_list)\". No categorical features were "
+                    "passed, therefore heuristically inferring categorical features in the data.\n"
+                    "0 categorical features were inferred")
+    ))
+
+    # Test that warning is not raised when cat_features is not None
+    caplog.clear()
+    with caplog.at_level(logging.WARNING):
+        Dataset(iris, cat_features=[])
+    assert_that(caplog.records, has_length(0))