Source code for maxframe.learn.linear_model._lin_reg

# Copyright 1999-2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from numpy.linalg import LinAlgError

from maxframe import tensor as mt
from maxframe.learn.core import RegressorMixin
from maxframe.learn.linear_model._base import LinearModel, _rescale_data
from maxframe.learn.utils.validation import _check_sample_weight

try:
    from sklearn.base import MultiOutputMixin
except ImportError:
    MultiOutputMixin = type("MultiOutputMixin", (object,), {})


[docs] class LinearRegression(LinearModel, RegressorMixin, MultiOutputMixin): """ Ordinary least squares Linear Regression. LinearRegression fits a linear model with coefficients w = (w1, ..., wp) to minimize the residual sum of squares between the observed targets in the dataset, and the targets predicted by the linear approximation. Parameters ---------- fit_intercept : bool, default=True Whether to calculate the intercept for this model. If set to False, no intercept will be used in calculations (i.e. data is expected to be centered). normalize : bool, default=False This parameter is ignored when ``fit_intercept`` is set to False. If True, the regressors X will be normalized before regression by subtracting the mean and dividing by the l2-norm. If you wish to standardize, please use :class:`~sklearn.preprocessing.StandardScaler` before calling ``fit`` on an estimator with ``normalize=False``. copy_X : bool, default=True If True, X will be copied; else, it may be overwritten. positive : bool, default=False When set to ``True``, forces the coefficients to be positive. This option is only supported for dense arrays. Attributes ---------- coef_ : array of shape (n_features, ) or (n_targets, n_features) Estimated coefficients for the linear regression problem. If multiple targets are passed during the fit (y 2D), this is a 2D array of shape (n_targets, n_features), while if only one target is passed, this is a 1D array of length n_features. rank_ : int Rank of matrix `X`. Only available when `X` is dense. singular_ : array of shape (min(X, y),) Singular values of `X`. Only available when `X` is dense. intercept_ : float or array of shape (n_targets,) Independent term in the linear model. Set to 0.0 if `fit_intercept = False`. n_features_in_ : int Number of features seen during :term:`fit`. See Also -------- Ridge : Ridge regression addresses some of the problems of Ordinary Least Squares by imposing a penalty on the size of the coefficients with l2 regularization. Lasso : The Lasso is a linear model that estimates sparse coefficients with l1 regularization. ElasticNet : Elastic-Net is a linear regression model trained with both l1 and l2 -norm regularization of the coefficients. """ _data_attributes = ["coef_", "intercept_"]
[docs] def __init__( self, *, fit_intercept=True, normalize=False, copy_X=True, positive=False, ): self.fit_intercept = fit_intercept self.normalize = normalize self.copy_X = copy_X self.positive = positive
def fit( self, X, y, sample_weight=None, session=None, run_kwargs=None, execute=False ): """ Fit linear model. Parameters ---------- X : {array-like, sparse matrix} of shape (n_samples, n_features) Training data. y : array-like of shape (n_samples,) or (n_samples, n_targets) Target values. Will be cast to X's dtype if necessary. sample_weight : array-like of shape (n_samples,), default=None Individual weights for each sample. Returns ------- self : object Fitted Estimator. """ accept_sparse = False if self.positive else ["csr", "csc", "coo"] X, y = self._validate_data( X, y, accept_sparse=accept_sparse, y_numeric=True, multi_output=True ) if sample_weight is not None: sample_weight = _check_sample_weight(sample_weight, X, dtype=X.dtype) X, y, X_offset, y_offset, X_scale = self._preprocess_data( X, y, fit_intercept=self.fit_intercept, normalize=self.normalize, copy=self.copy_X, sample_weight=sample_weight, return_mean=True, ) if sample_weight is not None: # Sample weight can be implemented via a simple rescaling. X, y = _rescale_data(X, y, sample_weight) if self.positive: # TODO: implement optimize.nnls first raise NotImplementedError("Does not support positive coefficients!") elif X.issparse(): # TODO: implement sparse.linalg.lsqr first raise NotImplementedError("Does not support sparse input!") else: # TODO: implement linalg.lstsq first # In numpy: # Mat mul does NOT always satisfy associative law # Tyipical mistake: # (mt.linalg.inv(X.T @ X) @ (X.T @ y)).T self.coef_ = (mt.linalg.inv(X.T @ X) @ X.T @ y).T if y.ndim == 1: self.coef_ = mt.ravel(self.coef_) self._set_intercept(X_offset, y_offset, X_scale) if execute: run_kwargs = run_kwargs or {} try: self.execute(session=session, **run_kwargs) except LinAlgError: # TODO: implement linalg.lstsq first raise NotImplementedError("Does not support singular matrix!") return self