--- a
+++ b/python/aggregation_voting_strategies.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+
+"""
+aggregation_voting_strategies.py
+
+Description:
+Contains the methods for combining the decisions given by 
+multiclass SVM models: OvO and OvR 
+
+VARPA, University of Coruna
+Mondejar Guerra, Victor M.
+13 Nov 2017
+"""
+
+import numpy as np
+from evaluation_AAMI import *
+from sklearn import svm
+import time
+
+
+# NOTE: use direct decision values or transform to range (0,1) with
+# something like: 1/exp(-decision) ?
+
+# Each classifier gives only one vote for its higher class.
+# Then the majority vote rule is applied to select the final prediction
+def ovo_voting(decision_ovo, n_classes):
+    predictions = np.zeros(len(decision_ovo))
+    class_pos, class_neg = ovo_class_combinations(n_classes)
+
+    counter = np.zeros([len(decision_ovo), n_classes])
+
+    for p in range(len(decision_ovo)):
+        for i in range(len(decision_ovo[p])):
+            if decision_ovo[p,i] > 0:
+                counter[p, class_pos[i]] += 1
+            else:
+                counter[p, class_neg[i]] += 1
+
+        predictions[p] = np.argmax(counter[p])
+
+    return predictions, counter
+
+
+def ovo_voting_exp(decision_ovo, n_classes):
+    predictions = np.zeros(len(decision_ovo))
+    class_pos, class_neg = ovo_class_combinations(n_classes)
+
+    counter = np.zeros([len(decision_ovo), n_classes])
+
+    for p in range(len(decision_ovo)):
+        for i in range(len(decision_ovo[p])):
+            counter[p, class_pos[i]] += 1 / (1 + np.exp(-decision_ovo[p,i]) )
+            counter[p, class_neg[i]] += 1 / (1 + np.exp( decision_ovo[p,i]) )
+
+        predictions[p] = np.argmax(counter[p])
+
+    return predictions, counter
+
+
+
+
+####################################################
+# Testing new functions...
+
+
+# http://sci2s.ugr.es/ovo-ova
+
+def ovo_class_combinations(n_classes):
+    class_pos = []
+    class_neg = []
+    for c1 in range(n_classes-1):
+        for c2 in range(c1+1,n_classes):
+            class_pos.append(c1)
+            class_neg.append(c2)
+
+    return class_pos, class_neg
+
+# Each classifier adds it value for both classes (+/-)
+# Then the class with largest number of votes is the prediction
+def ovo_voting_both(decision_ovo, n_classes):
+    
+    predictions = np.zeros(len(decision_ovo))
+    class_pos, class_neg = ovo_class_combinations(n_classes)
+
+    counter = np.zeros([len(decision_ovo), n_classes])
+
+    for p in range(len(decision_ovo)):
+        for i in range(len(decision_ovo[p])):
+            counter[p, class_pos[i]] += decision_ovo[p,i] 
+            counter[p, class_neg[i]] -= decision_ovo[p,i] 
+
+        predictions[p] = np.argmax(counter[p])
+
+    return predictions, counter
+
+
+def ovo_voting_both2(decision_ovo, n_classes):
+    
+    predictions = np.zeros(len(decision_ovo))
+    class_pos, class_neg = ovo_class_combinations(n_classes)
+
+    counter = np.zeros([len(decision_ovo), n_classes])
+
+    for p in range(len(decision_ovo)):
+        for i in range(len(decision_ovo[p])):
+            if decision_ovo[p,i] != 0.0:
+                counter[p, class_pos[i]] += (decision_ovo[p,i]  - 0.5)
+                counter[p, class_neg[i]] += (0.5 - decision_ovo[p,i])
+
+        predictions[p] = np.argmax(counter[p])
+
+    return predictions, counter
+
+# https://papers.nips.cc/paper/1773-large-margin-dags-for-multiclass-classification.pdf
+#def ovo_DDAG(): # Decision Directed Acyclic Graph 
+
+
+# https://link.springer.com/content/pdf/10.1007%2Fs00500-006-0093-3.pdf
+def ovo_fuzzy(decision_ovo, n_classes):
+    
+    predictions = np.zeros(len(decision_ovo))
+    class_pos, class_neg = ovo_class_combinations(n_classes)
+
+    counter = np.zeros([len(decision_ovo), n_classes])
+
+    for p in range(len(decision_ovo)):
+        for i in range(len(decision_ovo[p])):
+
+
+            # TODO... continuar esta idea..abs
+
+            counter[p, class_pos[i]] = counter[p, class_pos[i]] + (decision_ovo[p,i] if decision_ovo[p,i] < 1 else 1 )
+            counter[p, class_neg[i]] = counter[p, class_neg[i]] (-decision_ovo[p,i] if decision_ovo[p,i] > -1 else -1 )
+
+        predictions[p] = np.argmax(counter[p])
+
+    return predictions, counter