Это длинная проблема, но я надеюсь, что кто-то знает ответ.Я получаю ошибку в коде, который мне не следует, и после проверки GitHub scikit-learn обнаружил, что код scikit-learn на моем компьютере не совпадает с кодом в репозитории, даже если я полностью обновлен (как проверено с помощью__version__ метод).Не уверен, действительно ли это актуально или нет, я позволю вам попытаться определить это.Основная проблема изложена ниже в прикрепленном коде:
class ModelCollection(BaseEstimator):
def __init__(self, models, **model_params):
'''
Class to allow collections of models to be easily fit together and predict outcome of each model
:param model_list: List of tuples of form (name, model). Similar to the setup for a scitkit-learn pipeline
'''
import numpy as np
self.np = np
self.models = models
self.__set_params(models)
self.set_params(**model_params)
def model_index(self, model_name):
'''
Returns index of model given model name
:param model_name: name of model
:return: index of model in self.model_list
'''
try:
return self.name_list.index(model_name)
except:
raise ValueError("Model name not found in model list.")
def __get_X(self, X, key):
'''
Workaround to allow different models to be trained on different sets concurrently
:param X: Either a single dataset or list of datasets
:param key: Index of dataset in list
:return: returns X if X is not a list, returns the key-th dataset if X is a list of datasets
'''
if type(X)==list:
return X[key]
else:
return X
def fit(self, X, y, names=None, verbose=False):
'''
Fits each model
:param X: Feature set or list of feature sets
:param y: Labels
:param names: names of models to train. If None, trains all models
:param verbose: True to return tqdm progress bar
:return: self
'''
temp_list = []
if names is None:
names = self.name_list
for key, name in self.tqdm(enumerate(names), disable=(not verbose)):
index = self.name_list.index(name)
temp_model = self.model_list[key].fit(self.__get_X(X, key), y)
temp_list.append(temp_model)
self.model_list = temp_list
return self
def predict(self, X, verbose=False):
'''
Create a prediction array
:param X: Features
:param verbose: True to return tqdm progress bar
:return: returns an array of predictions, where each column represents the prediction of it's corresponding model
'''
for model_col in self.tqdm(range(self.num_models), disable=(not verbose)):
if model_col == 0:
predict_array = self.model_list[model_col].predict(self.__get_X(X, model_col))
else:
temp_array = self.model_list[model_col].predict(self.__get_X(X, model_col))
predict_array = self.np.vstack((predict_array, temp_array))
return self.np.transpose(predict_array)
def predict_proba(self, X, shorten_array=True, verbose=False):
'''
Create a probability prediction array
:param X: Features
:param verbose: True to return tqdm progress bar
:return: returns an array of prediction probabilities, where each column represents the prediction of it's corresponding model
'''
if shorten_array:
slice = 1
else:
slice = 0
for model_col in self.tqdm(range(self.num_models), disable=(not verbose)):
if model_col == 0:
try:
prob_array = self.model_list[model_col].predict_proba(self.__get_X(X, model_col))[:,slice:]
except:
prob_array = self.model_list[model_col].predict(self.__get_X(X, model_col))
else:
try:
temp_array = self.model_list[model_col].predict_proba(self.__get_X(X, model_col))[:,slice:]
except:
temp_array = self.model_list[model_col].predict(self.__get_X(X, model_col))
prob_array = self.np.hstack((prob_array, temp_array))
return prob_array
if __name__ == "__main__":
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import MultinomialNB
from sklearn.ensemble import RandomForestClassifier
#generate random numbers to train on
np.random.seed(0)
x_train = np.random.randint(0, 10, (80, 3))
x_test = np.random.randint(0, 10, (20, 3))
y_train = np.random.randint(0, 2, 80)
y_test = np.random.randint(0, 2, 20)
test = ModelCollection([('log', LogisticRegression(random_state=0)), ('nb', MultinomialNB())])
test.fit(x_train, y_train)
После этого я могу отлично использовать методы класса .predict () и .predict_proba () класса.Сами модели обучены и работают по назначению.Однако, когда я пытаюсь вызвать этот класс в другом классе, все модели в test.model_list по отдельности завершают работу с методом .decision_function () в LinearClassifierMixin.Последняя строка сообщения об ошибке гласит:
~\Anaconda3\lib\site-packages\sklearn\linear_model\base.py in predict(self, X)
287 Predicted class label per sample.
288 """
--> 289 scores = self.decision_function(X)
290 if len(scores.shape) == 1:
291 indices = (scores > 0).astype(np.int)
~\Anaconda3\lib\site-packages\sklearn\linear_model\base.py in decision_function(self, X)
253 if not hasattr(self, 'coef_') or self.coef_ is None:
254 raise NotFittedError("This %(name)s instance is not fitted "
--> 255 "yet" % {'name': type(self).__name__})
256
257 X = check_array(X, accept_sparse='csr')
NotFittedError: This LogisticRegression instance is not fitted yet
Когда я проверяю это, отдельные условия в условной строке 253 для каждой модели, однако, они не соответствуют обоим условиям, поэтому никогда не следует переходить к строке 254.Некоторое время я заходил в исходный код для этого, и исходный код выше не не соответствует репозиторию scikit-learn GitHub, хотя я полностью обновлен и использую __version__, подтверждающий это.Я, честно говоря, понятия не имею, что происходит, моя функция не должна соответствовать условиям выражения «или» в строке 253, но это по какой-то причине.Как я уже сказал, обе модели на самом деле подходят , и функция прекрасно работает, вызывая методы .predict () и .predict_proba () моего класса.
Я предполагаю, что смогу заставить его работать, просто перебив тесты соответствия, используемые scikit-learn и пропуская их, но я хочу, чтобы классы работали так, чтобы другие люди могли использовать их безтакже зарезать библиотеку на своем компьютере.Буду признателен за любую помощь.
(есть еще кое-что из вышеперечисленного класса, которое я вырезал по космическим причинам, которое не должно быть релевантным. Если вам нужны они или класс ансамбля, в котором я использую этот класс, позвольте мнезнаю).Спасибо!