nkululeko 0.83.2__py3-none-any.whl → 0.84.0__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/constants.py CHANGED
@@ -1,2 +1,2 @@
1
- VERSION="0.83.2"
1
+ VERSION="0.84.0"
2
2
  SAMPLING_RATE = 16000
nkululeko/demo.py CHANGED
@@ -2,8 +2,9 @@
2
2
  # Demonstration code to use the ML-experiment framework
3
3
  # Test the loading of a previously trained model and demo mode
4
4
  # needs the project config file to run before
5
- """
6
- This script is used to test the loading of a previously trained model and run it in demo mode.
5
+ """This script is used to test the loading of a previously trained model.
6
+
7
+ And run it in demo mode.
7
8
  It requires the project config file to be run before.
8
9
 
9
10
  Usage:
@@ -20,17 +21,15 @@ import argparse
20
21
  import configparser
21
22
  import os
22
23
 
23
- import nkululeko.glob_conf as glob_conf
24
24
  from nkululeko.constants import VERSION
25
25
  from nkululeko.experiment import Experiment
26
+ import nkululeko.glob_conf as glob_conf
26
27
  from nkululeko.utils.util import Util
27
28
 
28
29
 
29
30
  def main(src_dir):
30
- parser = argparse.ArgumentParser(
31
- description="Call the nkululeko DEMO framework.")
32
- parser.add_argument("--config", default="exp.ini",
33
- help="The base configuration")
31
+ parser = argparse.ArgumentParser(description="Call the nkululeko DEMO framework.")
32
+ parser.add_argument("--config", default="exp.ini", help="The base configuration")
34
33
  parser.add_argument(
35
34
  "--file", help="A file that should be processed (16kHz mono wav)"
36
35
  )
@@ -1,18 +1,19 @@
1
1
  # demo_predictor.py
2
2
  import os
3
3
 
4
- import audformat
5
- import audiofile
6
4
  import numpy as np
7
5
  import pandas as pd
8
6
 
7
+ import audformat
8
+ import audiofile
9
+
9
10
  import nkululeko.glob_conf as glob_conf
10
11
  from nkululeko.utils.util import Util
11
12
 
12
13
 
13
14
  class Demo_predictor:
14
15
  def __init__(self, model, file, is_list, feature_extractor, label_encoder, outfile):
15
- """Constructor setting up name and configuration"""
16
+ """Constructor setting up name and configuration."""
16
17
  self.model = model
17
18
  self.feature_extractor = feature_extractor
18
19
  self.label_encoder = label_encoder
nkululeko/experiment.py CHANGED
@@ -5,20 +5,22 @@ import pickle
5
5
  import random
6
6
  import time
7
7
 
8
- import audeer
9
- import audformat
10
8
  import numpy as np
11
9
  import pandas as pd
12
10
  from sklearn.preprocessing import LabelEncoder
13
11
 
14
- import nkululeko.glob_conf as glob_conf
12
+ import audeer
13
+ import audformat
14
+
15
15
  from nkululeko.data.dataset import Dataset
16
16
  from nkululeko.data.dataset_csv import Dataset_CSV
17
17
  from nkululeko.demo_predictor import Demo_predictor
18
18
  from nkululeko.feat_extract.feats_analyser import FeatureAnalyser
19
19
  from nkululeko.feature_extractor import FeatureExtractor
20
20
  from nkululeko.file_checker import FileChecker
21
- from nkululeko.filter_data import DataFilter, filter_min_dur
21
+ from nkululeko.filter_data import DataFilter
22
+ from nkululeko.filter_data import filter_min_dur
23
+ import nkululeko.glob_conf as glob_conf
22
24
  from nkululeko.plots import Plots
23
25
  from nkululeko.reporting.report import Report
24
26
  from nkululeko.runmanager import Runmanager
@@ -101,6 +103,7 @@ class Experiment:
101
103
  self.got_speaker = True
102
104
  self.datasets.update({d: data})
103
105
  self.target = self.util.config_val("DATA", "target", "emotion")
106
+ glob_conf.set_target(self.target)
104
107
  # print target via debug
105
108
  self.util.debug(f"target: {self.target}")
106
109
  # print keys/column
@@ -487,11 +490,7 @@ class Experiment:
487
490
  return df_ret
488
491
 
489
492
  def analyse_features(self, needs_feats):
490
- """
491
- Do a feature exploration
492
-
493
- """
494
-
493
+ """Do a feature exploration."""
495
494
  plot_feats = eval(
496
495
  self.util.config_val("EXPL", "feature_distributions", "False")
497
496
  )
@@ -511,7 +510,7 @@ class Experiment:
511
510
  f"unknown sample selection specifier {sample_selection}, should"
512
511
  " be [all | train | test]"
513
512
  )
514
-
513
+ self.util.debug(f"sampling selection: {sample_selection}")
515
514
  if self.util.config_val("EXPL", "value_counts", False):
516
515
  self.plot_distribution(df_labels)
517
516
 
@@ -537,9 +536,13 @@ class Experiment:
537
536
  f"unknown sample selection specifier {sample_selection}, should"
538
537
  " be [all | train | test]"
539
538
  )
539
+ feat_analyser = FeatureAnalyser(sample_selection, df_labels, df_feats)
540
+ # check if SHAP features should be analysed
541
+ shap = eval(self.util.config_val("EXPL", "shap", "False"))
542
+ if shap:
543
+ feat_analyser.analyse_shap(self.runmgr.get_best_model())
540
544
 
541
545
  if plot_feats:
542
- feat_analyser = FeatureAnalyser(sample_selection, df_labels, df_feats)
543
546
  feat_analyser.analyse()
544
547
 
545
548
  # check if a scatterplot should be done
@@ -692,22 +695,26 @@ class Experiment:
692
695
  if self.runmgr.modelrunner.model.is_ann():
693
696
  self.runmgr.modelrunner.model = None
694
697
  self.util.warn(
695
- f"Save experiment: Can't pickle the learning model so saving without it."
698
+ "Save experiment: Can't pickle the trained model so saving without it. (it should be stored anyway)"
696
699
  )
697
700
  try:
698
701
  f = open(filename, "wb")
699
702
  pickle.dump(self.__dict__, f)
700
703
  f.close()
701
- except TypeError:
704
+ except (TypeError, AttributeError) as error:
702
705
  self.feature_extractor.feat_extractor.model = None
703
706
  f = open(filename, "wb")
704
707
  pickle.dump(self.__dict__, f)
705
708
  f.close()
706
709
  self.util.warn(
707
- f"Save experiment: Can't pickle the feature extraction model so saving without it."
710
+ "Save experiment: Can't pickle the feature extraction model so saving without it."
711
+ + f"{type(error).__name__} {error}"
712
+ )
713
+ except RuntimeError as error:
714
+ self.util.warn(
715
+ "Save experiment: Can't pickle local object, NOT saving: "
716
+ + f"{type(error).__name__} {error}"
708
717
  )
