Case_study_9_1#

!wget --no-cache -O init.py -q https://raw.githubusercontent.com/jdariasl/OTBD/main/content/init.py
import init; init.init(force_download=False)

Use BO to find the best value for the regularisation constant of a linear SVM model

\[\underset{{\bf{w}}}{\arg\min}f({\bf{w}})=\underset{{\bf{w}}\in\mathbb{R}^{d+1}}{\textrm{ arg min}}\left(\frac{1}{n}\sum_{i=1}^n\textrm{max}\left(1-y_{i}\left({\bf{w}}^{T}{\bf{x}}_{i}\right),0\right)+\frac{\lambda}{2}\left\Vert {\bf{w}}\right\Vert _{2}^{2}\right)\]
from local.lib.data import load_data
import cvxpy as cp
import numpy as np
import matplotlib.pyplot as plt
from local.lib.BOutils import BayesianOpt
#cvx_solver
def solver_cvx(n,X,Y,lamb,objective_fn):
    n_columns = X.shape[1]
    w = cp.Variable(n_columns)
    lambd = cp.Parameter(nonneg=True)
    lambd.value = lamb
    problem = cp.Problem(
        cp.Minimize(objective_fn(n, X, Y, w, lambd))
    )
    problem.solve(solver=cp.ECOS)
    return w.value
# Constant parameters
lamb = 0.1   # regularisation parameter
Niter= 3000   # Number of iterations for training the SVM
eta = 0.001   # step size 
# Loading scenarios
# ===========================
#load data
X,y = load_data("classification", 7)
n,d = X.shape

# Definition of the problem
#===================================
loss_fn = lambda n, X, Y, w: (1/n)*cp.sum(cp.pos(1-cp.multiply(Y,X @ w)))
reg_L2 = lambda w: cp.pnorm(w, p=2)**2
loss_svm_L2 = lambda n, X, Y, w, lambd: loss_fn(n, X, Y, w) + (lambd/2) * reg_L2(w)

# Solution of the empirical risk using CVX
w_svm_cvx=solver_cvx(n,X,y,lamb,loss_svm_L2)
f_cvx=loss_svm_L2(n,X,y,w_svm_cvx,lamb).value

print(f'The loss function f for the default lambda takes the value {f_cvx}')
The loss function f for the default lambda takes the value 0.4640527919165618
#Initial samples
bounds = np.array([[1e-5,1]])
n_init = 5
x = np.random.uniform(bounds[:, 0], bounds[:, 1], size=(n_init, 1))
x = np.concatenate([x,np.array([[lamb]])])

yl = []
for i in x:
    w_svm_cvx=solver_cvx(n,X,y,i[0],loss_svm_L2)
    w = cp.Variable(w_svm_cvx.shape[0])
    w.value = w_svm_cvx
    yl.append(loss_svm_L2(n,X,y,w_svm_cvx,lamb).value)
yl = np.array(yl)

bo_opt = BayesianOpt('EI',x,yl,bounds,epsilon=0.5)
/Users/julian/opt/anaconda3/envs/tensorflow/lib/python3.9/site-packages/sklearn/gaussian_process/_gpr.py:610: ConvergenceWarning: lbfgs failed to converge (status=2):
ABNORMAL_TERMINATION_IN_LNSRCH.

Increase the number of iterations (max_iter) or scale the data as shown in:
    https://scikit-learn.org/stable/modules/preprocessing.html
  _check_optimize_result("lbfgs", opt_res)
#Current best value
f_min = f_cvx

#Number of iteration for the BO loop
iter_bo = 10
for k in range(iter_bo):

    #Get the candidate new solution
    x_n = bo_opt.get_next_query_point()

    #Sample the objective function at the new candidate solution
    w_svm_cvx=solver_cvx(n,X,y,x_n[0,0],loss_svm_L2)
    f_cvx=loss_svm_L2(n,X,y,w_svm_cvx,x_n).value
    #Add the new pair to the observed data and train the surrogate model 
    # considering the current set of observed samples
    bo_opt.set_data(x_n,f_cvx[0])
    
    fopt = np.min(bo_opt.obs_y)
    indx = np.argmin(bo_opt.obs_y)
    lopt = bo_opt.obs_x[indx,0]
    if fopt < f_min:
        f_min = fopt
        print(f'loss function improvement at iteration {k}, loss={fopt} and corresponds to lambda = {lopt}')
loss function improvement at iteration 2, loss=0.42061861254062327 and corresponds to lambda = 1e-05
plt.rcParams.update({
    "text.usetex": True,
    "font.family": "Helvetica"
})

x2 = np.linspace(0, 1, 400)[:, None]
mu_pred, sigma_pred = bo_opt.model.predict(x2, return_std=True)

plt.plot(bo_opt.obs_x, bo_opt.obs_y, 'r.', markersize=10, label='Observations')
plt.plot(x2, mu_pred, 'b-', label=u'Mean Prediction')
plt.fill(np.concatenate([x2, x2[::-1]]),
        np.concatenate([mu_pred -  sigma_pred,
                    (mu_pred +  sigma_pred)[::-1]]),
        alpha=.5, fc='b', ec='None', label='$\pm$ 1 std. dev.')
plt.xlabel('$x$')
plt.ylabel('$f(x)$')
plt.legend(loc='upper left')
plt.show()
../_images/b10e4cf4bc9458e05f4a2e5f77c7a728b92126d148266ba5ccfe8c84a19d1119.png