예제 #1
0
    def test_ProxElasticNet(self):
        """...Test of ProxElasticNet
        """
        coeffs = self.coeffs.copy()

        l_enet = 3e-2
        ratio = .3
        t = 1.7
        prox_enet = ProxElasticNet(l_enet, ratio=ratio)
        prox_l1 = ProxL1(ratio * l_enet)
        prox_l2 = ProxL2Sq((1 - ratio) * l_enet)

        self.assertAlmostEqual(prox_enet.value(coeffs),
                               prox_l1.value(coeffs) + prox_l2.value(coeffs),
                               delta=1e-15)

        out = coeffs.copy()
        prox_l1.call(out, t, out)
        prox_l2.call(out, t, out)
        assert_almost_equal(prox_enet.call(coeffs, step=t), out, decimal=10)

        prox_enet = ProxElasticNet(l_enet, ratio=ratio, positive=True)
        prox_l1 = ProxL1(ratio * l_enet, positive=True)
        prox_l2 = ProxL2Sq((1 - ratio) * l_enet, positive=True)

        self.assertAlmostEqual(prox_enet.value(coeffs),
                               prox_l1.value(coeffs) + prox_l2.value(coeffs),
                               delta=1e-15)

        out = coeffs.copy()
        prox_l1.call(out, t, out)
        prox_l2.call(out, t, out)
        assert_almost_equal(prox_enet.call(coeffs, step=t), out, decimal=10)
예제 #2
0
    def compare_solver_sdca(self):
        """...Compare SDCA solution with SVRG solution
        """
        np.random.seed(12)
        n_samples = Test.n_samples
        n_features = Test.n_features

        for fit_intercept in [True, False]:
            y, X, coeffs0, interc0 = TestSolver.generate_logistic_data(
                n_features, n_samples)

            model = ModelLogReg(fit_intercept=fit_intercept).fit(X, y)
            ratio = 0.5
            l_enet = 1e-2

            # SDCA "elastic-net" formulation is different from elastic-net
            # implementation
            l_l2_sdca = ratio * l_enet
            l_l1_sdca = (1 - ratio) * l_enet
            sdca = SDCA(l_l2sq=l_l2_sdca, max_iter=100, verbose=False, tol=0,
                        seed=Test.sto_seed).set_model(model)
            prox_l1 = ProxL1(l_l1_sdca)
            sdca.set_prox(prox_l1)
            coeffs_sdca = sdca.solve()

            # Compare with SVRG
            svrg = SVRG(max_iter=100, verbose=False, tol=0,
                        seed=Test.sto_seed).set_model(model)
            prox_enet = ProxElasticNet(l_enet, ratio)
            svrg.set_prox(prox_enet)
            coeffs_svrg = svrg.solve(step=0.1)

            np.testing.assert_allclose(coeffs_sdca, coeffs_svrg)
예제 #3
0
    def test_ProxL1(self):
        """...Test of ProxL1
        """
        coeffs = self.coeffs.copy()

        l_l1 = 3e-2
        t = 1.7

        prox = ProxL1(l_l1)
        thresh = t * l_l1
        out = np.sign(coeffs) * (np.abs(coeffs) - thresh) \
              * (np.abs(coeffs) > thresh)
        self.assertAlmostEqual(prox.value(coeffs),
                               l_l1 * np.abs(coeffs).sum(),
                               delta=1e-15)
        assert_almost_equal(prox.call(coeffs, step=t), out, decimal=10)

        prox = ProxL1(l_l1, (3, 8))
        thresh = t * l_l1
        sub_coeffs = coeffs[3:8]
        out = coeffs.copy()
        out[3:8] = np.sign(sub_coeffs) \
                   * (np.abs(sub_coeffs) - thresh) \
                   * (np.abs(sub_coeffs) > thresh)
        self.assertAlmostEqual(prox.value(coeffs),
                               l_l1 * np.abs(coeffs[3:8]).sum(),
                               delta=1e-15)
        assert_almost_equal(prox.call(coeffs, step=t), out, decimal=10)

        prox = ProxL1(l_l1, (3, 8), positive=True)
        thresh = t * l_l1
        sub_coeffs = coeffs[3:8]
        out = coeffs.copy()
        out[3:8] = np.sign(sub_coeffs) * (np.abs(sub_coeffs) - thresh) \
                   * (np.abs(sub_coeffs) > thresh)
        idx = out[3:8] < 0
        out[3:8][idx] = 0
        self.assertAlmostEqual(prox.value(coeffs),
                               l_l1 * np.abs(coeffs[3:8]).sum(),
                               delta=1e-15)
        assert_almost_equal(prox.call(coeffs, step=t), out, decimal=10)