709
- except (AttributeError, RuntimeError) as error:
710
- self.util.warn(f"Save experiment: Can't pickle local object: {error}")
711
718
 
712
719
  def save_onnx(self, filename):
713
720
  # export the model to onnx
nkululeko/explore.py CHANGED
@@ -12,9 +12,9 @@ from nkululeko.utils.util import Util
12
12
 
13
13
  def main(src_dir):
14
14
  parser = argparse.ArgumentParser(
15
- description="Call the nkululeko EXPLORE framework.")
16
- parser.add_argument("--config", default="exp.ini",
17
- help="The base configuration")
15
+ description="Call the nkululeko EXPLORE framework."
16
+ )
17
+ parser.add_argument("--config", default="exp.ini", help="The base configuration")
18
18
  args = parser.parse_args()
19
19
  if args.config is not None:
20
20
  config_file = args.config
@@ -43,28 +43,34 @@ def main(src_dir):
43
43
  import warnings
44
44
 
45
45
  warnings.filterwarnings("ignore")
46
-
47
- # load the data
48
- expr.load_datasets()
49
-
50
- # split into train and test
51
- expr.fill_train_and_tests()
52
- util.debug(
53
- f"train shape : {expr.df_train.shape}, test shape:{expr.df_test.shape}")
54
-
55
- plot_feats = eval(util.config_val(
56
- "EXPL", "feature_distributions", "False"))
57
- tsne = eval(util.config_val("EXPL", "tsne", "False"))
58
- scatter = eval(util.config_val("EXPL", "scatter", "False"))
59
- spotlight = eval(util.config_val("EXPL", "spotlight", "False"))
60
- model_type = util.config_val("EXPL", "model", False)
61
- plot_tree = eval(util.config_val("EXPL", "plot_tree", "False"))
62
46
  needs_feats = False
63
- if plot_feats or tsne or scatter or model_type or plot_tree:
64
- # these investigations need features to explore
65
- expr.extract_feats()
47
+ try:
48
+ # load the experiment
49
+ expr.load(f"{util.get_save_name()}")
66
50
  needs_feats = True
67
- # explore
51
+ except FileNotFoundError:
52
+ # first time: load the data
53
+ expr.load_datasets()
54
+
55
+ # split into train and test
56
+ expr.fill_train_and_tests()
57
+ util.debug(
58
+ f"train shape : {expr.df_train.shape}, test shape:{expr.df_test.shape}"
59
+ )
60
+
61
+ plot_feats = eval(util.config_val("EXPL", "feature_distributions", "False"))
62
+ tsne = eval(util.config_val("EXPL", "tsne", "False"))
63
+ scatter = eval(util.config_val("EXPL", "scatter", "False"))
64
+ spotlight = eval(util.config_val("EXPL", "spotlight", "False"))
65
+ shap = eval(util.config_val("EXPL", "shap", "False"))
66
+ model_type = util.config_val("EXPL", "model", False)
67
+ plot_tree = eval(util.config_val("EXPL", "plot_tree", "False"))
68
+ needs_feats = False
69
+ if plot_feats or tsne or scatter or model_type or plot_tree or shap:
70
+ # these investigations need features to explore
71
+ expr.extract_feats()
72
+ needs_feats = True
73
+ # explore
68
74
  expr.analyse_features(needs_feats)
69
75
  expr.store_report()
70
76
  print("DONE")
@@ -40,6 +40,39 @@ class FeatureAnalyser:
40
40
  importance = model.feature_importances_
41
41
  return importance
42
42
 
43
+ def analyse_shap(self, model):
44
+ """Shap analysis.
45
+
46
+ Use the best model from a previous run and analyse feature importance with SHAP.
47
+ https://m.mage.ai/how-to-interpret-and-explain-your-machine-learning-models-using-shap-values-471c2635b78e.
48
+ """
49
+ import shap
50
+
51
+ name = "my_shap_values"
52
+ if not self.util.exist_pickle(name):
53
+
54
+ explainer = shap.Explainer(
55
+ model.predict_shap,
56
+ self.features,
57
+ output_names=glob_conf.labels,
58
+ algorithm="permutation",
59
+ npermutations=5,
60
+ )
61
+ self.util.debug("computing SHAP values...")
62
+ shap_values = explainer(self.features)
63
+ self.util.to_pickle(shap_values, name)
64
+ else:
65
+ shap_values = self.util.from_pickle(name)
66
+ plt.tight_layout()
67
+ shap.plots.bar(shap_values)
68
+ fig_dir = self.util.get_path("fig_dir") + "../" # one up because of the runs
69
+ exp_name = self.util.get_exp_name(only_data=True)
70
+ format = self.util.config_val("PLOT", "format", "png")
71
+ filename = f"_SHAP_{model.name}"
72
+ filename = f"{fig_dir}{exp_name}{filename}.{format}"
73
+ plt.savefig(filename)
74
+ self.util.debug(f"plotted SHAP feature importance tp {filename}")
75
+
43
76
  def analyse(self):
44
77
  models = ast.literal_eval(self.util.config_val("EXPL", "model", "['log_reg']"))
45
78
  model_name = "_".join(models)
@@ -1,35 +1,39 @@
1
1
  # feats_trill.py
2
- import tensorflow_hub as hub
3
2
  import os
3
+
4
+ import pandas as pd
4
5
  import tensorflow as tf
5
- from numpy.core.numeric import tensordot
6
+ import tensorflow_hub as hub
6
7
  from tqdm import tqdm
7
- import pandas as pd
8
+
8
9
  import audiofile as af
9
- from nkululeko.utils.util import Util
10
- import nkululeko.glob_conf as glob_conf
10
+
11
11
  from nkululeko.feat_extract.featureset import Featureset
12
+ import nkululeko.glob_conf as glob_conf
13
+ from nkululeko.utils.util import Util
14
+
12
15
 
13
16
  # Import TF 2.X and make sure we're running eager.
14
17
  assert tf.executing_eagerly()
15
18
 
16
19
 
17
20
  class TRILLset(Featureset):
18
- """A feature extractor for the Google TRILL embeddings"""
21
+ """A feature extractor for the Google TRILL embeddings.
19
22
 
20
- """https://ai.googleblog.com/2020/06/improving-speech-representations-and.html"""
23
+ See https://ai.googleblog.com/2020/06/improving-speech-representations-and.html.
24
+ """
21
25
 
22
26
  # Initialization of the class
23
27
  def __init__(self, name, data_df, feats_type):
24
- """
25
- Initialize the class with name, data and Util instance
26
- Also loads the model from hub
28
+ """Initialize the class with name, data and Util instance.
27
29
 
28
- :param name: Name of the class
29
- :type name: str
30
- :param data_df: Data of the class
31
- :type data_df: DataFrame
32
- :return: None
30
+ Also loads the model from hub
31
+ Args:
32
+ :param name: Name of the class
33
+ :type name: str
34
+ :param data_df: Data of the class
35
+ :type data_df: DataFrame
36
+ :return: None
33
37
  """
