python - regresion - ¿Cómo escribir un estimador personalizado en sklearn y usar validación cruzada en él?
modelos machine learning python (1)
La respuesta también se encuentra en la documentation de Sklearn.
Necesitas definir dos cosas:
un estimador que implementa la función de
fit(X, y)
, siendoX
la matriz con entradas yy
el vector de salidasuna función de anotador, u objeto llamable que se puede usar con:
scorer(estimator, X, y)
y devuelve la puntuación del modelo dado
Refiriéndose a su ejemplo: en primer lugar, el scorer
no debe ser un método del estimador, es una noción diferente. Solo crea un llamable
def scorer(estimator, X, y)
return ????? # compute whatever you want, it''s up to you to define
# what does it mean that the given estimator is "good" or "bad"
O incluso una solución más simple: puede pasar una cadena ''mean_squared_error''
o ''accuracy''
(lista completa disponible en esta parte de la documentación ) a la función cross_val_score
para usar un anotador predefinido.
Otra posibilidad es utilizar la función de fábrica make_scorer
.
En cuanto a lo segundo, puede pasar parámetros a su modelo a través del parámetro documentation función documentation (como se menciona en la documentación). Estos parámetros serán pasados a la función de fit
.
class my_estimator():
def fit(X, y, **kwargs):
alpha = kwargs[''alpha'']
beta=X[1,:]+alpha
return beta
Después de leer todos los mensajes de error, que proporcionan una idea bastante clara de lo que falta, aquí hay un ejemplo simple:
import numpy as np
from sklearn.cross_validation import cross_val_score
class RegularizedRegressor:
def __init__(self, l = 0.01):
self.l = l
def combine(self, inputs):
return sum([i*w for (i,w) in zip([1] + inputs, self.weights)])
def predict(self, X):
return [self.combine(x) for x in X]
def classify(self, inputs):
return sign(self.predict(inputs))
def fit(self, X, y, **kwargs):
self.l = kwargs[''l'']
X = np.matrix(X)
y = np.matrix(y)
W = (X.transpose() * X).getI() * X.transpose() * y
self.weights = [w[0] for w in W.tolist()]
def get_params(self, deep = False):
return {''l'':self.l}
X = np.matrix([[0, 0], [1, 0], [0, 1], [1, 1]])
y = np.matrix([0, 1, 1, 0]).transpose()
print cross_val_score(RegularizedRegressor(),
X,
y,
fit_params={''l'':0.1},
scoring = ''mean_squared_error'')
Me gustaría verificar el error de predicción de un nuevo método a través de la validación cruzada. Me gustaría saber si puedo pasar mi método a la función de validación cruzada de sklearn y en caso de cómo.
Me gustaría algo como sklearn.cross_validation(cv=10).mymethod
.
También necesito saber cómo definir mi mymethod
si es una función y qué elemento de entrada y qué salida
Por ejemplo, podemos considerar como un mymethod
una implementación del estimador de mínimos cuadrados (por supuesto, no los de sklearn).
He encontrado este link tutorial pero no está muy claro para mí.
En la documentation que utilizan.
>>> import numpy as np
>>> from sklearn import cross_validation
>>> from sklearn import datasets
>>> from sklearn import svm
>>> iris = datasets.load_iris()
>>> iris.data.shape, iris.target.shape
((150, 4), (150,))
>>> clf = svm.SVC(kernel=''linear'', C=1)
>>> scores = cross_validation.cross_val_score(
... clf, iris.data, iris.target, cv=5)
...
>>> scores
Pero el problema es que están utilizando como estimador clf
que se obtiene mediante una función incorporada en sklearn. ¿Cómo debo definir mi propio estimador para poder pasarlo a la función cross_validation.cross_val_score
?
Entonces, por ejemplo, supongamos que un estimador simple usa un modelo lineal $ y = x / beta $ donde beta se estima como X [1,:] + alfa donde alfa es un parámetro. ¿Cómo debo completar el código?
class my_estimator():
def fit(X,y):
beta=X[1,:]+alpha #where can I pass alpha to the function?
return beta
def scorer(estimator, X, y) #what should the scorer function compute?
return ?????
Con el siguiente código recibí un error:
class my_estimator():
def fit(X, y, **kwargs):
#alpha = kwargs[''alpha'']
beta=X[1,:]#+alpha
return beta
>>> cv=cross_validation.cross_val_score(my_estimator,x,y,scoring="mean_squared_error")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:/Python27/lib/site-packages/scikit_learn-0.14.1-py2.7-win32.egg/sklearn/cross_validation.py", line 1152, in cross_val_score
for train, test in cv)
File "C:/Python27/lib/site-packages/scikit_learn-0.14.1-py2.7-win32.egg/sklearn/externals/joblib/parallel.py", line 516, in __call__
for function, args, kwargs in iterable:
File "C:/Python27/lib/site-packages/scikit_learn-0.14.1-py2.7-win32.egg/sklearn/cross_validation.py", line 1152, in <genexpr>
for train, test in cv)
File "C:/Python27/lib/site-packages/scikit_learn-0.14.1-py2.7-win32.egg/sklearn/base.py", line 43, in clone
% (repr(estimator), type(estimator)))
TypeError: Cannot clone object ''<class __main__.my_estimator at 0x05ACACA8>'' (type <type ''classobj''>): it does not seem to be a scikit-learn estimator a it does not implement a ''get_params'' methods.
>>>