classWLS(RegressorMixin):""" - Uses element-wise multiplication () for weighted regression to avoid the more cumbersome .dot and .diag - np.linalg.lstsq is the most stable method, others are - np.linalg.solve - np.linalg.pinv - np.linalg.inv - Add 1s if intercept required """def__init__(self,fit_intercept=True,alpha=0,penalize_intercept=False,**init_params):self.fit_intercept=fit_interceptself.alpha=lamself.penalize_intercept=penalize_interceptdeffit(self,X,y,sample_weight=None,**fit_params):self.n_features=X.shape[1]# Exclude intercept# Augment matrix and target vectorpenalty=np.sqrt(self.alpha)*np.eye(self.n_features)ifsample_weightisNone:sample_weight=np.ones(X.shape[0])ifself.fit_intercept:X=np.c_[np.ones(x.shape[0]),X]w=np.sqrt(sample_weight)X_aug=np.vstack([X*w.reshape(X.shape[0],1),np.hstack([penalty,np.zeros((n_features,1))])])y_aug=np.concatenate([y*w,np.zeros(n_features)])self.coef,residuals,rank,singular_values=np.linalg.lstsq(X_aug,y_aug,rcond=None)returnselfdefpredict(self,X,y=None):returnnp.dot([1,X],self.coef)
Mini-Batch
classMiniBatchWLS(RegressorMixin):""" - Uses element-wise multiplication () for weighted regression to avoid the more cumbersome .dot and .diag - np.linalg.lstsq is the most stable method, others are - np.linalg.solve - np.linalg.pinv - np.linalg.inv - Add 1s if intercept required """def__init__(self,fit_intercept=True,alpha=0,penalize_intercept=False,n_splits=4,n_jobs=1,**init_params):self.fit_intercept=fit_interceptself.alpha=lamself.penalize_intercept=penalize_interceptself.n_splits=n_splitsself.n_jobs=n_jobsdeffit(self,X,y,sample_weight=None,**fit_params):self.n_samples,self.n_features=X.shape# Exclude interceptself.split_size=self.n_samples//self.n_splits# Augment matrix and target vectorpenalty=np.sqrt(self.alpha)*np.eye(self.n_features)ifsample_weightisNone:sample_weight=np.ones(X.shape[0])ifself.fit_intercept:X=np.c_[np.ones(x.shape[0]),X]w=np.sqrt(sample_weight)# parallelize thisforsplitinrange(self.n_splits):idx_start=split*self.split_sizeidx_end=(split+1)*self.split_sizeXg=X[start_idx:end_idx,:]yg=y[start_idx:end_idx,:]XtX+=Xg.T@XgXty+=Xg.T@ygX_aug=np.vstack([Xtx*w.reshape(self.n_samples,1),np.hstack([penalty,np.zeros((self.n_features,1))])])y_aug=np.concatenate([Xty*w,np.zeros(self.n_features)])self.coef,residuals,rank,singular_values=np.linalg.lstsq(X_aug,y_aug,rcond=None)returnselfdefpredict(self,X,y=None):returnnp.dot([1,X],self.coef)