예제 #4
0
    def test_dense_and_sparse_match(self):
        """...Test in SVRG that dense and sparse code matches in all possible
        settings
        """
        variance_reductions = ['last', 'rand']
        rand_types = ['perm', 'unif']
        seed = 123
        tol = 0.
        max_iter = 50

        n_samples = 500
        n_features = 20

        # Crazy prox examples
        proxs = [
            ProxTV(strength=1e-2, range=(5, 13), positive=True),
            ProxElasticNet(strength=1e-2, ratio=0.9),
            ProxEquality(range=(0, n_features)),
            ProxL1(strength=1e-3, range=(5, 17)),
            ProxL1w(strength=1e-3, weights=np.arange(5, 17, dtype=np.double),
                    range=(5, 17)),
        ]

        for intercept in [-1, None]:
            X, y = self.simu_linreg_data(interc=intercept,
                                         n_features=n_features,
                                         n_samples=n_samples)

            fit_intercept = intercept is not None
            model_dense, model_spars = self.get_dense_and_sparse_linreg_model(
                    X, y, fit_intercept=fit_intercept)
            step = 1 / model_spars.get_lip_max()

            for variance_reduction, rand_type, prox in product(
                    variance_reductions, rand_types, proxs):
                solver_sparse = SVRG(step=step, tol=tol, max_iter=max_iter,
                                     verbose=False,
                                     variance_reduction=variance_reduction,
                                     rand_type=rand_type, seed=seed) \
                    .set_model(model_spars) \
                    .set_prox(prox)

                solver_dense = SVRG(step=step, tol=tol, max_iter=max_iter,
                                    verbose=False,
                                    variance_reduction=variance_reduction,
                                    rand_type=rand_type, seed=seed) \
                    .set_model(model_dense) \
                    .set_prox(prox)

                solver_sparse.solve()
                solver_dense.solve()
                np.testing.assert_array_almost_equal(solver_sparse.solution,
                                                     solver_dense.solution, 7)
예제 #5
0
    def test_solver_sdca(self):
        """...Check SDCA solver for a Logistic regression with Ridge
        penalization and L1 penalization
        """
        solver = SDCA(l_l2sq=1e-5, max_iter=100, verbose=False, tol=0)
        self.check_solver(solver,
                          fit_intercept=False,
                          model="logreg",
                          decimal=1)

        # Now a specific test with a real prox for SDCA
        np.random.seed(12)
        n_samples = Test.n_samples
        n_features = Test.n_features

        for fit_intercept in [True, False]:
            y, X, coeffs0, interc0 = TestSolver.generate_logistic_data(
                n_features, n_samples)

            model = ModelLogReg(fit_intercept=fit_intercept).fit(X, y)
            ratio = 0.5
            l_enet = 1e-2

            # SDCA "elastic-net" formulation is different from elastic-net
            # implementation
            l_l2_sdca = ratio * l_enet
            l_l1_sdca = (1 - ratio) * l_enet
            sdca = SDCA(l_l2sq=l_l2_sdca,
                        max_iter=100,
                        verbose=False,
                        tol=0,
                        seed=Test.sto_seed).set_model(model)
            prox_l1 = ProxL1(l_l1_sdca)
            sdca.set_prox(prox_l1)
            coeffs_sdca = sdca.solve()

            # Compare with SVRG
            svrg = SVRG(max_iter=100, verbose=False, tol=0,
                        seed=Test.sto_seed).set_model(model)
            prox_enet = ProxElasticNet(l_enet, ratio)
            svrg.set_prox(prox_enet)
            coeffs_svrg = svrg.solve(step=0.1)

            np.testing.assert_allclose(coeffs_sdca, coeffs_svrg)