34
38
  super().__init__(name, data_df, feats_type)
35
39
  # Load the model from the configured path
@@ -38,25 +42,21 @@ class TRILLset(Featureset):
38
42
  "trill.model",
39
43
  "https://tfhub.dev/google/nonsemantic-speech-benchmark/trill/3",
40
44
  )
41
- self.module = hub.load(model_path)
45
+ self.model = hub.load(model_path)
42
46
  self.feats_type = feats_type
43
47
 
44
48
  def extract(self):
45
49
  store = self.util.get_path("store")
46
50
  storage = f"{store}{self.name}.pkl"
47
- extract = self.util.config_val(
48
- "FEATS", "needs_feature_extraction", False)
51
+ extract = self.util.config_val("FEATS", "needs_feature_extraction", False)
49
52
  no_reuse = eval(self.util.config_val("FEATS", "no_reuse", "False"))
50
53
  if extract or no_reuse or not os.path.isfile(storage):
51
- self.util.debug(
52
- "extracting TRILL embeddings, this might take a while...")
54
+ self.util.debug("extracting TRILL embeddings, this might take a while...")
53
55
  emb_series = pd.Series(index=self.data_df.index, dtype=object)
54
- length = len(self.data_df.index)
55
56
  for idx, file in enumerate(tqdm(self.data_df.index.get_level_values(0))):
56
- emb = self.getEmbeddings(file)
57
- emb_series[idx] = emb
58
- self.df = pd.DataFrame(
59
- emb_series.values.tolist(), index=self.data_df.index)
57
+ emb = self.get_embeddings(file)
58
+ emb_series.iloc[idx] = emb
59
+ self.df = pd.DataFrame(emb_series.values.tolist(), index=self.data_df.index)
60
60
  self.df.to_pickle(storage)
61
61
  try:
62
62
  glob_conf.config["DATA"]["needs_feature_extraction"] = "false"
@@ -70,15 +70,15 @@ class TRILLset(Featureset):
70
70
  if len(wav.shape) > 1:
71
71
  wav = tf.reduce_mean(wav, axis=0)
72
72
 
73
- emb_dict = self.module(samples=wav, sample_rate=tf.constant(16000))
73
+ emb_dict = self.model(samples=wav, sample_rate=tf.constant(16000))
74
74
  return emb_dict["embedding"]
75
75
 
76
- def getEmbeddings(self, file):
76
+ def get_embeddings(self, file):
77
77
  wav = af.read(file)[0]
78
- emb_short = self.getEmbeddings_signal(wav, 16000)
78
+ emb_short = self.get_embeddings_signal(wav, 16000)
79
79
  return emb_short
80
80
 
81
- def getEmbeddings_signal(self, signal, sr):
81
+ def get_embeddings_signal(self, signal, sr):
82
82
  wav = tf.convert_to_tensor(signal)
83
83
  emb_short = self.embed_wav(wav)
84
84
  # you get one embedding per frame, we use the mean for all the frames
@@ -86,7 +86,7 @@ class TRILLset(Featureset):
86
86
  return emb_short
87
87
 
88
88
  def extract_sample(self, signal, sr):
89
- if self.module == None:
89
+ if self.model == None:
90
90
  self.__init__("na", None)
91
- feats = self.getEmbeddings_signal(signal, sr)
91
+ feats = self.get_embeddings_signal(signal, sr)
92
92
  return feats
nkululeko/glob_conf.py CHANGED
@@ -29,3 +29,8 @@ def set_report(report_obj):
29
29
  def set_labels(labels_obj):
30
30
  global labels
31
31
  labels = labels_obj
32
+
33
+
34
+ def set_target(target_obj):
35
+ global target
36
+ target = target_obj
nkululeko/models/model.py CHANGED
@@ -20,6 +20,7 @@ class Model:
20
20
 
21
21
  def __init__(self, df_train, df_test, feats_train, feats_test):
22
22
  """Constructor taking the configuration and all dataframes."""
