Skip to content

Commit

Permalink
fixed unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
iskandr committed Jan 5, 2016
1 parent acc8042 commit c2b1e95
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 36 deletions.
7 changes: 5 additions & 2 deletions experiments/complete_faces.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def save_images(
images,
base_filename,
imshape=(64, 64),
image_indices=[0, 100, 200, 300],
image_indices=[0, 50, 100, 150, 200, 250, 300, 350],
dirname="face_images"):
if not exists(dirname):
mkdir(dirname)
Expand All @@ -57,7 +57,10 @@ def save_images(
image[np.isnan(image)] = 0
ax.imshow(image, cmap="gray")
filename = base_filename + "_%d" % (i) + ".png"
path = join(dirname, filename)
subdir = join(dirname, str(i))
if not exists(subdir):
mkdir(subdir)
path = join(subdir, filename)
fig.savefig(path)
paths.append(path)
return paths
Expand Down
6 changes: 3 additions & 3 deletions fancyimpute/auto_encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def __init__(
batch_size=32,
l1_penalty=0,
l2_penalty=0,
recurrent_weight=0.5,
output_history_size=5,
patience_epochs=10,
recurrent_weight=0.1,
output_history_size=10,
patience_epochs=None,
min_improvement=0.995,
max_training_epochs=None,
init_fill_method="zero",
Expand Down
16 changes: 8 additions & 8 deletions fancyimpute/matrix_factorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ def __init__(
self,
rank=10,
initializer=np.random.randn,
learning_rate=0.01,
patience=3,
l1_penalty_weight=0.005,
l2_penalty_weight=0.005,
learning_rate=0.001,
patience=5,
l1_penalty=0.005,
l2_penalty=0.005,
min_improvement=0.005,
max_gradient_norm=10,
optimization_algorithm="adam",
Expand All @@ -59,8 +59,8 @@ def __init__(
self.initializer = initializer
self.learning_rate = learning_rate
self.patience = patience
self.l1_penalty_weight = l1_penalty_weight
self.l2_penalty_weight = l2_penalty_weight
self.l1_penalty = l1_penalty
self.l2_penalty = l2_penalty
self.max_gradient_norm = max_gradient_norm
self.optimization_algorithm = optimization_algorithm
self.min_improvement = min_improvement
Expand Down Expand Up @@ -88,8 +88,8 @@ def solve(self, X, missing_mask):
mse = err.mean()
loss = (
mse +
self.l1_penalty_weight * abs(U).mean() +
self.l2_penalty_weight * (V * V).mean()
self.l1_penalty * abs(U).mean() +
self.l2_penalty * (V * V).mean()
)
downhill.minimize(
loss=loss,
Expand Down
21 changes: 9 additions & 12 deletions fancyimpute/nuclear_norm_minimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from __future__ import absolute_import, print_function, division

import cvxpy
import numpy as np

from .solver import Solver

Expand All @@ -27,7 +26,7 @@ class NuclearNormMinimization(Solver):
def __init__(
self,
require_symmetric_solution=False,
normalize_columns=True,
normalize_columns=False,
min_value=None,
max_value=None,
error_tolerance=0.0,
Expand All @@ -43,23 +42,20 @@ def __init__(
self.fast_but_approximate = fast_but_approximate
self.verbose = verbose

def _constraints(self, X, S, error_tolerance):
def _constraints(self, X, missing_mask, S, error_tolerance):
"""
Parameters
----------
X : np.array
Data matrix with missing values
Data matrix with missing values filled in
missing_mask : np.array
Boolean array indicating where missing values were
S : cvxpy.Variable
Representation of solution variable
"""
missing_values = np.isnan(X)
self._check_missing_value_mask(missing_values)
# copy the array before modifying it
X = X.copy()
# zero out the NaN values
X[missing_values] = 0
ok_mask = ~missing_values

ok_mask = ~missing_mask
masked_X = cvxpy.mul_elemwise(ok_mask, X)
masked_S = cvxpy.mul_elemwise(ok_mask, S)
abs_diff = cvxpy.abs(masked_S - masked_X)
Expand Down Expand Up @@ -96,6 +92,7 @@ def solve(self, X, missing_mask):
S, objective = self._create_objective(m, n)
constraints = self._constraints(
X=X,
missing_mask=missing_mask,
S=S,
error_tolerance=self.error_tolerance)
problem = cvxpy.Problem(objective, constraints)
Expand Down
1 change: 1 addition & 0 deletions fancyimpute/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ def project_result(
of actual values. Undo these transformations and clip values to
fall within any global or column-wise min/max constraints.
"""
X = np.asarray(X)
if column_scales is not None:
X *= column_scales

Expand Down
6 changes: 4 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
if __name__ == '__main__':
setup(
name='fancyimpute',
version="0.0.3",
version="0.0.4",
description="Matrix completion and feature imputation algorithms",
author="Alex Rubinsteyn and Sergey Feldman",
author_email="alex {dot} rubinsteyn {at} mssm {dot} edu",
Expand All @@ -53,7 +53,9 @@
install_requires=[
'six',
'numpy>=1.7',
'cvxpy'
'scipy',
'cvxpy',
'scikit-learn',
],
long_description=readme,
packages=['fancyimpute'],
Expand Down
15 changes: 7 additions & 8 deletions test/test_auto_encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,22 @@ def test_auto_encoder_with_low_rank_random_matrix():
solver = AutoEncoder(
hidden_layer_sizes=None,
hidden_activation="tanh",
optimizer="adam")
optimizer="adam",
recurrent_weight=0.0)
XY_completed = solver.complete(
XY_incomplete,
X_complete=XY)
XY_incomplete)
_, missing_mae = reconstruction_error(XY, XY_completed, missing_mask)
assert missing_mae < 0.1, "Error too high!"


def test_auto_encoder_with_low_rank_random_matrix_using_hallucination():
solver = AutoEncoder(
hidden_layer_sizes=None,
hidden_layer_sizes=[3],
hidden_activation="tanh",
optimizer="adam")
optimizer="adam",
recurrent_weight=0.5)
XY_completed = solver.complete(
XY_incomplete,
X_complete=XY,
hallucination_weight=1.0)
XY_incomplete)
_, missing_mae = reconstruction_error(XY, XY_completed, missing_mask)
assert missing_mae < 0.1, "Error too high!"

Expand Down
6 changes: 5 additions & 1 deletion test/test_matrix_factorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@


def test_matrix_factorization_with_low_rank_random_matrix():
solver = MatrixFactorization(k=3, l1_penalty_weight=0, l2_penalty_weight=0)
solver = MatrixFactorization(
rank=3,
l1_penalty=0,
l2_penalty=0,
normalize_columns=False)
XY_completed = solver.complete(XY_incomplete)
_, missing_mae = reconstruction_error(
XY,
Expand Down

0 comments on commit c2b1e95

Please sign in to comment.