Как метод .fit () Scikit-Learn передает данные в .predict ()? - PullRequest
1 голос
/ 25 октября 2019

Я пытаюсь понять связь между методом sklearn's .fit() и методом .predict();главным образом, как именно данные (как правило) передаются от одного к другому. Я не нашел другого вопроса о SO, который касался этого, но танцевал вокруг него (то есть здесь )

Я написал собственный оценщик, используя BaseEstimator и RegressorMixin классов, но несколько раз сталкивались с NotFitedError, когда я начал просматривать свои данные. Может ли кто-нибудь провести меня через простую линейную регрессию и как данные передаются через методы подбора и прогнозирования? Не нужно углубляться в математику - я понимаю, как работают регрессии и что делают кусочки головоломки. Может быть, я упускаю из виду очевидное и делаю его более сложным, чем должно быть? Но методы оценки ощущаются как черный ящик.

Ответы [ 2 ]

2 голосов
/ 25 октября 2019

Давайте посмотрим на игрушечный Оценщик, который выполняет LinearRegression

from sklearn.base import TransformerMixin, BaseEstimator
import numpy as np

class ToyEstimator(BaseEstimator):
    def __init__(self):
        pass

    def fit(self, X, y):
        X = np.hstack((X,np.ones((len(X),1))))
        self.W = np.random.randn(X.shape[1])

        self.W = np.dot(np.dot(np.linalg.inv(np.dot(X.T,X)), X.T), y)
        self.coef_ = self.W[:-1]
        self.intercept_ = self.W[-1]
        return self


    def transform(self, X):
        X = np.hstack((X,np.ones((len(X),1))))
        return np.dot(X,self.W)

X = np.random.randn(10,3)
y = X[:,0]*1.11+X[:,1]*2.22+X[:,2]*3.33+4.44

reg = ToyEstimator()
reg.fit(X,y)
y_ = reg.transform(X)
print (reg.coef_, reg.intercept_)

Вывод:

[1.11 2.22 3.33] 4.4399999999999995

Так что же сделал приведенный выше код?

  1. В fit мы подгоняем \ тренируем веса, используя данные тренировок. Эти весовые коэффициенты являются переменными-членами класса [это то, что вы изучаете в ООП]
  2. Метод transform прогнозирует данные, используя обученные весовые коэффициенты, которые хранятся как переменные-члены.

Поэтому перед вызовом transform необходимо позвонить fit, потому что transform использует веса, которые рассчитываются при подгонке.

В модулях sklearn, если вы вызываете transform до fit вы получаете NotFittedError исключение.

1 голос
/ 25 октября 2019

NotFittedError происходит, когда вы пытаетесь использовать метод .predict() вашего классификатора до того, как вы обучились или использовали метод .fit().

Давайте возьмем, например, LinearRegression из scikit learn.

>>> import numpy as np
>>> from sklearn.linear_model import LinearRegression
>>> X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])
>>> # y = 1 * x_0 + 2 * x_1 + 3
>>> y = np.dot(X, np.array([1, 2])) + 3
>>> reg = LinearRegression().fit(X, y)
>>> reg.score(X, y)
1.0
>>> reg.coef_
array([1., 2.])
>>> reg.intercept_ 
3.0000...
>>> reg.predict(np.array([[3, 5]]))
array([16.])

, поэтому с помощью строки reg = LinearRegression().fit(X, y) вы создаете экземпляр класса LinearRegression, а затем подгоняете егок вашим данным X и y, где X - независимые переменные, а y - ваши зависимые. После обучения модели внутри этого класса бета-коэффициенты для линейной регрессии сохраняются в атрибуте класса coef_, и вы можете получить к нему доступ, используя reg.coef_. Вот как класс знает, как предсказать, когда вы используете метод класса .predict(). Класс обращается к этим коэффициентам, а затем к своей простой алгебре, чтобы получить прогноз.

Итак, вернемся к вашей ошибке. Если вы не подгоняете модель к своим данным обучения, тогда у класса нет необходимых атрибутов, необходимых для предсказаний. Надеюсь, это прояснит некоторую путаницу в отношении того, что происходит внутри класса, по крайней мере, в отношении того, как взаимодействуют методы fit() и predict().

В конечном счете, как прокомментировано выше, это восходит к основам объектно-ориентированного программирования. поэтому, если вы хотите узнать больше, я бы прочитал о том, как Python обрабатывает классы, так как модели обучения scikit следуют тому же поведению

...