def TrainSTLSQ(X: np.ndarray, y: np.ndarray, alpha: float, delta_threshold: float, max_iterations: int = 100, test_size: float = 0.2, random_state: int = 0) -> np.ndarray: """[summary] Args: X (np.ndarray): [description] y (np.ndarray): [description] alpha (float): [description] delta_threshold (float): [description] max_iterations (int, optional): [description]. Defaults to 100. test_size (float, optional): [description]. Defaults to 0.2. random_state (int, optional): [description]. Defaults to 0. Returns: np.ndarray: [description] """ # Split data X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=test_size, random_state=random_state) # Set up the initial tolerance l0 penalty and estimates l0 = 1e-3 * np.linalg.cond(X) delta_t = delta_threshold # for interal use, can be updated # Initial estimate optimizer = STLSQ(threshold=0, alpha=0.0, fit_intercept=False) # Now similar to LSTSQ y_predict = optimizer.fit(X_train, y_train).predict(X_test) min_loss = np.linalg.norm(y_predict - y_test, 2) + l0 * np.count_nonzero(optimizer.coef_) # Setting alpha and tolerance best_threshold = delta_t threshold = delta_t for iteration in np.arange(max_iterations): optimizer.set_params(alpha=alpha, threshold=threshold) y_predict = optimizer.fit(X_train, y_train).predict(X_test) loss = np.linalg.norm(y_predict - y_test, 2) + l0 * np.count_nonzero(optimizer.coef_) if (loss <= min_loss) and not (np.all(optimizer.coef_ == 0)): min_loss = loss best_threshold = threshold threshold += delta_threshold else: # if loss increases, we need to a) lower the current threshold and/or decrease step size new_lower_threshold = np.max([0, threshold - 2 * delta_t]) delta_t = 2 * delta_t / (max_iterations - iteration) threshold = new_lower_threshold + delta_t optimizer.set_params(alpha=alpha, threshold=best_threshold) optimizer.fit(X_train, y_train) return optimizer.coef_
def test_alternate_parameters(data_derivative_1d, kwargs): x, x_dot = data_derivative_1d x = x.reshape(-1, 1) model = STLSQ(**kwargs) model.fit(x, x_dot) model.fit(x, x_dot, sample_weight=x[:, 0]) check_is_fitted(model)
def TrainSTLSQ( X: np.ndarray, y: np.ndarray, alpha: float, delta_threshold: float, max_iterations: int = 100, test_size: float = 0.2, random_state: int = 0, ) -> np.ndarray: """PDE-FIND sparsity selection algorithm. Based on method described by Rudy et al. (10.1126/sciadv.1602614). Args: X (np.ndarray): Training input data of shape (n_samples, n_features). y (np.ndarray): Training target data of shape (n_samples, n_outputs). alpha (float): Magnitude of the L2 regularization. delta_threshold (float): Initial stepsize for the search of the threshold max_iterations (int, optional): Maximum number of iterations. Defaults to 100. test_size (float, optional): Fraction of the data that is assigned to the test-set. Defaults to 0.2. random_state (int, optional): Defaults to 0. Returns: np.ndarray: Coefficient vector. """ # Split data X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=test_size, random_state=random_state) # Set up the initial tolerance l0 penalty and estimates l0 = 1e-3 * np.linalg.cond(X) delta_t = delta_threshold # for interal use, can be updated # Initial estimate optimizer = STLSQ(threshold=0, alpha=0.0, fit_intercept=False) # Now similar to LSTSQ y_predict = optimizer.fit(X_train, y_train).predict(X_test) min_loss = np.linalg.norm(y_predict - y_test, 2) + l0 * np.count_nonzero(optimizer.coef_) # Setting alpha and tolerance best_threshold = delta_t threshold = delta_t for iteration in np.arange(max_iterations): optimizer.set_params(alpha=alpha, threshold=threshold) y_predict = optimizer.fit(X_train, y_train).predict(X_test) loss = np.linalg.norm(y_predict - y_test, 2) + l0 * np.count_nonzero(optimizer.coef_) if (loss <= min_loss) and not (np.all(optimizer.coef_ == 0)): min_loss = loss best_threshold = threshold threshold += delta_threshold else: # if loss increases, we need to a) lower the current threshold and/or decrease step size new_lower_threshold = np.max([0, threshold - 2 * delta_t]) delta_t = 2 * delta_t / (max_iterations - iteration) threshold = new_lower_threshold + delta_t optimizer.set_params(alpha=alpha, threshold=best_threshold) optimizer.fit(X_train, y_train) return optimizer.coef_