Skip to content

Commit 4156b87

Browse files
committed
Merge remote-tracking branch 'origin/dev' into chp_add_rand_state_ddpm
2 parents 29b13cf + edaf2d3 commit 4156b87

File tree

10 files changed

+105
-49
lines changed

10 files changed

+105
-49
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,14 @@ jobs:
2727
with:
2828
python-version: ${{matrix.python-version}}
2929
environment-file: environment.ci.yml
30-
channels: default, conda-forge
3130
- name: Lint with flake8
3231
run: |
3332
conda install flake8
3433
flake8
3534
- name: Test with pytest
3635
run: |
3736
conda install pytest
38-
pytest
39-
echo you should uncomment pytest and delete this line
37+
make coverage
4038
- name: typing with mypy
4139
run: |
4240
mypy qolmat

.readthedocs.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
version: 2
22

33
build:
4-
image: latest
4+
os: "ubuntu-22.04"
5+
tools:
6+
python: "mambaforge-22.9"
57

68
python:
7-
version: 3.8
89
install:
910
- method: pip
1011
path: .

Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
coverage:
2+
pytest --cov-branch --cov=qolmat --cov-report=xml
3+
4+
doctest:
5+
pytest --doctest-modules --pyargs qolmat
6+
7+
doc:
8+
make html -C docs
9+
10+
clean:
11+
rm -rf .mypy_cache .pytest_cache .coverage*
12+
rm -rf **__pycache__
13+
make clean -C docs

environment.ci.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
name: env_qolmat_ci
22
channels:
3-
- conda-forge
43
- defaults
4+
- conda-forge
55
dependencies:
6-
- pip=23.0.1
6+
- codecov
7+
- flake8
8+
- matplotlib
9+
- mypy
10+
- numpy
11+
- numpydoc
12+
- pytest
13+
- pytest-cov
14+
- pytest-mock
15+
- pip
716
- pip:
8-
- codecov
9-
- flake8
10-
- matplotlib
11-
- mypy
12-
- numpy
13-
- numpydoc
14-
- pytest
15-
- pytest-cov
16-
- pytest-mock
17-
- torch==2.0.1
18-
- -e .
17+
- torch
18+
- -e .

qolmat/imputations/em_sampler.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,16 @@ def fit(self, X: NDArray) -> Self:
326326
self.p = p
327327
self.fit_X(X)
328328
n1, n2 = self.X.shape
329-
aic = np.log(np.linalg.det(self.S)) + 2 * p * (n2**2) / n1
329+
det = np.linalg.det(self.S)
330+
if abs(det) < 1e-12:
331+
aic = -np.inf
332+
else:
333+
aic = np.log(det) + 2 * p * (n2**2) / n1
330334
if len(aics) > 0 and aic > aics[-1]:
331335
break
332336
aics.append(aic)
337+
if aic == -np.inf:
338+
break
333339
self.p = int(np.argmin(aics))
334340
self.fit_X(X)
335341

@@ -352,15 +358,15 @@ def transform(self, X: NDArray) -> NDArray:
352358
NDArray
353359
Final array after EM sampling.
354360
"""
361+
mask_na = np.isnan(X)
362+
355363
# shape_original = X.shape
356364
if hash(X.tobytes()) == self.hash_fit:
357365
X = self.X
358366
else:
359367
X = utils.prepare_data(X, self.period)
360368
X = utils.linear_interpolation(X)
361369

362-
mask_na = np.isnan(X)
363-
364370
if self.method == "mle":
365371
X_transformed = self._maximize_likelihood(X, mask_na)
366372
elif self.method == "sample":
@@ -664,14 +670,19 @@ class VARpEM(EM):
664670
Examples
665671
--------
666672
>>> import numpy as np
667-
>>> import pandas as pd
668673
>>> from qolmat.imputations.em_sampler import VARpEM
669-
>>> imputer = VARpEM(method="sample")
670-
>>> X = pd.DataFrame(data=[[1, 1, 1, 1],
671-
>>> [np.nan, np.nan, 3, 2],
672-
>>> [1, 2, 2, 1], [2, 2, 2, 2]],
673-
>>> columns=["var1", "var2", "var3", "var4"])
674+
>>> imputer = VARpEM(method="sample", random_state=11)
675+
>>> X = np.array([[1, 1, 1, 1],
676+
... [np.nan, np.nan, 3, 2],
677+
... [1, 2, 2, 1], [2, 2, 2, 2]])
674678
>>> imputer.fit_transform(X)
679+
EM converged after 9 iterations.
680+
EM converged after 20 iterations.
681+
EM converged after 13 iterations.
682+
array([[1. , 1. , 1. , 1. ],
683+
[1.17054054, 1.49986137, 3. , 2. ],
684+
[1. , 2. , 2. , 1. ],
685+
[2. , 2. , 2. , 2. ]])
675686
"""
676687

