UserWarning:一个或多个测试分数是非有限的 - GridSearchCV for MultiOutputClassifier(MLPClassifier)
UserWarning: One or more of the test scores are non-finite – GridSearchCV for MultiOutputClassifier(MLPClassifier)
我第一次尝试 scikit-learn,解决 Multi-Output Multi-Class text classification 问题。为此,我正在尝试使用 GridSearchCV
来优化 MLPClassifier
的参数。
下面是我目前的代码:
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.multioutput import MultiOutputClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score
df = pd.read_csv('data.csv')
df.fillna('', inplace=True) #Replaces NaNs with "" in the DataFrame (which would be considered a viable choice in this multi-classification model)
x_features = df['input_text']
y_labels = df[['output_text_label_1', 'output_text_label_2']]
x_train, x_test, y_train, y_test = train_test_split(x_features, y_labels, test_size=0.3, random_state=7)
当我尝试在没有任何参数优化的情况下为 MultiOutputClassifier(MLPClassifier())
设置 Pipeline
时,pipe.score
给出了 ~0.837 的分数,这似乎表明上面的代码正在做某物。 运行 pipe.predict()
在某些测试字符串上似乎产生了相对足够的输出结果。
pipe = Pipeline(steps=[('cv', CountVectorizer()),
('mlpc', MultiOutputClassifier(MLPClassifier()))])
pipe.fit(x_train, y_train)
pipe.score(x_test, y_test)
但是,当尝试使用下面的另一个 的起始代码单独使用 GridSearchCV
时,我 运行 遇到了问题:
mlpc = MLPClassifier(solver='adam',
learning_rate_init=0.01,
max_iter=300,
activation='relu',
early_stopping=True)
pipe = Pipeline(steps=[('cv', CountVectorizer(ngram_range=(1, 1))),
('scale', StandardScaler(with_mean=False)),
('mlpc', MultiOutputClassifier(mlpc))])
search_space = {
'cv__max_df': (0.9, 0.95, 0.99),
'cv__min_df': (0.01, 0.05, 0.1),
'mlpc__estimator__alpha': 10.0 ** -np.arange(1, 5),
'mlpc__estimator__hidden_layer_sizes': ((64, 32), (128, 64),
(64, 32, 16), (128, 64, 32)),
'mlpc__estimator__tol': (1e-3, 5e-3, 1e-4),
}
grid_search = GridSearchCV(pipe, search_space, scoring='accuracy', error_score='raise', n_jobs=-1)
grid_search.fit(x_train, y_train)
这个警告似乎与评分问题有关,UserWarning: One or more of the test scores are non-finite
:
UserWarning: One or more of the test scores are non-finite: [nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan]
warnings.warn(
x_train
、x_test
、y_train
、y_test
的.shape
是(3036,)
(1302,)
(3036, 2)
(1302, 2)
分别。内容都是字符串,在上面的代码中可以看到,我已经将多次出现的NaN替换为空字符串""
,这对于模型来说应该是一个可行的选择(基本上有它select None 作为 class):
df.fillna('', inplace=True) #Replaces NaNs with "" in the DataFrame (which would be considered a viable choice in this multi-classification model)
我在 GridSearchCV
中尝试了其他 scoring=
方法:roc_auc_ovr
和 f1_macro
,但问题基本相同。
如果我在 GridSearchCV
中包含以下选项:error_score='raise'
,我会收到错误消息:ValueError: multiclass-multioutput is not supported
.
ValueError Traceback (most recent call last)
<ipython-input-10-14bccd802d09> in <module>
21 #
22
---> 23 grid_search.fit(x_train, y_train)
~/condaenv/lib/python3.9/site-packages/sklearn/model_selection/_search.py in fit(self, X, y, groups, **fit_params)
889 return results
890
--> 891 self._run_search(evaluate_candidates)
892
893 # multimetric is determined here because in the case of a callable
~/condaenv/lib/python3.9/site-packages/sklearn/model_selection/_search.py in _run_search(self, evaluate_candidates)
1390 def _run_search(self, evaluate_candidates):
1391 """Search all candidates in param_grid"""
-> 1392 evaluate_candidates(ParameterGrid(self.param_grid))
1393
1394
~/condaenv/lib/python3.9/site-packages/sklearn/model_selection/_search.py in evaluate_candidates(candidate_params, cv, more_results)
836 )
837
--> 838 out = parallel(
839 delayed(_fit_and_score)(
840 clone(base_estimator),
~/condaenv/lib/python3.9/site-packages/joblib/parallel.py in __call__(self, iterable)
1059
1060 with self._backend.retrieval_context():
-> 1061 self.retrieve()
1062 # Make sure that we get a last message telling us we are done
1063 elapsed_time = time.time() - self._start_time
~/condaenv/lib/python3.9/site-packages/joblib/parallel.py in retrieve(self)
938 try:
939 if getattr(self._backend, 'supports_timeout', False):
--> 940 self._output.extend(job.get(timeout=self.timeout))
941 else:
942 self._output.extend(job.get())
~/condaenv/lib/python3.9/site-packages/joblib/_parallel_backends.py in wrap_future_result(future, timeout)
540 AsyncResults.get from multiprocessing."""
541 try:
--> 542 return future.result(timeout=timeout)
543 except CfTimeoutError as e:
544 raise TimeoutError from e
~/condaenv/lib/python3.9/concurrent/futures/_base.py in result(self, timeout)
444 raise CancelledError()
445 elif self._state == FINISHED:
--> 446 return self.__get_result()
447 else:
448 raise TimeoutError()
~/condaenv/lib/python3.9/concurrent/futures/_base.py in __get_result(self)
389 if self._exception:
390 try:
--> 391 raise self._exception
392 finally:
393 # Break a reference cycle with the exception in self._exception
ValueError: multiclass-multioutput is not supported
在四处寻找解决方案时,我发现了 ,这表明 CountVectorizer
需要一维输入。我的 .shape
中有两个功能用于多输出。我不知道这个答案是否正确,因为我是第一次评估 scikit-learn。答案建议使用 ColumnTransformer
来解决这个问题,但我需要一个代码示例来理解如果这确实是问题。
您的 y
有多个列,而不是您的 X
,因此 CountVectorizer
不是问题所在。相反,问题在于您有两个目标,每个目标都有两种以上的可能结果。来自同一页面的the User Guide, MLPClassifier
supports multilabel, but not multi-output multiclass. Later,关于评分的额外警告:
Warning: At present, no metric in sklearn.metrics
supports the multiclass-multioutput classification task.
所以即使您将分类器包装在例如MultiOutputClassifier
网格搜索的评分将失败。我认为您应该能够定义一个自定义记分器来完成这项工作?您可能还会考虑您的标签是否真正正确排序为 label_1 和 label_2,或者这是否可以转换为多标签问题,将目标二值化?
我第一次尝试 scikit-learn,解决 Multi-Output Multi-Class text classification 问题。为此,我正在尝试使用 GridSearchCV
来优化 MLPClassifier
的参数。
下面是我目前的代码:
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.multioutput import MultiOutputClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score
df = pd.read_csv('data.csv')
df.fillna('', inplace=True) #Replaces NaNs with "" in the DataFrame (which would be considered a viable choice in this multi-classification model)
x_features = df['input_text']
y_labels = df[['output_text_label_1', 'output_text_label_2']]
x_train, x_test, y_train, y_test = train_test_split(x_features, y_labels, test_size=0.3, random_state=7)
当我尝试在没有任何参数优化的情况下为 MultiOutputClassifier(MLPClassifier())
设置 Pipeline
时,pipe.score
给出了 ~0.837 的分数,这似乎表明上面的代码正在做某物。 运行 pipe.predict()
在某些测试字符串上似乎产生了相对足够的输出结果。
pipe = Pipeline(steps=[('cv', CountVectorizer()),
('mlpc', MultiOutputClassifier(MLPClassifier()))])
pipe.fit(x_train, y_train)
pipe.score(x_test, y_test)
但是,当尝试使用下面的另一个 GridSearchCV
时,我 运行 遇到了问题:
mlpc = MLPClassifier(solver='adam',
learning_rate_init=0.01,
max_iter=300,
activation='relu',
early_stopping=True)
pipe = Pipeline(steps=[('cv', CountVectorizer(ngram_range=(1, 1))),
('scale', StandardScaler(with_mean=False)),
('mlpc', MultiOutputClassifier(mlpc))])
search_space = {
'cv__max_df': (0.9, 0.95, 0.99),
'cv__min_df': (0.01, 0.05, 0.1),
'mlpc__estimator__alpha': 10.0 ** -np.arange(1, 5),
'mlpc__estimator__hidden_layer_sizes': ((64, 32), (128, 64),
(64, 32, 16), (128, 64, 32)),
'mlpc__estimator__tol': (1e-3, 5e-3, 1e-4),
}
grid_search = GridSearchCV(pipe, search_space, scoring='accuracy', error_score='raise', n_jobs=-1)
grid_search.fit(x_train, y_train)
这个警告似乎与评分问题有关,UserWarning: One or more of the test scores are non-finite
:
UserWarning: One or more of the test scores are non-finite: [nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan]
warnings.warn(
x_train
、x_test
、y_train
、y_test
的.shape
是(3036,)
(1302,)
(3036, 2)
(1302, 2)
分别。内容都是字符串,在上面的代码中可以看到,我已经将多次出现的NaN替换为空字符串""
,这对于模型来说应该是一个可行的选择(基本上有它select None 作为 class):
df.fillna('', inplace=True) #Replaces NaNs with "" in the DataFrame (which would be considered a viable choice in this multi-classification model)
我在 GridSearchCV
中尝试了其他 scoring=
方法:roc_auc_ovr
和 f1_macro
,但问题基本相同。
如果我在 GridSearchCV
中包含以下选项:error_score='raise'
,我会收到错误消息:ValueError: multiclass-multioutput is not supported
.
ValueError Traceback (most recent call last)
<ipython-input-10-14bccd802d09> in <module>
21 #
22
---> 23 grid_search.fit(x_train, y_train)
~/condaenv/lib/python3.9/site-packages/sklearn/model_selection/_search.py in fit(self, X, y, groups, **fit_params)
889 return results
890
--> 891 self._run_search(evaluate_candidates)
892
893 # multimetric is determined here because in the case of a callable
~/condaenv/lib/python3.9/site-packages/sklearn/model_selection/_search.py in _run_search(self, evaluate_candidates)
1390 def _run_search(self, evaluate_candidates):
1391 """Search all candidates in param_grid"""
-> 1392 evaluate_candidates(ParameterGrid(self.param_grid))
1393
1394
~/condaenv/lib/python3.9/site-packages/sklearn/model_selection/_search.py in evaluate_candidates(candidate_params, cv, more_results)
836 )
837
--> 838 out = parallel(
839 delayed(_fit_and_score)(
840 clone(base_estimator),
~/condaenv/lib/python3.9/site-packages/joblib/parallel.py in __call__(self, iterable)
1059
1060 with self._backend.retrieval_context():
-> 1061 self.retrieve()
1062 # Make sure that we get a last message telling us we are done
1063 elapsed_time = time.time() - self._start_time
~/condaenv/lib/python3.9/site-packages/joblib/parallel.py in retrieve(self)
938 try:
939 if getattr(self._backend, 'supports_timeout', False):
--> 940 self._output.extend(job.get(timeout=self.timeout))
941 else:
942 self._output.extend(job.get())
~/condaenv/lib/python3.9/site-packages/joblib/_parallel_backends.py in wrap_future_result(future, timeout)
540 AsyncResults.get from multiprocessing."""
541 try:
--> 542 return future.result(timeout=timeout)
543 except CfTimeoutError as e:
544 raise TimeoutError from e
~/condaenv/lib/python3.9/concurrent/futures/_base.py in result(self, timeout)
444 raise CancelledError()
445 elif self._state == FINISHED:
--> 446 return self.__get_result()
447 else:
448 raise TimeoutError()
~/condaenv/lib/python3.9/concurrent/futures/_base.py in __get_result(self)
389 if self._exception:
390 try:
--> 391 raise self._exception
392 finally:
393 # Break a reference cycle with the exception in self._exception
ValueError: multiclass-multioutput is not supported
在四处寻找解决方案时,我发现了 CountVectorizer
需要一维输入。我的 .shape
中有两个功能用于多输出。我不知道这个答案是否正确,因为我是第一次评估 scikit-learn。答案建议使用 ColumnTransformer
来解决这个问题,但我需要一个代码示例来理解如果这确实是问题。
您的 y
有多个列,而不是您的 X
,因此 CountVectorizer
不是问题所在。相反,问题在于您有两个目标,每个目标都有两种以上的可能结果。来自同一页面的the User Guide, MLPClassifier
supports multilabel, but not multi-output multiclass. Later,关于评分的额外警告:
Warning: At present, no metric in
sklearn.metrics
supports the multiclass-multioutput classification task.
所以即使您将分类器包装在例如MultiOutputClassifier
网格搜索的评分将失败。我认为您应该能够定义一个自定义记分器来完成这项工作?您可能还会考虑您的标签是否真正正确排序为 label_1 和 label_2,或者这是否可以转换为多标签问题,将目标二值化?