예제 #6
0
    def test_solver_gfb(self):
        """...Check GFB's solver for a Logistic Regression with ElasticNet
        penalization

        Notes
        -----
        Using GFB solver with l1 and l2 penalizations is obviously a bad
        idea as ElasticNet prox is meant to do this, but it allows us to
        compare with another algorithm.
        """
        n_samples = 200
        n_features = 10
        y, X, w, c = Test.generate_logistic_data(n_features=n_features,
                                                 n_samples=n_samples)
        strength = 1e-3
        ratio = 0.3
        prox_elasticnet = ProxElasticNet(strength, ratio)
        prox_l1 = ProxL1(strength * ratio)
        prox_l2 = ProxL2Sq(strength * (1 - ratio))

        # First we get GFB solution with prox l1 and prox l2
        gfb = GFB(tol=1e-13, max_iter=1000, verbose=False, step=1)
        Test.prepare_solver(gfb, X, y, prox=None)
        gfb.set_prox([prox_l1, prox_l2])
        gfb_solution = gfb.solve()

        # Then we get AGD solution with prox ElasticNet
        agd = AGD(tol=1e-13,
                  max_iter=1000,
                  verbose=False,
                  step=0.5,
                  linesearch=False)
        Test.prepare_solver(agd, X, y, prox=prox_elasticnet)
        agd_solution = agd.solve()

        # Finally we assert that both algorithms lead to the same solution
        np.testing.assert_almost_equal(gfb_solution, agd_solution, decimal=1)
예제 #7
0
import numpy as np
import matplotlib.pyplot as plt
from tick.optim.prox import ProxL1

x = 0.5 * np.random.randn(50)
a, b = x.min() - 1e-1, x.max() + 1e-1

proxs = [
    ProxL1(strength=0.),
    ProxL1(strength=3e-1),
    ProxL1(strength=3e-1, range=(10, 40)),
    ProxL1(strength=3e-1, positive=True),
    ProxL1(strength=3e-1, range=(10, 40), positive=True),
]

names = [
    "original vector",
    "prox",
    "prox with range=(10, 40)",
    "prox with positive=True",
    "range=(10, 40) and positive=True",
]

_, ax_list = plt.subplots(1, 5, figsize=(20, 4), sharey=True)

for prox, name, ax in zip(proxs, names, ax_list):
    ax.stem(prox.call(x))
    ax.set_title(name)
    ax.set_xlim((-1, 51))
    ax.set_ylim((a, b))
예제 #8
0
"""

import numpy as np
import matplotlib.pyplot as plt
from tick.optim.prox import ProxL1, ProxElasticNet, ProxL2Sq, \
    ProxPositive, ProxSlope, ProxTV, ProxZero

x = np.random.randn(50)
a, b = x.min() - 1e-1, x.max() + 1e-1
s = 0.4

proxs = [
    ProxZero(),
    ProxPositive(),
    ProxL2Sq(strength=s),
    ProxL1(strength=s),
    ProxElasticNet(strength=s, ratio=0.5),
    ProxSlope(strength=s),
    ProxTV(strength=s)
]

fig, _ = plt.subplots(2, 4, figsize=(16, 8), sharey=True, sharex=True)
fig.axes[0].stem(x)
fig.axes[0].set_title("original vector", fontsize=16)
fig.axes[0].set_xlim((-1, 51))
fig.axes[0].set_ylim((a, b))

for i, prox in enumerate(proxs):
    fig.axes[i + 1].stem(prox.call(x))
    fig.axes[i + 1].set_title(prox.name, fontsize=16)
    fig.axes[i + 1].set_xlim((-1, 51))
예제 #9
0
import numpy as np
import matplotlib.pyplot as plt
from tick.optim.prox import ProxL1, ProxTV, ProxMulti

s = 0.4

prox = ProxMulti(proxs=(ProxTV(strength=s, range=(0, 20)),
                        ProxL1(strength=2 * s, range=(20, 50))))

x = np.random.randn(50)
a, b = x.min() - 1e-1, x.max() + 1e-1

plt.figure(figsize=(8, 4))
plt.subplot(1, 2, 1)
plt.stem(x)
plt.title("original vector", fontsize=16)
plt.xlim((-1, 51))
plt.ylim((a, b))
plt.subplot(1, 2, 2)
plt.stem(prox.call(x))
plt.title("ProxMulti: TV and L1", fontsize=16)
plt.xlim((-1, 51))
plt.ylim((a, b))
plt.vlines(20, a, b, linestyles='dashed')
plt.tight_layout()
plt.show()