15#include <Eigen/SparseCore>
50 void setSolver(
const std::string& solver);
208 void setLoss(
const std::string& loss_type);
284 void setScaling(
const Eigen::VectorXd& x_scales);
333 const Eigen::MatrixXd& y_in,
334 Eigen::ArrayXd alpha = Eigen::ArrayXd::Zero(0),
335 Eigen::ArrayXd lambda = Eigen::ArrayXd::Zero(0));
354 const Eigen::MatrixXd& y_in,
355 const double alpha = 1.0,
356 Eigen::ArrayXd lambda = Eigen::ArrayXd::Zero(0));
375 const Eigen::VectorXd& y_in,
376 const double gamma = 0.0,
377 Eigen::VectorXd beta0 = Eigen::VectorXd(0),
378 Eigen::VectorXd beta = Eigen::VectorXd(0))
380 using Eigen::MatrixXd;
381 using Eigen::VectorXd;
386 if (beta0.size() == 0) {
390 if (beta.size() == 0) {
398 std::vector<double> primals, duals, time;
401 auto jit_normalization =
402 normalize(x, x_centers, x_scales, centering_type, scaling_type, modify_x);
404 bool update_clusters =
false;
406 std::unique_ptr<Loss> loss =
setupLoss(this->loss_type);
408 MatrixXd y = loss->preprocessResponse(y_in);
412 Eigen::ArrayXd lambda_relax = Eigen::ArrayXd::Zero(p * m);
424 VectorXd gradient = VectorXd::Zero(p * m);
425 VectorXd residual(n);
426 VectorXd working_residual(n);
428 VectorXd w = VectorXd::Ones(n);
429 VectorXd w_ones = VectorXd::Ones(n);
436 for (
int irls_it = 0; irls_it < max_it_outer_relax; irls_it++) {
437 residual = loss->residual(eta, y);
439 if (collect_diagnostics) {
440 primals.push_back(loss->loss(eta, y));
441 duals.push_back(0.0);
442 time.push_back(timer.
elapsed());
445 Eigen::VectorXd cluster_gradient = clusterGradient(beta,
454 double norm_grad = cluster_gradient.lpNorm<Eigen::Infinity>();
456 if (norm_grad < tol_relax) {
460 loss->updateWeightsAndWorkingResponse(w, z, eta, y);
461 working_residual = eta - z;
463 for (
int inner_it = 0; inner_it < max_it_inner_relax; ++inner_it) {
479 if (max_abs_gradient < tol_relax) {
484 eta = working_residual + z;
486 if (irls_it == max_it_outer_relax) {
488 "Maximum number of IRLS iterations reached.");
492 double dev = loss->deviance(eta, y);
497 beta = (1 - gamma) * beta + gamma * old_coefs;
501 beta.reshaped(p, m).sparseView(),
535 const Eigen::VectorXd& y,
536 const double gamma = 0.0)
538 std::vector<SlopeFit> fits;
543 for (
size_t i = 0; i <
path.
size(); i++) {
544 auto relaxed_fit =
relax(
path(i), x, y, gamma, beta0, beta);
546 fits.emplace_back(relaxed_fit);
552 beta0 = relaxed_fit.getIntercepts(
false);
553 beta = relaxed_fit.getCoefs(
false);
561 bool collect_diagnostics =
false;
562 bool intercept =
true;
563 bool modify_x =
false;
564 bool return_clusters =
true;
565 bool update_clusters =
false;
566 double alpha_min_ratio = -1;
567 double dev_change_tol = 1e-5;
568 double dev_ratio_tol = 0.999;
569 double learning_rate_decr = 0.5;
574 double tol_relax = 1e-4;
575 int alpha_est_maxit = 1000;
576 int cd_iterations = 10;
578 int max_it_inner_relax = 1e5;
579 int max_it_outer_relax = 50;
580 int path_length = 100;
581 std::optional<int> max_clusters = std::nullopt;
582 std::string alpha_type =
"path";
583 std::string centering_type =
"mean";
584 std::string lambda_type =
"bh";
585 std::string loss_type =
"quadratic";
586 std::string scaling_type =
"sd";
587 std::string screening_type =
"strong";
588 std::string solver_type =
"auto";
591 Eigen::VectorXd x_centers;
592 Eigen::VectorXd x_scales;
Representation of the clusters in SLOPE.
A class representing the results of SLOPE (Sorted L1 Penalized Estimation) fitting.
const Clusters & getClusters() const
Gets the clusters.
Eigen::VectorXd getIntercepts(const bool original_scale=true) const
Gets the intercept terms for this SLOPE fit.
Eigen::SparseMatrix< double > getCoefs(const bool original_scale=true) const
Gets the sparse coefficient matrix for this fit.
double getNullDeviance() const
Gets the null model deviance.
Container class for SLOPE regression solution paths.
std::vector< Eigen::VectorXd > getIntercepts(const bool original_scale=true) const
Returns the vector of intercept terms for each solution in the path.
std::size_t size() const
Gets the number of solutions in the path.
std::vector< Eigen::SparseMatrix< double > > getCoefs(const bool original_scale=true) const
Returns the vector of coefficient matrices for each solution in the path.
void setSolver(const std::string &solver)
Sets the numerical solver used to fit the model.
void setAlphaMinRatio(double alpha_min_ratio)
Sets the alpha min ratio.
void setMaxIterations(int max_it)
Sets the maximum number of iterations.
void setAlphaEstimationMaxIterations(const int alpha_est_maxit)
Sets the maximum number of iterations for the alpha estimation procedure.
void setRelaxMaxInnerIterations(int max_it)
Sets the maximum number of inner iterations for the relaxed solver.
SlopePath path(T &x, const Eigen::MatrixXd &y_in, Eigen::ArrayXd alpha=Eigen::ArrayXd::Zero(0), Eigen::ArrayXd lambda=Eigen::ArrayXd::Zero(0))
Computes SLOPE regression solution path for multiple alpha and lambda values.
void setDevRatioTol(const double dev_ratio_tol)
Sets tolerance in deviance change for early stopping.
void setScaling(const std::string &type)
Sets the scaling type.
SlopeFit fit(T &x, const Eigen::MatrixXd &y_in, const double alpha=1.0, Eigen::ArrayXd lambda=Eigen::ArrayXd::Zero(0))
Fits a single SLOPE regression model for given alpha and lambda values.
void setDevChangeTol(const double dev_change_tol)
Sets tolerance in deviance change for early stopping.
const std::string & getLossType()
Get currently defined loss type.
void setReturnClusters(const bool return_clusters)
Sets the return clusters flag.
void setRelaxMaxOuterIterations(int max_it)
Sets the maximum number of outer (IRLS) iterations for the relaxed solver.
void setMaxClusters(const int max_clusters)
Sets the maximum number of clusters.
void setIntercept(bool intercept)
Sets the intercept flag.
bool getFitIntercept() const
Returns the intercept flag.
void setDiagnostics(const bool collect_diagnostics)
Toggles collection of diagnostics.
void setNormalization(const std::string &type)
Sets normalization type for the design matrix.
SlopeFit relax(const SlopeFit &fit, T &x, const Eigen::VectorXd &y_in, const double gamma=0.0, Eigen::VectorXd beta0=Eigen::VectorXd(0), Eigen::VectorXd beta=Eigen::VectorXd(0))
Relaxes a fitted SLOPE model.
int getAlphaEstimationMaxIterations() const
Gets the maximum number of iterations allowed for the alpha estimation procedure.
void setScreening(const std::string &screening_type)
Sets the type of feature screening used, which discards predictors that are unlikely to be active.
void setOscarParameters(const double theta1, const double theta2)
Sets OSCAR parameters.
void setLambdaType(const std::string &lambda_type)
Sets the lambda type for regularization weights.
void setAlphaType(const std::string &alpha_type)
Sets the alpha type.
void setModifyX(const bool modify_x)
Controls if x should be modified-in-place.
void setCentering(const std::string &type)
Sets the center points for feature normalization.
void setLearningRateDecr(double learning_rate_decr)
Sets the learning rate decrement.
void setLoss(const std::string &loss_type)
Sets the loss function type.
SlopePath relax(const SlopePath &path, T &x, const Eigen::VectorXd &y, const double gamma=0.0)
Relaxes a fitted SLOPE path.
void setRelaxTol(double tol)
Sets the tolerance value for the relaxed SLOPE solver.
void setPathLength(int path_length)
Sets the path length.
void setHybridCdIterations(int cd_iterations)
Sets the frequence of proximal gradient descent steps.
void setTol(double tol)
Sets the tolerance value.
void setQ(double q)
Sets the q value.
void setUpdateClusters(bool update_clusters)
Sets the update clusters flag.
Timer class for measuring elapsed time with high resolution.
void start()
Starts the timer by recording the current time point.
double elapsed() const
Returns the elapsed time in seconds since start() was called.
static void addWarning(WarningCode code, const std::string &message)
Log a new warning.
An implementation of the coordinate descent step in the hybrid algorithm for solving SLOPE.
Thread-safe warning logging facility for the slope library.
Namespace containing SLOPE regression implementation.
double coordinateDescent(Eigen::VectorXd &beta0, Eigen::VectorXd &beta, Eigen::VectorXd &residual, Clusters &clusters, const Eigen::ArrayXd &lambda, const T &x, const Eigen::VectorXd &w, const Eigen::VectorXd &x_centers, const Eigen::VectorXd &x_scales, const bool intercept, const JitNormalization jit_normalization, const bool update_clusters)
std::unique_ptr< Loss > setupLoss(const std::string &loss)
Factory function to create the appropriate loss function based on the distribution family.
Eigen::MatrixXd linearPredictor(const T &x, const std::vector< int > &active_set, const Eigen::VectorXd &beta0, const Eigen::VectorXd &beta, const Eigen::VectorXd &x_centers, const Eigen::VectorXd &x_scales, const JitNormalization jit_normalization, const bool intercept)
JitNormalization normalize(Eigen::MatrixXd &x, Eigen::VectorXd &x_centers, Eigen::VectorXd &x_scales, const std::string ¢ering_type, const std::string &scaling_type, const bool modify_x)
@ MAXIT_REACHED
Maximum iterations reached without convergence.
std::vector< int > activeSet(const Eigen::VectorXd &beta)
Identifies previously active variables.
Screening rules for SLOPE regression optimization.
SLOPE (Sorted L-One Penalized Estimation) fitting results.
Defines the SlopePath class for storing and accessing SLOPE regression solution paths.
Simple high-resolution timer class for performance measurements.