1

Я использую scikit-learn и создаю конвейер. Как только строится конвейер, я использую GridSearchCV для поиска оптимальной модели. Я работаю с текстовыми данными, поэтому я экспериментирую с разными стволовыми клетками. Я создал класс, называемый Preprocessor, который берет класс стеблемера и векторика, затем пытается переопределить метод build_analyzer метода векторизации, чтобы включить данный стеблемер. Тем не менее, я вижу, что set_params GridSearchCV просто прямой доступ к переменным экземпляра - то есть он не будет повторно создать экземпляр векторизатор с новым анализатором, как я делал это:Метод переопределения для набора классов, реализующих интерфейс

class Preprocessor(object): 
    # hard code the stopwords for now 
    stopwords = nltk.corpus.stopwords.words() 

    def __init__(self, stemmer_cls, vectorizer_cls): 
     self.stemmer = stemmer_cls() 
     analyzer = self._build_analyzer(self.stemmer, vectorizer_cls) 
     self.vectorizer = vectorizer_cls(stopwords=stopwords, 
             analyzer=analyzer, 
             decode_error='ignore') 

    def _build_analyzer(self, stemmer, vectorizer_cls): 
     # analyzer tokenizes and lowercases 
     analyzer = super(vectorizer_cls, self).build_analyzer() 
     return lambda doc: (stemmer.stem(w) for w in analyzer(doc)) 

    def fit(self, **kwargs): 
     return self.vectorizer.fit(kwargs) 

    def transform(self, **kwargs): 
     return self.vectorizer.transform(kwargs) 

    def fit_transform(self, **kwargs): 
     return self.vectorizer.fit_transform(kwargs) 

Таким образом, вопрос: как я могу переопределить build_analyzer для всех классов векторизации, переданных в?

ответ

0

Да, GridSearchCV напрямую задает поля экземпляра, а затем вызывает соответствие классификатору с измененными полями.

Каждый классификатор в scikit-learn был построен таким образом, что __init__ устанавливает только поля параметров, и все зависимые объекты, необходимые для дальнейшей работы (например, вызов _build_analyzer в вашем случае), построены только внутри метода fit. Вы должны добавить дополнительное поле, в котором хранится vectorizer_cls, тогда вам нужно построить зависимые от объектов vectorized_cls и stemmer_cls внутри метода fit.

Что-то вроде:

class Preprocessor(object): 
    # hard code the stopwords for now 
    stopwords = nltk.corpus.stopwords.words() 

    def __init__(self, stemmer_cls, vectorizer_cls): 
     self.stemmer_cls = stemmer_cls 
     self.vectorizer_cls = vectorizer_cls 

    def _build_analyzer(self, stemmer, vectorizer_cls): 
     # analyzer tokenizes and lowercases 
     analyzer = super(vectorizer_cls, self).build_analyzer() 
     return lambda doc: (stemmer.stem(w) for w in analyzer(doc)) 

    def fit(self, **kwargs): 
     analyzer = self._build_analyzer(self.stemmer_cls(), vectorizer_cls) 
     self.vectorizer_cls = vectorizer_cls(stopwords=stopwords, 
             analyzer=analyzer, 
             decode_error='ignore') 

     return self.vectorizer_cls.fit(kwargs) 

    def transform(self, **kwargs): 
     return self.vectorizer_cls.transform(kwargs) 

    def fit_transform(self, **kwargs): 
     return self.vectorizer_cls.fit_transform(kwargs)