23
+ self.name = "undefined"
23
24
  self.df_train, self.df_test, self.feats_train, self.feats_test = (
24
25
  df_train,
25
26
  df_test,
@@ -12,3 +12,4 @@ class Bayes_model(Model):
12
12
  def __init__(self, df_train, df_test, feats_train, feats_test):
13
13
  super().__init__(df_train, df_test, feats_train, feats_test)
14
14
  self.clf = GaussianNB() # set up the classifier
15
+ self.name = "bayes"
@@ -34,7 +34,8 @@ class CNN_model(Model):
34
34
  """Constructor taking the configuration and all dataframes"""
35
35
  super().__init__(df_train, df_test, feats_train, feats_test)
36
36
  super().set_model_type("ann")
37
- self.target = glob_conf.config["DATA"]["target"]
37
+ self.name = "cnn"
38
+ self.target = glob_conf.target
38
39
  labels = glob_conf.labels
39
40
  self.class_num = len(labels)
40
41
  # set up loss criterion
@@ -86,8 +87,7 @@ class CNN_model(Model):
86
87
  train_set = self.Dataset_image(
87
88
  feats_train, df_train, self.target, transformations
88
89
  )
89
- test_set = self.Dataset_image(
90
- feats_test, df_test, self.target, transformations)
90
+ test_set = self.Dataset_image(feats_test, df_test, self.target, transformations)
91
91
  # Define data loaders
92
92
  self.trainloader = torch.utils.data.DataLoader(
93
93
  train_set,
@@ -140,8 +140,7 @@ class CNN_model(Model):
140
140
  losses = []
141
141
  for images, labels in self.trainloader:
142
142
  logits = self.model(images.to(self.device))
143
- loss = self.criterion(logits, labels.to(
144
- self.device, dtype=torch.int64))
143
+ loss = self.criterion(logits, labels.to(self.device, dtype=torch.int64))
145
144
  losses.append(loss.item())
146
145
  self.optimizer.zero_grad()
147
146
  loss.backward()
@@ -169,16 +168,14 @@ class CNN_model(Model):
169
168
 
170
169
  self.loss_eval = (np.asarray(losses)).mean()
171
170
  predictions = logits.argmax(dim=1)
172
- uar = recall_score(
173
- targets.numpy(), predictions.numpy(), average="macro")
171
+ uar = recall_score(targets.numpy(), predictions.numpy(), average="macro")
174
172
  return uar, targets, predictions
175
173
 
176
174
  def predict(self):
177
175
  _, truths, predictions = self.evaluate_model(
178
176
  self.model, self.testloader, self.device
179
177
  )
180
- uar, _, _ = self.evaluate_model(
181
- self.model, self.trainloader, self.device)
178
+ uar, _, _ = self.evaluate_model(self.model, self.trainloader, self.device)
182
179
  report = Reporter(truths, predictions, self.run, self.epoch)
183
180
  try:
184
181
  report.result.loss = self.loss
@@ -11,10 +11,9 @@ class GMM_model(Model):
11
11
 
12
12
  def __init__(self, df_train, df_test, feats_train, feats_test):
13
13
  super().__init__(df_train, df_test, feats_train, feats_test)
14
+ self.name = "gmm"
14
15
  n_components = int(self.util.config_val("MODEL", "GMM_components", "4"))
15
- covariance_type = self.util.config_val(
16
- "MODEL", "GMM_covariance_type", "full"
17
- )
16
+ covariance_type = self.util.config_val("MODEL", "GMM_covariance_type", "full")
18
17
  self.clf = mixture.GaussianMixture(
19
18
  n_components=n_components, covariance_type=covariance_type
20
19
  )
@@ -11,6 +11,7 @@ class KNN_model(Model):
11
11
 
12
12
  def __init__(self, df_train, df_test, feats_train, feats_test):
13
13
  super().__init__(df_train, df_test, feats_train, feats_test)
14
+ self.name = "knn"
14
15
  method = self.util.config_val("MODEL", "KNN_weights", "uniform")
15
16
  k = int(self.util.config_val("MODEL", "K_val", "5"))
16
17
  self.clf = KNeighborsClassifier(
@@ -11,6 +11,7 @@ class KNN_reg_model(Model):
11
11
 
12
12
  def __init__(self, df_train, df_test, feats_train, feats_test):
13
13
  super().__init__(df_train, df_test, feats_train, feats_test)
14
+ self.name = "knn_reg"
14
15
  method = self.util.config_val("MODEL", "KNN_weights", "uniform")
15
16
  k = int(self.util.config_val("MODEL", "K_val", "5"))
16
17
  self.clf = KNeighborsRegressor(
@@ -11,4 +11,5 @@ class Lin_reg_model(Model):
11
11
 
12
12
  def __init__(self, df_train, df_test, feats_train, feats_test):
13
13
  super().__init__(df_train, df_test, feats_train, feats_test)
14
+ self.name = "lin_reg"
14
15
  self.clf = LinearRegression() # set up the classifier
@@ -1,4 +1,6 @@
1
1
  # model_mlp.py
2
+ import pandas as pd
3
+
2
4
  from nkululeko.utils.util import Util
3
5
  import nkululeko.glob_conf as glob_conf
4
6
  from nkululeko.models.model import Model
@@ -20,6 +22,7 @@ class MLP_model(Model):
20
22
  """Constructor taking the configuration and all dataframes"""
21
23
  super().__init__(df_train, df_test, feats_train, feats_test)
22
24
  super().set_model_type("ann")
25
+ self.name = "mlp"
23
26
  self.target = glob_conf.config["DATA"]["target"]
24
27
  labels = glob_conf.labels
25
28
  self.class_num = len(labels)
@@ -87,8 +90,7 @@ class MLP_model(Model):
87
90
  losses = []
88
91
  for features, labels in self.trainloader:
89
92
  logits = self.model(features.to(self.device))
90
- loss = self.criterion(logits, labels.to(
91
- self.device, dtype=torch.int64))
93
+ loss = self.criterion(logits, labels.to(self.device, dtype=torch.int64))
92
94
  losses.append(loss.item())
93
95
  self.optimizer.zero_grad()
94
96
  loss.backward()
@@ -116,16 +118,14 @@ class MLP_model(Model):
116
118
 
117
119
  self.loss_eval = (np.asarray(losses)).mean()
118
120
  predictions = logits.argmax(dim=1)
119
- uar = recall_score(
120
- targets.numpy(), predictions.numpy(), average="macro")
121
+ uar = recall_score(targets.numpy(), predictions.numpy(), average="macro")
121
122
  return uar, targets, predictions
122
123
 
123
124
  def predict(self):
124
125
  _, truths, predictions = self.evaluate_model(
125
126
  self.model, self.testloader, self.device
126
127
  )
127
- uar, _, _ = self.evaluate_model(
128
- self.model, self.trainloader, self.device)
128
+ uar, _, _ = self.evaluate_model(self.model, self.trainloader, self.device)
129
129
  report = Reporter(truths, predictions, self.run, self.epoch)
130
130
  try:
131
131
  report.result.loss = self.loss
@@ -176,8 +176,18 @@ class MLP_model(Model):
176
176
  x = x.squeeze(dim=1).float()
177
177
  return self.linear(x)
178
178
 
179
+ def predict_shap(self, features):
180
+ # predict outputs for all samples in SHAP format (pd. dataframe)
181
+ results = []
182
+ for index, row in features.iterrows():
183
+ feats = row.values
184
+ res_dict = self.predict_sample(feats)
185
+ class_key = max(res_dict, key=res_dict.get)
186
+ results.append(class_key)
187
+ return results
188
+
179
189
  def predict_sample(self, features):
180
- """Predict one sample"""
190
+ """Predict one sample."""
181
191
  with torch.no_grad():
182
192
  features = torch.from_numpy(features)
183
193
  features = np.reshape(features, (-1, 1)).T
@@ -25,6 +25,7 @@ class MLP_Reg_model(Model):
25
25
  def __init__(self, df_train, df_test, feats_train, feats_test):
26
26
  """Constructor taking the configuration and all dataframes"""
27
27
  super().__init__(df_train, df_test, feats_train, feats_test)
28
+ self.name = "mlp_reg"
28
29
  super().set_model_type("ann")
29
30
  self.target = glob_conf.config["DATA"]["target"]
30
31
  labels = glob_conf.labels
@@ -52,8 +53,7 @@ class MLP_Reg_model(Model):
52
53
  drop = self.util.config_val("MODEL", "drop", False)
53
54
  if drop:
54
55
  self.util.debug(f"training with dropout: {drop}")
55
- self.model = self.MLP(
56
- feats_train.shape[1], layers, 1, drop).to(self.device)
56
+ self.model = self.MLP(feats_train.shape[1], layers, 1, drop).to(self.device)
57
57
  self.learning_rate = float(
58
58
  self.util.config_val("MODEL", "learning_rate", 0.0001)
59
59
  )
@@ -96,10 +96,8 @@ class MLP_Reg_model(Model):
96
96
  _, truths, predictions = self.evaluate_model(
97
97
  self.model, self.testloader, self.device
98
98
  )
99
- result, _, _ = self.evaluate_model(
100
- self.model, self.trainloader, self.device)
101
- report = Reporter(truths.numpy(), predictions.numpy(),
102
- self.run, self.epoch)
99
+ result, _, _ = self.evaluate_model(self.model, self.trainloader, self.device)
100
+ report = Reporter(truths.numpy(), predictions.numpy(), self.run, self.epoch)
103
101
  try:
104
102
  report.result.loss = self.loss
105
103
  except AttributeError: # if the model was loaded from disk the loss is unknown
@@ -133,11 +131,9 @@ class MLP_Reg_model(Model):
133
131
 
134
132
  def __getitem__(self, item):
135
133
  index = self.df.index[item]
136
- features = self.df_features.loc[index, :].values.astype(
137
- "float32").squeeze()
134
+ features = self.df_features.loc[index, :].values.astype("float32").squeeze()
138
135
  labels = (
139
- np.array([self.df.loc[index, self.label]]
140
- ).astype("float32").squeeze()
136
+ np.array([self.df.loc[index, self.label]]).astype("float32").squeeze()
141
137
  )
142
138
  return features, labels
143
139
 
@@ -194,8 +190,7 @@ class MLP_Reg_model(Model):
194
190
  end_index = (index + 1) * loader.batch_size
195
191
  if end_index > len(loader.dataset):
196
192
  end_index = len(loader.dataset)
197
- logits[start_index:end_index] = model(
198
- features.to(device)).reshape(-1)
193
+ logits[start_index:end_index] = model(features.to(device)).reshape(-1)
199
194
  targets[start_index:end_index] = labels
200
195
  loss = self.criterion(
201
196
  logits[start_index:end_index].to(
@@ -11,6 +11,7 @@ class SVM_model(Model):
11
11
 
12
12
  def __init__(self, df_train, df_test, feats_train, feats_test):
13
13
  super().__init__(df_train, df_test, feats_train, feats_test)
14
+ self.name = "svm"
14
15
  c = float(self.util.config_val("MODEL", "C_val", "0.001"))
15
16
  if eval(self.util.config_val("MODEL", "class_weight", "False")):
16
17
  class_weight = "balanced"
@@ -11,6 +11,7 @@ class SVR_model(Model):
11
11
 
12
12
  def __init__(self, df_train, df_test, feats_train, feats_test):
13
13
  super().__init__(df_train, df_test, feats_train, feats_test)
14
+ self.name = "svr"
14
15
  c = float(self.util.config_val("MODEL", "C_val", "0.001"))
15
16
  # kernel{‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’} or callable, default=’rbf’
16
17
  kernel = self.util.config_val("MODEL", "kernel", "rbf")
@@ -11,4 +11,5 @@ class Tree_model(Model):
11
11
 
12
12
  def __init__(self, df_train, df_test, feats_train, feats_test):
13
13
  super().__init__(df_train, df_test, feats_train, feats_test)
14
+ self.name = "tree"
14
15
  self.clf = DecisionTreeClassifier() # set up the classifier
@@ -11,4 +11,5 @@ class Tree_reg_model(Model):
11
11
 
12
12
  def __init__(self, df_train, df_test, feats_train, feats_test):
13
13
  super().__init__(df_train, df_test, feats_train, feats_test)
14
+ self.name = "tree_reg"
14
15
  self.clf = DecisionTreeRegressor() # set up the classifier
@@ -7,9 +7,11 @@ from nkululeko.models.model import Model
7
7
  class XGB_model(Model):
8
8
  """An XGBoost model"""
9
9
 
10
- is_classifier = True
11
-
12
- clf = XGBClassifier() # set up the classifier
10
+ def __init__(self, df_train, df_test, feats_train, feats_test):
11
+ super().__init__(df_train, df_test, feats_train, feats_test)
12
+ self.name = "xgb"
13
+ self.is_classifier = True
14
+ self.clf = XGBClassifier() # set up the classifier
13
15
 
14
16
  def get_type(self):
15
17
  return "xgb"
@@ -5,8 +5,10 @@ from nkululeko.models.model import Model
5
5
 
6
6
 
7
7
  class XGR_model(Model):
8
- """An XGBoost model"""
8
+ """An XGBoost regression model"""
9
9
 
10
- is_classifier = False
11
-
12
- clf = XGBRegressor() # set up the regressor
10
+ def __init__(self, df_train, df_test, feats_train, feats_test):
11
+ super().__init__(df_train, df_test, feats_train, feats_test)
12
+ self.name = "xgr"
13
+ self.is_classifier = False
14
+ self.clf = XGBRegressor() # set up the regressor
@@ -0,0 +1,117 @@
1
+ # test_pretrain.py
2
+ import argparse
3
+ import configparser
4
+ import os.path
5
+
6
+ import datasets
7
+ import numpy as np
8
+ import pandas as pd
9
+ import torch
10
+ import transformers
11
+
12
+ import audeer
13
+ import audiofile
14
+
15
+ from nkululeko.constants import VERSION
16
+ import nkululeko.experiment as exp
17
+ import nkululeko.glob_conf as glob_conf
18
+ from nkululeko.utils.util import Util
19
+
20
+
21
+ def doit(config_file):
22
+ # test if the configuration file exists
23
+ if not os.path.isfile(config_file):
24
+ print(f"ERROR: no such file: {config_file}")
25
+ exit()
26
+
27
+ # load one configuration per experiment
28
+ config = configparser.ConfigParser()
29
+ config.read(config_file)
30
+
31
+ # create a new experiment
32
+ expr = exp.Experiment(config)
33
+ module = "test_pretrain"
34
+ expr.set_module(module)
35
+ util = Util(module)
36
+ util.debug(
37
+ f"running {expr.name} from config {config_file}, nkululeko version"
38
+ f" {VERSION}"
39
+ )
40
+
41
+ if util.config_val("EXP", "no_warnings", False):
42
+ import warnings
43
+
44
+ warnings.filterwarnings("ignore")
45
+
46
+ # load the data
47
+ expr.load_datasets()
48
+
49
+ # split into train and test
50
+ expr.fill_train_and_tests()
51
+ util.debug(f"train shape : {expr.df_train.shape}, test shape:{expr.df_test.shape}")
52
+
53
+ sampling_rate = 16000
54
+ max_duration_sec = 8.0
55
+
56
+ model_path = "facebook/wav2vec2-large-robust-ft-swbd-300h"
57
+ num_layers = None
58
+
59
+ batch_size = 16
60
+ accumulation_steps = 4
61
+
62
+ # create dataset
63
+
64
+ dataset = {}
65
+ data_sources = {
66
+ "train": pd.DataFrame(expr.df_train[glob_conf.target]),
67
+ "dev": pd.DataFrame(expr.df_test[glob_conf.target]),
68
+ }
69
+
70
+ for split in ["train", "dev"]:
71
+
72
+ y = pd.Series(
73
+ data=data_sources[split].itertuples(index=False, name=None),
74
+ index=data_sources[split].index,
75
+ dtype=object,
76
+ name="labels",
77
+ )
78
+
79
+ y.name = "targets"
80
+ df = y.reset_index()
81
+ df.start = df.start.dt.total_seconds()
82
+ df.end = df.end.dt.total_seconds()
83
+ print(f"{split}: {len(df)}")
84
+ ds = datasets.Dataset.from_pandas(df)
85
+ dataset[split] = ds
86
+
87
+ dataset = datasets.DatasetDict(dataset)
88
+
89
+ config = transformers.AutoConfig.from_pretrained(
90
+ model_path,
91
+ num_labels=len(util.la),
92
+ label2id=data.gender_mapping,
93
+ id2label=data.gender_mapping_reverse,
94
+ finetuning_task="age-gender",
95
+ )
96
+ if num_layers is not None:
97
+ config.num_hidden_layers = num_layers
98
+ setattr(config, "sampling_rate", sampling_rate)
99
+ setattr(config, "data", ",".join(sources))
100
+
101
+ print("DONE")
102
+
103
+
104
+ def main(src_dir):
105
+ parser = argparse.ArgumentParser(description="Call the nkululeko framework.")
106
+ parser.add_argument("--config", default="exp.ini", help="The base configuration")
107
+ args = parser.parse_args()
108
+ if args.config is not None:
109
+ config_file = args.config
110
+ else:
111
+ config_file = f"{src_dir}/exp.ini"
112
+ doit(config_file)
113
+
114
+
115
+ if __name__ == "__main__":
116
+ cwd = os.path.dirname(os.path.abspath(__file__))
117
+ main(cwd) # use this if you want to state the config file path on command line
nkululeko/utils/util.py CHANGED
@@ -1,10 +1,13 @@
1
1
  # util.py
2
- import pandas as pd
3
2
  import ast
3
+ import configparser
4
+ import os.path
5
+ import pickle
4
6
  import sys
7
+
5
8
  import numpy as np
6
- import os.path
7
- import configparser
9
+ import pandas as pd
10
+
8
11
  import audeer
9
12
  import audformat
10
13
 
@@ -295,6 +298,28 @@ class Util:
295
298
  f" {vals.argmax()}"
296
299
  )
297
300
 
301
+ def exist_pickle(self, name):
302
+ store = self.get_path("store")
303
+ name = "/".join([store, name]) + ".pkl"
304
+ if os.path.isfile(name):
305
+ return True
306
+ return False
307
+
308
+ def to_pickle(self, anyobject, name):
309
+ store = self.get_path("store")
310
+ name = "/".join([store, name]) + ".pkl"
311
+ self.debug(f"saving {name}")
312
+ with open(name, "wb") as handle:
313
+ pickle.dump(anyobject, handle)
314
+
315
+ def from_pickle(self, name):
316
+ store = self.get_path("store")
317
+ name = "/".join([store, name]) + ".pkl"
318
+ self.debug(f"loading {name}")
319
+ with open(name, "rb") as handle:
320
+ any_opject = pickle.load(handle)
321
+ return any_opject
322
+
298
323
  def write_store(self, df, storage, format):
299
324
  if format == "pkl":
300
325
  df.to_pickle(storage)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nkululeko
3
- Version: 0.83.2
3
+ Version: 0.84.0
4
4
  Summary: Machine learning audio prediction experiments based on templates
5
5
  Home-page: https://github.com/felixbur/nkululeko
6
6
  Author: Felix Burkhardt
@@ -333,6 +333,15 @@ F. Burkhardt, Johannes Wagner, Hagen Wierstorf, Florian Eyben and Björn Schulle
333
333
  Changelog
334
334
  =========
335
335
 
336
+ Version 0.84.0
337
+ --------------
338
+ * added SHAP analysis
339
+ * started with finetuning
340
+
341
+ Version 0.83.3
342
+ --------------
343
+ * fixed a naming error in trill features that prevented storage of experiment
344
+
336
345
  Version 0.83.2
337
346
  --------------
338
347
  * added default cuda if present and not stated
@@ -2,17 +2,17 @@ nkululeko/__init__.py,sha256=62f8HiEzJ8rG2QlTFJXUCMpvuH3fKI33DoJSj33mscc,63
2
2
  nkululeko/aug_train.py,sha256=YhuZnS_WVWnun9G-M6g5n6rbRxoVREz6Zh7k6qprFNQ,3194
3
3
  nkululeko/augment.py,sha256=4MG0apTAG5RgkuJrYEjGgDdbodZWi_HweSPNI1JJ5QA,3051
4
4
  nkululeko/cacheddataset.py,sha256=lIJ6hUo5LoxSrzXtWV8mzwO7wRtUETWnOQ4ws2XfL1E,969
5
- nkululeko/constants.py,sha256=VE94aCLZ8N-hTKIgb4OLo1s9l_Fxncl9iTNis0eotFw,39
6
- nkululeko/demo.py,sha256=55kNFA2helMhOxD4yZuKg1JWDtlUUpxm-6uAnroIydI,3264
5
+ nkululeko/constants.py,sha256=Ij7mvqjHA328NaCRJL2JvyYgAPfkfYpVq_WiS735RQY,39
6
+ nkululeko/demo.py,sha256=8bl15Kitoesnz8oa8yrs52T6YCSOhWbbq9PnZ8Hj6D0,3232
7
7
  nkululeko/demo_feats.py,sha256=sAeGFojhEj9WEDFtG3SzPBmyYJWLF2rkbpp65m8Ujo4,2025
8
- nkululeko/demo_predictor.py,sha256=-ggSHc3DXxRzjzcGB4qFBOMvKsfUdTkkde50BDrS9dA,4755
9
- nkululeko/experiment.py,sha256=WyLiOJ_VxlaXoS1cwXruzYV9OESMjjedcFNreKE1Z8I,29728
10
- nkululeko/explore.py,sha256=2wdoGRqldvsN1zCiWk0quSDgHHHUoF2UZOWQ1r-2OLM,2310
8
+ nkululeko/demo_predictor.py,sha256=es56xbT8ifkS_vnrlb5NTZT54gNmeUtNlA4zVA_gnN8,4757
9
+ nkululeko/experiment.py,sha256=mYdHfInMkuOI3frkZo7oaEe9viO-Qa1ZShyF6MPozcU,30225
10
+ nkululeko/explore.py,sha256=lDzRoW_Taa5u4BBABZLD89BcQWnYlrftJR4jgt1yyj0,2609
11
11
  nkululeko/export.py,sha256=mHeEAAmtZuxdyebLlbSzPrHSi9OMgJHbk35d3DTxRBc,4632
12
12
  nkululeko/feature_extractor.py,sha256=8mssYKmo4LclVI-hiLmJEDZ0ZPyDavFG2YwtXcrGzwM,3976
13
13
  nkululeko/file_checker.py,sha256=LoLnL8aHpW-axMQ46qbqrManTs5otG9ShpEZuz9iRSk,3474
14
14
  nkululeko/filter_data.py,sha256=w-X2mhKdYr5DxDIz50E5yzO6Jmzk4jjDBoXsgOOVtcA,7222
15
- nkululeko/glob_conf.py,sha256=iHiVSxDYgmYwdx6z0HuGUMSWrfZfufPHxHb60q2dLRY,453
15
+ nkululeko/glob_conf.py,sha256=KL9YJQTHvTztxo1vr25qRRgaPnx4NTg0XrdbovKGMmw,525
16
16
  nkululeko/modelrunner.py,sha256=GwDXcE2gDQXat4W0-HhHQ1BcUNCRBXMBQ4QycfHp_5c,9288
17
17
  nkululeko/multidb.py,sha256=fG3VukEWP1vreVN4gB1IRXxwwg4jLftsSEYtu0o1f78,5634
18
18
  nkululeko/nkuluflag.py,sha256=PGWSmZz-PiiHLgcZJAoGOI_Y-sZDVI1ksB8p5r7riWM,3725
@@ -26,6 +26,7 @@ nkululeko/segment.py,sha256=YLKckX44tbvTb3LrdgYw9X4guzuF27sutl92z9DkpZU,4835
26
26
  nkululeko/syllable_nuclei.py,sha256=Sky-C__MeUDaxqHnDl2TGLLYOYvsahD35TUjWGeG31k,10047
27
27
  nkululeko/test.py,sha256=1w624vo5KTzmFC8BUStGlLDmIEAFuJUz7J0W-gp7AxI,1677
28
28
  nkululeko/test_predictor.py,sha256=_w5J8CxH6hmW3mLTKbdfmywl5QpdNAnW1Y8TE5GtlfE,3237
29
+ nkululeko/test_pretrain.py,sha256=aoN-C9M4Zn9LwseIWQdMMpEGclnkWs-gJXyItU5V0fk,3109
29
30
  nkululeko/augmenting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
31
  nkululeko/augmenting/augmenter.py,sha256=XAt0dpmlnKxqyysqCgV3rcz-pRIvOz7rU7dmGDCVAzs,2905
31
32
  nkululeko/augmenting/randomsplicer.py,sha256=Z5rxdKKUpuncLWuTS6xVfVKUeVbeiYU_dLRHQ5fcg4Y,2669
@@ -49,7 +50,7 @@ nkululeko/data/dataset_csv.py,sha256=uLa7jW4w2ft299NkpXZMD361kPHF8oSYoIZ_ucxhuOM
49
50
  nkululeko/feat_extract/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
51
  nkululeko/feat_extract/feats_agender.py,sha256=Qm69G4kqAyTVVk7wwRgrXlNwGaDMGRYyKGpuf0vOEgM,3113
51
52
  nkululeko/feat_extract/feats_agender_agender.py,sha256=tgH2BnwcxpvuLmOkrMbVdBSX0Onfz2MG12FsddalRKI,3424
52
- nkululeko/feat_extract/feats_analyser.py,sha256=_5oz4y-NZCEBgfNP2GZ9WNqQR50Hbykm0TvDVomWP0U,11399
53
+ nkululeko/feat_extract/feats_analyser.py,sha256=Y9hMpZ9WsQOrxTP3B1diHnzMeOgwbVpVFWVlIyhHMJs,12722
53
54
  nkululeko/feat_extract/feats_auddim.py,sha256=VlzKKXTXa5kjLgQBWyEFy-daIyU1SkOwCCOIhKsWCvE,3162
54
55
  nkululeko/feat_extract/feats_audmodel.py,sha256=VjBNgAoxsHJhwr6Kwt9CxX6SaCM4RK_OV-GU2W5-bhU,3187
55
56
  nkululeko/feat_extract/feats_clap.py,sha256=nR6eEIRdsMHcfmD1bNtt5WfDvkxKjvEbukSSrXHm-HU,3489
@@ -64,7 +65,7 @@ nkululeko/feat_extract/feats_snr.py,sha256=9dqZ-4RpK98iJEssM3ttozNd18LWlZYM_QVXv
64
65
  nkululeko/feat_extract/feats_spectra.py,sha256=5Pex8awIQC3cjQRHSu4NQFmg4quamG0RL3V3Yd0pJHs,3670
65
66
  nkululeko/feat_extract/feats_spkrec.py,sha256=VK4ma3uWzM0YZStsgRTirfkbzjWIfRWSgsYI038QlRY,4803
66
67
  nkululeko/feat_extract/feats_squim.py,sha256=Y31YmDmscuG0YozvxyBZIutO3id8t7IZJWCfKucw-6M,4617
67
- nkululeko/feat_extract/feats_trill.py,sha256=HXQBaPWTX0iNEjBY7RD8uyFeYjDieHqv8ZilE0Jb-Pg,3319
68
+ nkululeko/feat_extract/feats_trill.py,sha256=K2ahhdpwpjgg3WZS1POg3UMP2U44i8cLZZvn5Rq7fUI,3228
68
69
  nkululeko/feat_extract/feats_wav2vec2.py,sha256=9WUMfyddB_3nx79g7mZoQrRynhM1uEBWuOotRq8bxoU,5268
69
70
  nkululeko/feat_extract/feats_wavlm.py,sha256=ulxpGjifUFx2ZgGmY32SmBJGIuvkYHoLb2n1LZ8KMwA,4703
70
71
  nkululeko/feat_extract/feats_whisper.py,sha256=BFspQBI53HAgw22vBEeFskGwFZA-94Rpl17xM458HRo,4576
@@ -74,21 +75,21 @@ nkululeko/losses/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
74
75
  nkululeko/losses/loss_ccc.py,sha256=NOK0y0fxKUnU161B5geap6Fmn8QzoPl2MqtPiV8IuJE,976
75
76
  nkululeko/losses/loss_softf1loss.py,sha256=5gW-PuiqeAZcRgfwjueIOQtMokOjZWgQnVIv59HKTCo,1309
76
77
  nkululeko/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
- nkululeko/models/model.py,sha256=oAdKq2wY5lYKfpZkQwO46ojYRsj_Z-FR56oR1uHAWI0,11569
78
- nkululeko/models/model_bayes.py,sha256=wI7-sCwibqXMCHviu349TYjgJXXNXym-Z6ZM83uxlFQ,378
79
- nkululeko/models/model_cnn.py,sha256=revCxyeX69DU6OA63YTnF28UaAFV7AmUfqODMCE_pbQ,10002
80
- nkululeko/models/model_gmm.py,sha256=onovzGBeguwZ-upXtuDLaBw9sd6fDDQslVBOrz1Z8TE,645
81
- nkululeko/models/model_knn.py,sha256=5tGqiPo2JTw9VLmD-MXNZKFJ5RTLA6uv_blJDJ9lScA,573
82
- nkululeko/models/model_knn_reg.py,sha256=Fbuk6Ku6eyrbbMEk7rB5dwfhvQOMsdZk6HI_0T0gYPw,580
83
- nkululeko/models/model_lin_reg.py,sha256=NBTnY2ULuhUBt5ArYQwskZ2Vq4BBDGkqd9SYBFl7Ql4,392
84
- nkululeko/models/model_mlp.py,sha256=IuNGrLPx54-ZmpydH2yJdm2ddCm4rgu59Csv5ikbEpI,9471
85
- nkululeko/models/model_mlp_regression.py,sha256=-ailThquUXwLkOj5jlJ4qn1vlb3nSHW5s0KS7GLp4qI,10290
86
- nkululeko/models/model_svm.py,sha256=QqwRjfG9I5y-57CcJAMUSbvYzV0DOlDcpDK5f4yQ_qw,914
87
- nkululeko/models/model_svr.py,sha256=p-Mb4Bn54yOe1upuHQKNpfj4ttOmQnm9pCB7ECkJkJQ,699
88
- nkululeko/models/model_tree.py,sha256=soXjV523eRvRZ-jbX7X_3S73Wto1B9bm7ZzzDmgYzTc,390
89
- nkululeko/models/model_tree_reg.py,sha256=QxkQEz3LOuCLkXw5xH9IwFg4IcTL3Y5RK03qKe4TtGQ,397
90
- nkululeko/models/model_xgb.py,sha256=yPJFD2jxOGcPDKuBeqJSmh83eKrfbnD_n722i6g39_g,267
91
- nkululeko/models/model_xgr.py,sha256=yY6wZV8jdiQCIYQCjYSb8gE0jjeiY44eh3rERe2HDvg,227
78
+ nkululeko/models/model.py,sha256=fL6LB6I9Oqo_OWUIptqiu6abuxVYYv8bW2a3m4XSLqU,11601
79
+ nkululeko/models/model_bayes.py,sha256=WJFZ8wFKwWATz6MhmjeZIi1Pal1viU549WL_PjXDSy8,406
80
+ nkululeko/models/model_cnn.py,sha256=bJxqwe6FnVR2hFeqN6EXexYGgvKYFED1VOhBXVlLWaE,9954
81
+ nkululeko/models/model_gmm.py,sha256=hZ9UO36KNf48qa3J-xkWIicIj9-TApmt21zNES2vEOs,649
82
+ nkululeko/models/model_knn.py,sha256=KlnrJfwiVnmXZrAaYGFrKA2f5sznvTzSJQ8-5etOP0k,599
83
+ nkululeko/models/model_knn_reg.py,sha256=j7YFfVm6xOR2d9yBYdQiwwqYfqkX0JynX_qLCvkr1fk,610
84
+ nkululeko/models/model_lin_reg.py,sha256=0D7mSnSwK82lNWDMwHYRyq3FmGa6y-DHDGg4qUe85q4,422
85
+ nkululeko/models/model_mlp.py,sha256=JtC83GYKtqCTW00rUm_xKSKjAsdMUAsqtnBfEFZBCwA,9854
86
+ nkululeko/models/model_mlp_regression.py,sha256=PO5qyfjgAJH8hawhmeXDaUThyXDYdM642dQHkO0NY7c,10204
87
+ nkululeko/models/model_svm.py,sha256=rsME3KvKvNG7bdE5lbvYUu85WZhaASZxxmdNDIVJRZ4,940
88
+ nkululeko/models/model_svr.py,sha256=_YZeksqB3eBENGlg3g9RwYFlk9rQQ-XCeNBKLlGGVoE,725
89
+ nkululeko/models/model_tree.py,sha256=rf16faUm4o2LJgkoYpeY998b8DQIvXZ73_m1IS3TnnE,417
90
+ nkululeko/models/model_tree_reg.py,sha256=IgQcPTE-304HQLYSKPF8Z4ot_Ur9dH01fZjS0nXke_M,428
91
+ nkululeko/models/model_xgb.py,sha256=Thgx5ESdIok4v72mKh4plxpo4smGcKALWNCJTDScY0M,447
92
+ nkululeko/models/model_xgr.py,sha256=aGBtNGLWjOE_2rICGYGFxmT8DtnHYsIl1lIpMtghHsY,418
92
93
  nkululeko/reporting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
94
  nkululeko/reporting/defines.py,sha256=IsY1YgKRMaABpylVKjBJgJ5bNCEbGCVA_E6pivraqSU,648
94
95
  nkululeko/reporting/latex_writer.py,sha256=qiCRSmB4KOD_za4oHu5x-PhwjZohzfo8wecMOwlXZwc,1886
@@ -102,9 +103,9 @@ nkululeko/segmenting/seg_silero.py,sha256=lLytS38KzARS17omwv8VBw-zz60RVSXGSvZ5Ev
102
103
  nkululeko/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
104
  nkululeko/utils/files.py,sha256=UiGAtZRWYjHSvlmPaTMtzyNNGE6qaLaxQkybctS7iRM,4021
104
105
  nkululeko/utils/stats.py,sha256=1yUq0FTOyqkU8TwUocJRYdJaqMU5SlOBBRUun9STo2M,2829
105
- nkululeko/utils/util.py,sha256=_Z6OMJ3f-8TdETW9eqJYY5hwNRS5XCt9azzRnqoTTZE,12330
106
- nkululeko-0.83.2.dist-info/LICENSE,sha256=0zGP5B_W35yAcGfHPS18Q2B8UhvLRY3dQq1MhpsJU_U,1076
107
- nkululeko-0.83.2.dist-info/METADATA,sha256=DMkXO8jSm6iR4eETrG2aEK__7MfPhpAvOe6Tf99n_HE,36158
108
- nkululeko-0.83.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
109
- nkululeko-0.83.2.dist-info/top_level.txt,sha256=DPFNNSHPjUeVKj44dVANAjuVGRCC3MusJ08lc2a8xFA,10
110
- nkululeko-0.83.2.dist-info/RECORD,,
106
+ nkululeko/utils/util.py,sha256=lVKcIYHeN8wt7ap8o1UTx5z6nvOY40twJ_C4CshT42Y,13068
107
+ nkululeko-0.84.0.dist-info/LICENSE,sha256=0zGP5B_W35yAcGfHPS18Q2B8UhvLRY3dQq1MhpsJU_U,1076
108
+ nkululeko-0.84.0.dist-info/METADATA,sha256=RJnEnBwqdKRLs4J16zOzsps0GXmdVvzPMi1_2hpZh-Q,36346
109
+ nkululeko-0.84.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
110
+ nkululeko-0.84.0.dist-info/top_level.txt,sha256=DPFNNSHPjUeVKj44dVANAjuVGRCC3MusJ08lc2a8xFA,10
111
+ nkululeko-0.84.0.dist-info/RECORD,,