Example #1
0
    def fit(self, X, y, sample_weight=None):
        """Fit Ridge regression model

        Parameters
        ----------
        X : {array-like, sparse matrix}, shape = [n_samples, n_features]
            Training data

        y : array-like, shape = [n_samples] or [n_samples, n_targets]
            Target values

        sample_weight : float or array-like of shape [n_samples]
            Sample weight

        Returns
        -------
        self : Returns self.
        """
        X, y = check_X_y(X,
                         y, ['csr', 'csc', 'coo'],
                         dtype=np.float64,
                         multi_output=True,
                         y_numeric=True)
        n_samples, n_features = X.shape

        if hasattr(LinearModel, '_preprocess_data'):
            # Scikit-learn 0.18 and up
            X, y, X_offset, y_offset, X_scale = LinearModel._preprocess_data(
                X,
                y,
                self.fit_intercept,
                self.normalize,
                self.copy_X,
                sample_weight=sample_weight)
        else:
            X, y, X_offset, y_offset, X_scale = LinearModel._center_data(
                X,
                y,
                self.fit_intercept,
                self.normalize,
                self.copy_X,
                sample_weight=sample_weight)

        gcv_mode = self.gcv_mode
        with_sw = len(np.shape(sample_weight))

        if gcv_mode is None or gcv_mode == 'auto':
            if sparse.issparse(X) or n_features > n_samples or with_sw:
                gcv_mode = 'eigen'
            else:
                gcv_mode = 'svd'
        elif gcv_mode == "svd" and with_sw:
            # FIXME non-uniform sample weights not yet supported
            warnings.warn("non-uniform sample weights unsupported for svd, "
                          "forcing usage of eigen")
            gcv_mode = 'eigen'

        if gcv_mode == 'eigen':
            _pre_compute = self._pre_compute
            _errors = self._errors
            _values = self._values
        elif gcv_mode == 'svd':
            # assert n_samples >= n_features
            _pre_compute = self._pre_compute_svd
            _errors = self._errors_svd
            _values = self._values_svd
        else:
            raise ValueError('bad gcv_mode "%s"' % gcv_mode)

        if sample_weight is not None:
            X, y = _rescale_data(X, y, sample_weight)

        # Ensure that y is a 2D array: n_samples x n_targets
        flat_y = y.ndim == 1
        if flat_y:
            y = np.atleast_2d(y).T
        n_targets = y.shape[1]

        centered_kernel = not sparse.issparse(X) and self.fit_intercept
        v, Q, QT_y = _pre_compute(X, y, centered_kernel)
        cv_values = np.zeros((n_samples, n_targets, len(self.alphas)))
        C = []

        scorer = check_scoring(self, scoring=self.scoring, allow_none=True)
        error = scorer is None

        for i, alpha in enumerate(self.alphas):
            if error:
                out, c = _errors(alpha, y, v, Q, QT_y)
            else:
                out, c = _values(alpha, y, v, Q, QT_y)
            cv_values[:, :, i] = out
            C.append(c)

        if self.store_cv_values:
            self.cv_values_ = cv_values

        if error:
            if self.alpha_per_target:
                # Find the best alpha for each target
                best = cv_values.mean(axis=0).argmin(axis=1)
            else:
                # Find the best alpha overall
                best = np.mean(cv_values.reshape(-1, len(self.alphas)),
                               axis=0).argmin()
        else:
            # The scorer wants an object that will make the predictions, but
            # they are already computed efficiently by RidgeGCV. This
            # identity_estimator will just return them
            def identity_estimator():
                pass

            identity_estimator.decision_function = lambda y_predict: y_predict
            identity_estimator.predict = lambda y_predict: y_predict

            if self.alpha_per_target:
                out = [
                    scorer(identity_estimator, target, cv_values[:, i, j])
                    for j in range(len(self.alphas))
                    for i, target in enumerate(y.T)
                ]
                best = np.argmax(out, axis=1)
            else:
                out = [
                    scorer(identity_estimator, y.ravel(), cv_values[:, :,
                                                                    i].ravel())
                    for i in range(len(self.alphas))
                ]
                best = np.argmax(out)

        self.alpha_ = self.alphas[best]

        if self.alpha_per_target:
            self.dual_coef_ = np.vstack(
                [C[j][:, i] for i, j in enumerate(best)]).T
        else:
            self.dual_coef_ = C[best]

        self.coef_ = safe_sparse_dot(self.dual_coef_.T, X)

        # If the original y was flat, remove some dimensions to match
        if flat_y:
            if self.store_cv_values:
                self.cv_values_ = cv_values.reshape(n_samples,
                                                    len(self.alphas))
            self.coef_ = self.coef_.ravel()

        self._set_intercept(X_offset, y_offset, X_scale)

        return self