Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyod/models/gmm.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ def decision_function(self, X):
The anomaly score of the input samples.
"""
check_is_fitted(self, ["decision_scores_", "threshold_", "labels_"])
X = check_array(X)

# Invert outlier scores. Outliers come with higher outlier scores
return invert_order(self.detector_.score_samples(X))
Expand Down
1 change: 1 addition & 0 deletions pyod/models/iforest.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ def decision_function(self, X):
The anomaly score of the input samples.
"""
check_is_fitted(self, ['decision_scores_', 'threshold_', 'labels_'])
X = check_array(X)
# invert outlier scores. Outliers comes with higher outlier scores
return invert_order(self.detector_.decision_function(X))

Expand Down
1 change: 1 addition & 0 deletions pyod/models/lof.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ def decision_function(self, X):

check_is_fitted(self, ['decision_scores_', 'threshold_', 'labels_'])

X = check_array(X, accept_sparse=True)
# Invert outlier scores. Outliers comes with higher outlier scores
# noinspection PyProtectedMember
try:
Expand Down
1 change: 1 addition & 0 deletions pyod/models/ocsvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ def decision_function(self, X):
The anomaly score of the input samples.
"""
check_is_fitted(self, ['decision_scores_', 'threshold_', 'labels_'])
X = check_array(X)
# Invert outlier scores. Outliers comes with higher outlier scores
return invert_order(self.detector_.decision_function(X))

Expand Down
23 changes: 23 additions & 0 deletions pyod/test/test_iforest.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,29 @@ def test_feature_importances(self):
feature_importances = self.clf.feature_importances_
assert (len(feature_importances) == 2)

def test_dataframe_no_feature_name_warning(self):
"""Regression test for GitHub issue #540.

When a pandas DataFrame is passed to fit/predict, no warning about
feature names should be raised by the underlying sklearn estimator.
"""
import pytest
import warnings

pd = pytest.importorskip("pandas")

df_train = pd.DataFrame(self.X_train, columns=['f1', 'f2'])
df_test = pd.DataFrame(self.X_test, columns=['f1', 'f2'])

clf = IForest(contamination=self.contamination, random_state=42)
clf.fit(df_train)

with warnings.catch_warnings():
warnings.simplefilter("error", UserWarning)
clf.decision_function(df_test)
clf.predict(df_test)
clf.predict_proba(df_test)

def tearDown(self):
pass

Expand Down
11 changes: 11 additions & 0 deletions pyod/test/test_lof.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from numpy.testing import assert_array_less
from numpy.testing import assert_equal
from numpy.testing import assert_raises
from scipy.sparse import csr_matrix
from scipy.stats import rankdata
from sklearn.base import clone
from sklearn.metrics import roc_auc_score
Expand Down Expand Up @@ -61,6 +62,16 @@ def test_prediction_scores(self):
# check performance
assert (roc_auc_score(self.y_test, pred_scores) >= self.roc_floor)

def test_sparse_prediction_scores(self):
sparse_train = csr_matrix(self.X_train)
sparse_test = csr_matrix(self.X_test)
clf = LOF(contamination=self.contamination)
clf.fit(sparse_train)

pred_scores = clf.decision_function(sparse_test)

assert_equal(pred_scores.shape[0], self.X_test.shape[0])

def test_prediction_labels(self):
pred_labels = self.clf.predict(self.X_test)
assert_equal(pred_labels.shape, self.y_test.shape)
Expand Down