nkululeko 0.95.0__py3-none-any.whl → 0.95.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nkululeko/autopredict/tests/__init__.py +0 -0
- nkululeko/autopredict/tests/test_whisper_transcriber.py +122 -0
- nkululeko/balance.py +222 -0
- nkululeko/constants.py +1 -1
- nkululeko/feat_extract/feats_mld.py +13 -5
- nkululeko/feat_extract/feats_praat.py +3 -3
- nkululeko/feat_extract/{feinberg_praat.py → feats_praat_core.py} +0 -2
- nkululeko/feat_extract/tests/__init__.py +1 -0
- nkululeko/feat_extract/tests/test_feats_opensmile.py +162 -0
- nkululeko/feat_extract/tests/test_feats_praat_core.py +507 -0
- nkululeko/feature_extractor.py +5 -0
- nkululeko/modelrunner.py +15 -48
- nkululeko/models/tests/test_model_knn.py +49 -0
- nkululeko/models/tests/test_model_mlp.py +153 -0
- nkululeko/models/tests/test_model_xgb.py +33 -0
- nkululeko/optim.py +931 -0
- nkululeko/predict.py +3 -2
- nkululeko/reporting/reporter.py +12 -0
- nkululeko/test_predictor.py +7 -1
- nkululeko/tests/__init__.py +1 -0
- nkululeko/tests/test_balancing.py +270 -0
- nkululeko/tests/test_optim.py +200 -0
- nkululeko/utils/util.py +5 -5
- nkululeko-0.95.2.dist-info/METADATA +376 -0
- {nkululeko-0.95.0.dist-info → nkululeko-0.95.2.dist-info}/RECORD +29 -17
- nkululeko/feat_extract/feats_opensmile copy.py +0 -93
- nkululeko-0.95.0.dist-info/METADATA +0 -76
- {nkululeko-0.95.0.dist-info → nkululeko-0.95.2.dist-info}/WHEEL +0 -0
- {nkululeko-0.95.0.dist-info → nkululeko-0.95.2.dist-info}/entry_points.txt +0 -0
- {nkululeko-0.95.0.dist-info → nkululeko-0.95.2.dist-info}/licenses/LICENSE +0 -0
- {nkululeko-0.95.0.dist-info → nkululeko-0.95.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,153 @@
|
|
1
|
+
import numpy as np
|
2
|
+
import pandas as pd
|
3
|
+
import pytest
|
4
|
+
import torch
|
5
|
+
from unittest.mock import patch
|
6
|
+
|
7
|
+
from nkululeko.models.model_mlp import MLPModel
|
8
|
+
|
9
|
+
|
10
|
+
class DummyUtil:
|
11
|
+
def config_val(self, section, key, default=None):
|
12
|
+
# Provide defaults for required config values
|
13
|
+
if key == "manual_seed":
|
14
|
+
return True
|
15
|
+
if key == "loss":
|
16
|
+
return "cross"
|
17
|
+
if key == "device":
|
18
|
+
return "cpu"
|
19
|
+
if key == "learning_rate":
|
20
|
+
return 0.001
|
21
|
+
if key == "batch_size":
|
22
|
+
return 2
|
23
|
+
if key == "drop":
|
24
|
+
return False
|
25
|
+
return default
|
26
|
+
def debug(self, msg): pass
|
27
|
+
def error(self, msg): raise Exception(msg)
|
28
|
+
def get_path(self, key): return "./"
|
29
|
+
def get_exp_name(self, only_train=False): return "exp"
|
30
|
+
|
31
|
+
@pytest.fixture(autouse=True)
|
32
|
+
def patch_globals(monkeypatch):
|
33
|
+
# Patch global config and labels
|
34
|
+
import nkululeko.glob_conf as glob_conf
|
35
|
+
glob_conf.config = {
|
36
|
+
"DATA": {"target": "label"},
|
37
|
+
"MODEL": {"layers": "{'a': 8, 'b': 4}"}
|
38
|
+
}
|
39
|
+
glob_conf.labels = [0, 1]
|
40
|
+
yield
|
41
|
+
|
42
|
+
@pytest.fixture
|
43
|
+
def dummy_data():
|
44
|
+
# 4 samples, 3 features
|
45
|
+
feats_train = pd.DataFrame(np.random.rand(4, 3), columns=['f1', 'f2', 'f3'])
|
46
|
+
feats_test = pd.DataFrame(np.random.rand(2, 3), columns=['f1', 'f2', 'f3'])
|
47
|
+
df_train = pd.DataFrame({'label': [0, 1, 0, 1]})
|
48
|
+
df_test = pd.DataFrame({'label': [1, 0]})
|
49
|
+
return df_train, df_test, feats_train, feats_test
|
50
|
+
|
51
|
+
@pytest.fixture
|
52
|
+
def mlp_model(dummy_data, monkeypatch):
|
53
|
+
df_train, df_test, feats_train, feats_test = dummy_data
|
54
|
+
with patch.object(MLPModel, "__init__", return_value=None):
|
55
|
+
model = MLPModel(df_train, df_test, feats_train, feats_test)
|
56
|
+
model.util = DummyUtil()
|
57
|
+
model.n_jobs = 1
|
58
|
+
model.target = "label"
|
59
|
+
model.class_num = 2
|
60
|
+
model.criterion = torch.nn.CrossEntropyLoss()
|
61
|
+
model.device = "cpu"
|
62
|
+
model.learning_rate = 0.001
|
63
|
+
model.batch_size = 2
|
64
|
+
model.num_workers = 1
|
65
|
+
model.loss = 0.0
|
66
|
+
model.loss_eval = 0.0
|
67
|
+
model.run = 0
|
68
|
+
model.epoch = 0
|
69
|
+
model.df_test = df_test
|
70
|
+
model.feats_test = feats_test
|
71
|
+
model.feats_train = feats_train
|
72
|
+
|
73
|
+
# Create a simple MLP model for testing
|
74
|
+
model.model = MLPModel.MLP(3, {'a': 8, 'b': 4}, 2, False).to("cpu")
|
75
|
+
model.optimizer = torch.optim.Adam(model.model.parameters(), lr=0.001)
|
76
|
+
|
77
|
+
# Create data loaders
|
78
|
+
model.trainloader = model.get_loader(feats_train, df_train, True)
|
79
|
+
model.testloader = model.get_loader(feats_test, df_test, False)
|
80
|
+
model.store_path = "/tmp/test_model.pt"
|
81
|
+
|
82
|
+
return model
|
83
|
+
|
84
|
+
def test_mlpmodel_init(mlp_model):
|
85
|
+
assert hasattr(mlp_model, "model")
|
86
|
+
assert hasattr(mlp_model, "trainloader")
|
87
|
+
assert hasattr(mlp_model, "testloader")
|
88
|
+
assert mlp_model.model is not None
|
89
|
+
|
90
|
+
def test_train_and_predict(mlp_model):
|
91
|
+
mlp_model.train()
|
92
|
+
report = mlp_model.predict()
|
93
|
+
assert hasattr(report, "result")
|
94
|
+
assert hasattr(report.result, "train")
|
95
|
+
|
96
|
+
def test_get_predictions(mlp_model):
|
97
|
+
mlp_model.train()
|
98
|
+
preds = mlp_model.get_predictions()
|
99
|
+
assert isinstance(preds, np.ndarray)
|
100
|
+
assert preds.shape[0] == 2
|
101
|
+
|
102
|
+
def test_get_probas(mlp_model):
|
103
|
+
mlp_model.train()
|
104
|
+
_, _, _, logits = mlp_model.evaluate(mlp_model.model, mlp_model.testloader, mlp_model.device)
|
105
|
+
probas = mlp_model.get_probas(logits)
|
106
|
+
assert isinstance(probas, pd.DataFrame)
|
107
|
+
assert set(probas.columns) == set([0, 1])
|
108
|
+
|
109
|
+
def test_predict_sample(mlp_model):
|
110
|
+
mlp_model.train()
|
111
|
+
feats = np.random.rand(3)
|
112
|
+
res = mlp_model.predict_sample(feats)
|
113
|
+
assert isinstance(res, dict)
|
114
|
+
assert set(res.keys()) == set([0, 1])
|
115
|
+
|
116
|
+
def test_predict_shap(mlp_model):
|
117
|
+
mlp_model.train()
|
118
|
+
feats = pd.DataFrame(np.random.rand(2, 3))
|
119
|
+
results = mlp_model.predict_shap(feats)
|
120
|
+
assert len(results) == 2
|
121
|
+
|
122
|
+
def test_store_and_load(tmp_path, mlp_model, monkeypatch):
|
123
|
+
mlp_model.train()
|
124
|
+
|
125
|
+
# Mock the util methods that load() uses to construct the path
|
126
|
+
def mock_get_path(key):
|
127
|
+
if key == "model_dir":
|
128
|
+
return str(tmp_path) + "/"
|
129
|
+
return "./"
|
130
|
+
|
131
|
+
def mock_get_exp_name(only_train=False):
|
132
|
+
return "model"
|
133
|
+
|
134
|
+
mlp_model.util.get_path = mock_get_path
|
135
|
+
mlp_model.util.get_exp_name = mock_get_exp_name
|
136
|
+
|
137
|
+
# Set store path to match what load() will construct
|
138
|
+
mlp_model.store_path = str(tmp_path) + "/model_0_000.model"
|
139
|
+
mlp_model.store()
|
140
|
+
|
141
|
+
# Simulate loading
|
142
|
+
mlp_model.load(0, 0)
|
143
|
+
assert mlp_model.model is not None
|
144
|
+
|
145
|
+
def test_set_testdata(mlp_model, dummy_data):
|
146
|
+
_, df_test, _, feats_test = dummy_data
|
147
|
+
mlp_model.set_testdata(df_test, feats_test)
|
148
|
+
assert mlp_model.testloader is not None
|
149
|
+
|
150
|
+
def test_reset_test(mlp_model, dummy_data):
|
151
|
+
_, df_test, _, feats_test = dummy_data
|
152
|
+
mlp_model.reset_test(df_test, feats_test)
|
153
|
+
assert mlp_model.testloader is not None
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
import pytest
|
3
|
+
|
4
|
+
from ..model_xgb import XGB_model
|
5
|
+
|
6
|
+
|
7
|
+
class DummyUtil:
|
8
|
+
def config_val(self, section, key, default):
|
9
|
+
return default
|
10
|
+
def debug(self, msg):
|
11
|
+
pass
|
12
|
+
|
13
|
+
class DummyModel(XGB_model):
|
14
|
+
def __init__(self, df_train, df_test, feats_train, feats_test):
|
15
|
+
# Patch util before calling super().__init__
|
16
|
+
self.util = DummyUtil()
|
17
|
+
self.target = "label"
|
18
|
+
super().__init__(df_train, df_test, feats_train, feats_test)
|
19
|
+
self.util = DummyUtil()
|
20
|
+
self.target = "label"
|
21
|
+
|
22
|
+
@pytest.fixture
|
23
|
+
def dummy_data():
|
24
|
+
df_train = pd.DataFrame({"label": [0, 1], "f1": [1.0, 2.0]})
|
25
|
+
df_test = pd.DataFrame({"label": [0, 1], "f1": [1.5, 2.5]})
|
26
|
+
feats_train = df_train[["f1"]]
|
27
|
+
feats_test = df_test[["f1"]]
|
28
|
+
return df_train, df_test, feats_train, feats_test
|
29
|
+
|
30
|
+
def test_get_type_returns_xgb(dummy_data):
|
31
|
+
df_train, df_test, feats_train, feats_test = dummy_data
|
32
|
+
model = DummyModel(df_train, df_test, feats_train, feats_test)
|
33
|
+
assert model.get_type() == "xgb"
|