Repository: alteryx/evalml (python)
Issue: Partial Dependency Fails when feature has nans
I would like to generate a Partial Dependency for 'log_tel'. However, log_tel has nans:
`df['log_tel'].isnull().sum()`
`205`

I am getting the following Partial Dependency result:
![image](https://user-images.githubusercontent.com/16852533/95611526-f3812580-0a2f-11eb-8800-4035b8fd8303.png)

Next, I filled the nans with zero and verified the result:
`df['log_tel'] = df['log_tel'].fillna(0)`
`df['log_tel'].isnull().sum()`
`0`

Now, the Partial Dependency works properly:
![image](https://user-images.githubusercontent.com/16852533/95611753-46f37380-0a30-11eb-86dc-23444d87e7d9.png)
Pull request description: Warning on null values for partial_dependency
fix #1285 

Warns user when there are null values in the features of interest. 

Patch:
diff --git a/docs/source/release_notes.rst b/docs/source/release_notes.rst
index 97209e7f..bdd6d853 100644
--- a/docs/source/release_notes.rst
+++ b/docs/source/release_notes.rst
@@ -29,6 +29,7 @@ Release Notes
         * Removed Graphviz from test-requirements to add to requirements.txt :pr:`1327`
         * Removed ``max_pipelines`` parameter from ``AutoMLSearch`` :pr:`1264`
         * Include editable installs in all install make targets :pr:`1335`
+        * Added warning for ``partial_dependency`` when the feature includes null values :pr:`1352`
     * Documentation Changes
         * Fixed and updated code blocks in Release Notes :pr:`1243`
         * Added DecisionTree estimators to API Reference :pr:`1246`
diff --git a/evalml/exceptions/__init__.py b/evalml/exceptions/__init__.py
index 0427d1ab..72634b92 100644
--- a/evalml/exceptions/__init__.py
+++ b/evalml/exceptions/__init__.py
@@ -10,5 +10,6 @@ from .exceptions import (
     AutoMLSearchException,
     PipelineScoreError,
     DataCheckInitError,
-    EnsembleMissingPipelinesError
+    EnsembleMissingPipelinesError,
+    NullsInColumnWarning
 )
diff --git a/evalml/exceptions/exceptions.py b/evalml/exceptions/exceptions.py
index 7b171f2f..65c43ca2 100644
--- a/evalml/exceptions/exceptions.py
+++ b/evalml/exceptions/exceptions.py
@@ -70,3 +70,7 @@ class PipelineScoreError(Exception):
 
 class DataCheckInitError(Exception):
     """Exception raised when a data check can't initialize with the parameters given."""
+
+
+class NullsInColumnWarning(UserWarning):
+    """Warning thrown when there are null values in the column of interest"""
diff --git a/evalml/model_understanding/graphs.py b/evalml/model_understanding/graphs.py
index 9792ed17..c16165b6 100644
--- a/evalml/model_understanding/graphs.py
+++ b/evalml/model_understanding/graphs.py
@@ -15,6 +15,7 @@ from sklearn.preprocessing import LabelBinarizer
 from sklearn.utils.multiclass import unique_labels
 
 import evalml
+from evalml.exceptions import NullsInColumnWarning
 from evalml.model_family import ModelFamily
 from evalml.objectives.utils import get_objective
 from evalml.problem_types import ProblemTypes
@@ -436,6 +437,8 @@ def partial_dependence(pipeline, X, feature, grid_resolution=100):
     elif isinstance(pipeline, evalml.pipelines.RegressionPipeline):
         pipeline._estimator_type = "regressor"
     pipeline.feature_importances_ = pipeline.feature_importance
+    if ((isinstance(feature, int) and X.iloc[:, feature].isnull().sum()) or (isinstance(feature, str) and X[feature].isnull().sum())):
+        warnings.warn("There are null values in the features, which will cause NaN values in the partial dependence output. Fill in these values to remove the NaN values.", NullsInColumnWarning)
     try:
         avg_pred, values = sk_partial_dependence(pipeline, X=X, features=[feature], grid_resolution=grid_resolution)
     finally:


Test patch:
diff --git a/evalml/tests/model_understanding_tests/test_graphs.py b/evalml/tests/model_understanding_tests/test_graphs.py
index 3e21440d..0e42fe89 100644
--- a/evalml/tests/model_understanding_tests/test_graphs.py
+++ b/evalml/tests/model_understanding_tests/test_graphs.py
@@ -9,6 +9,7 @@ from sklearn.preprocessing import label_binarize
 from skopt.space import Real
 
 from evalml.demos import load_breast_cancer
+from evalml.exceptions import NullsInColumnWarning
 from evalml.model_family import ModelFamily
 from evalml.model_understanding.graphs import (
     binary_objective_vs_threshold,
@@ -816,6 +817,18 @@ def test_partial_dependence_not_fitted(X_y_binary, logistic_regression_binary_pi
         partial_dependence(pipeline, X, feature=0, grid_resolution=20)
 
 
+def test_partial_dependence_warning(logistic_regression_binary_pipeline_class):
+    X = pd.DataFrame({'a': [2, None, 2, 2], 'b': [1, 2, 2, 1]})
+    y = pd.Series([0, 1, 0, 1])
+    pipeline = logistic_regression_binary_pipeline_class(parameters={})
+    pipeline.fit(X, y)
+    with pytest.warns(NullsInColumnWarning, match="There are null values in the features, which will cause NaN values in the partial dependence output"):
+        partial_dependence(pipeline, X, feature=0, grid_resolution=20)
+
+    with pytest.warns(NullsInColumnWarning, match="There are null values in the features, which will cause NaN values in the partial dependence output"):
+        partial_dependence(pipeline, X, feature='a', grid_resolution=20)
+
+
 def test_graph_partial_dependence(test_pipeline):
     X, y = load_breast_cancer()