677688
def __init__(
@@ -837,6 +848,7 @@ def combine_parameters(self) -> None:
837848
stack_YY = np.stack(list_YY)
838849
self.YY = np.mean(stack_YY, axis=0)
839850
self.S = self.YY - self.ZY.T @ self.B - self.B.T @ self.ZY + self.B.T @ self.ZZ @ self.B
851+
self.S[self.S < 1e-12] = 0
840852
self.S_inv = np.linalg.pinv(self.S, rcond=1e-10)
841853

842854
def _check_convergence(self) -> bool:

qolmat/imputations/imputers.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,10 +1114,10 @@ class ImputerResiduals(_Imputer):
11141114
11151115
Examples
11161116
--------
1117-
TODO review/remake this exemple
11181117
>>> import numpy as np
11191118
>>> import pandas as pd
1120-
>>> from qolmat.imputations.models import ImputeOnResiduals
1119+
>>> from qolmat.imputations.imputers import ImputerResiduals
1120+
>>> np.random.seed(100)
11211121
>>> df = pd.DataFrame(index=pd.date_range('2015-01-01','2020-01-01'))
11221122
>>> mean = 5
11231123
>>> offset = 10
@@ -1127,11 +1127,24 @@ class ImputerResiduals(_Imputer):
11271127
>>> noise_mean = 0
11281128
>>> noise_var = 2
11291129
>>> df['y'] = df['y'] + np.random.normal(noise_mean, noise_var, df.shape[0])
1130-
>>> np.random.seed(100)
11311130
>>> mask = np.random.choice([True, False], size=df.shape)
11321131
>>> df = df.mask(mask)
1133-
>>> imputor = ImputeOnResiduals(period=365, model="additive")
1132+
>>> imputor = ImputerResiduals(period=365, model_tsa="additive")
11341133
>>> imputor.fit_transform(df)
1134+
y
1135+
2015-01-01 1.501210
1136+
2015-01-02 5.691061
1137+
2015-01-03 4.404106
1138+
2015-01-04 3.531540
1139+
2015-01-05 3.129532
1140+
... ...
1141+
2019-12-28 10.288054
1142+
2019-12-29 10.632659
1143+
2019-12-30 14.900671
1144+
2019-12-31 12.957837
1145+
2020-01-01 12.780517
1146+
<BLANKLINE>
1147+
[1827 rows x 1 columns]
11351148
"""
11361149

11371150
def __init__(
@@ -1353,10 +1366,10 @@ class ImputerMICE(_Imputer):
13531366
... columns=["var1", "var2", "var3", "var4"])
13541367
>>> imputer.fit_transform(df)
13551368
var1 var2 var3 var4
1356-
0 1.0 1.0 1.0 1.0
1357-
1 1.0 2.0 2.0 5.0
1358-
2 1.0 2.0 2.0 5.0
1359-
3 2.0 2.0 2.0 2.0
1369+
0 1.00 1.00 1.00 1.00
1370+
1 1.51 1.99 1.99 3.55
1371+
2 1.00 2.00 2.00 5.00
1372+
3 2.00 2.00 2.00 2.00
13601373
"""
13611374

13621375
def __init__(
@@ -1470,18 +1483,18 @@ class ImputerRegressor(_Imputer):
14701483
>>> import pandas as pd
14711484
>>> from qolmat.imputations import imputers
14721485
>>> from sklearn.ensemble import ExtraTreesRegressor
1473-
>>> imputer = imputers.ImputerRegressor(model=ExtraTreesRegressor())
1486+
>>> imputer = imputers.ImputerRegressor(estimator=ExtraTreesRegressor())
14741487
>>> df = pd.DataFrame(data=[[1, 1, 1, 1],
14751488
... [np.nan, np.nan, np.nan, np.nan],
14761489
... [1, 2, 2, 5],
14771490
... [2, 2, 2, 2]],
14781491
... columns=["var1", "var2", "var3", "var4"])
14791492
>>> imputer.fit_transform(df)
1480-
var1 var2 var3 var4
1481-
0 1.000000 1.000000 1.000000 1.000000
1482-
1 1.333333 1.666667 1.666667 2.666667
1483-
2 1.000000 2.000000 2.000000 5.000000
1484-
3 2.000000 2.000000 2.000000 2.000000
1493+
var1 var2 var3 var4
1494+
0 1.0 1.0 1.0 1.0
1495+
1 1.0 2.0 2.0 2.0
1496+
2 1.0 2.0 2.0 5.0
1497+
3 2.0 2.0 2.0 2.0
14851498
"""
14861499

14871500
def __init__(

qolmat/imputations/imputers_pytorch.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -471,12 +471,10 @@ def build_autoencoder(
471471
472472
Examples
473473
--------
474-
>>> encoder, decoder = build_autoencoder(
475-
input_dim=10,
476-
latent_dim=4,
477-
list_num_neurons=[32, 64, 128],
478-
output_dim=252
479-
)
474+
>>> encoder, decoder = build_autoencoder(input_dim=10,
475+
... latent_dim=4,
476+
... list_num_neurons=[32, 64, 128],
477+
... output_dim=252)
480478
>>> print(encoder)
481479
Sequential(
482480
(0): Linear(in_features=10, out_features=128, bias=True)

qolmat/imputations/softimpute.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,12 @@ class SoftImpute(BaseEstimator, TransformerMixin):
4646
>>> import numpy as np
4747
>>> from qolmat.imputations.softimpute import SoftImpute
4848
>>> X = np.array([[1, 2, np.nan, 4], [1, 5, 3, np.nan], [4, 2, 3, 2], [1, 1, 5, 4]])
49-
>>> X_imputed = SoftImpute().fit_transform(X)
49+
>>> X_imputed = SoftImpute(random_state=11).fit_transform(X)
5050
>>> print(X_imputed)
51+
[[1. 2. 3.7242757 4. ]
52+
[1. 5. 3. 1.97846028]
53+
[4. 2. 3. 2. ]
54+
[1. 1. 5. 4. ]]
5155
"""
5256

5357
def __init__(

tests/imputations/test_em_sampler.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,22 @@ def test_parameters_after_imputation_varpem(p: int):
306306
np.testing.assert_allclose(em.S, S, rtol=1e-1, atol=1e-1)
307307

308308

309+
def test_varpem_fit_transform():
310+
imputer = em_sampler.VARpEM(method="sample", random_state=11)
311+
X = np.array([[1, 1, 1, 1], [np.nan, np.nan, 3, 2], [1, 2, 2, 1], [2, 2, 2, 2]])
312+
result = imputer.fit_transform(X)
313+
expected = np.array(
314+
[
315+
[1.0, 1.0, 1.0, 1.0],
316+
[1.0, 1.5, 3.0, 2.0],
317+
[1.0, 2.0, 2.0, 1.0],
318+
[2.0, 2.0, 2.0, 2.0],
319+
]
320+
)
321+
np.testing.assert_allclose(result, expected, atol=1e-12)
322+
# assert False
323+
324+
309325
@pytest.mark.parametrize(
310326
"X, em, p",
311327
[(X_first_guess, em_sampler.MultiNormalEM(), 0), (X_first_guess, em_sampler.VARpEM(p=2), 2)],

tests/imputations/test_imputers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,10 @@ def test_ImputerEM_fit_transform(df: pd.DataFrame) -> None:
297297
expected = pd.DataFrame(
298298
{
299299
"col1": [i for i in range(20)],
300-
"col2": [0, 0.773, 2, 2.621, 2] + [i for i in range(5, 20)],
300+
"col2": [0, 0.638, 2, 2.714, 2] + [i for i in range(5, 20)],
301301
}
302302
)
303+
print(result)
303304
np.testing.assert_allclose(result, expected, atol=1e-2)
304305

305306

0 commit comments

Comments
 (0)