--- title: "Quadratic Programming" subtitle: Advanced Statistical Computing author: Joong-Ho Won date: today date-format: "MMMM YYYY" institute: Seoul National University execute: echo: true format: revealjs: toc: false theme: dark code-fold: false scrollable: true jupyter: julia --- versioninfo() using Pkg Pkg.activate(pwd()) Pkg.instantiate() Pkg.status() using Statistics using Random, LinearAlgebra, SparseArrays Random.seed!(123) # seed n, p = 100, 10 # Design matrix X0 = randn(n, p) X = [ones(n, 1) (X0 .- mean(X0 ,dims=1)) ./ std(X0, dims=1)] # design matrix is standardized and includes intercept # True regression coefficients (first 5 are non-zero) β = [1.0; randn(5); zeros(p - 5)] # Responses y = X * β + randn(n) # plot the true β using Plots plt = plot(1:p, β[2:end], line=:stem, marker=2, legend=:none) xlabel!(plt, "coordinate") ylabel!(plt, "beta_j") title!(plt, "True beta") using Convex, MathOptInterface using Mosek, MosekTools const MOI = MathOptInterface # solve at a grid of λ λgrid = 0:20:1000 ridgepath = zeros(length(λgrid), size(X, 2)) # each row is β̂ at a λ β̂ridge = Variable(size(X, 2)) @time for i in 1:length(λgrid) λ = λgrid[i] # objective problem = minimize(sumsquares(y - X * β̂ridge) + λ * sumsquares(β̂ridge[2:end])) solver = Mosek.Optimizer() # MOSEK this time! MOI.set(solver, MOI.RawOptimizerAttribute("LOG"), 0) # keep silent solve!(problem, solver) ridgepath[i, :] = β̂ridge.value end plt = plot(collect(λgrid), ridgepath, legend=:none) xlabel!(plt, "lambda") ylabel!(plt, "beta_hat") title!(plt, "Ridge") # Use COSMO solver using COSMO solver = COSMO.Optimizer() ## Use SCS solver # using SCS # solver = SCS.Optimizer() ## Use Mosek solver # using Mosek, MosekTools # solver = Mosek.Optimizer() ## Use Hypatia solver # using Hypatia # solver = Hypatia.Optimizer() # Set up optimizaiton problem β̂nonneg = Variable(size(X, 2)) problem = minimize(0.5sumsquares(y - X * β̂nonneg)) problem.constraints += β̂nonneg[2:end] >= 0 # Solve the problem @time solve!(problem, solver) plot(β[2:end], line=:stem, label="true beta") plot!(β̂nonneg.value[2:end], line=:stem, title="Nonnegative LS", label="fitted") using Mosek, MosekTools # solve at a grid of λ λgrid = 0:10:200 β̂path = zeros(length(λgrid), size(X, 2)) # each row is β̂ at a λ β̂lasso = Variable(size(X, 2)) @time for i in 1:length(λgrid) λ = λgrid[i] # objective problem = minimize(0.5sumsquares(y - X * β̂lasso) + λ * norm(β̂lasso[2:end], 1)) solver = Mosek.Optimizer() # MOSEK this time! MOI.set(solver, MOI.RawOptimizerAttribute("LOG"), 0) # keep silent solve!(problem, solver) β̂path[i, :] = β̂lasso.value end plt = plot(collect(λgrid), β̂path, legend=:none) xlabel!(plt, "lambda") ylabel!(plt, "beta_hat") title!(plt, "Lasso") # solve at a grid of λ λgrid = 0:10:400 alpha = 0.5 elastipath = zeros(length(λgrid), size(X, 2)) # each row is β̂ at a λ β̂elastic = Variable(size(X, 2)) @time for i in 1:length(λgrid) λ = λgrid[i] # objective problem = minimize(0.5*sumsquares(y - X * β̂elastic) + λ * (alpha*norm(β̂elastic[2:end],1) + (1-alpha)*sumsquares(β̂elastic[2:end]))) solver = Mosek.Optimizer() # MOSEK this time! MOI.set(solver, MOI.RawOptimizerAttribute("LOG"), 0) # keep silent solve!(problem, solver) elastipath[i, :] = β̂elastic.value end plt = plot(collect(λgrid), elastipath, legend=:none) xlabel!(plt, "lambda") ylabel!(plt, "beta_hat") title!(plt, "Elastic net") using Mosek, MosekTools # solve at a grid of λ λgrid = 0:10:150 β̂conpath = zeros(length(λgrid), size(X, 2)) # each row is β̂ at a λ β̂conlasso = Variable(size(X, 2)) @time for i in 1:length(λgrid) λ = λgrid[i] # objective problem = minimize(0.5sumsquares(y - X * β̂conlasso) + λ * norm(β̂conlasso[2:end], 1)) problem.constraints += β̂conlasso[2:end] >= 0 solver = Mosek.Optimizer() # MOSEK this time! MOI.set(solver, MOI.RawOptimizerAttribute("LOG"), 0) # keep silent solve!(problem, solver) β̂conpath[i, :] = β̂conlasso.value end plt = plot(collect(λgrid), β̂conpath, legend=:none) xlabel!(plt, "lambda") ylabel!(plt, "beta_hat") title!(plt, "Constrained Lasso") # convert to classification problem Y = sign.(X * β + 5 * randn(n)) # solve at a grid of λ λgrid = 0:10:100 β̂svmpath = zeros(length(λgrid), size(X, 2)) # each row is β̂ at a λ β̂svm = Variable(size(X, 2)) @time for i in 1:length(λgrid) λ = λgrid[i] # objective problem = minimize(sum(pos(1 - Y .* (X * β̂svm))) + λ * sumsquares(β̂svm[2:end])) solver = Mosek.Optimizer() # MOSEK this time! MOI.set(solver, MOI.RawOptimizerAttribute("LOG"), 0) # keep silent solve!(problem, solver) β̂svmpath[i, :] = β̂svm.value end plt = plot(collect(λgrid), β̂svmpath, legend=:none) xlabel!(plt, "lambda") ylabel!(plt, "beta_hat") title!(plt, "SVM")