Add TP3 exo3 and TP4 exo1.
[TP_AA.git] / TP3 / exo3 / tp3_exo3.py
diff --git a/TP3/exo3/tp3_exo3.py b/TP3/exo3/tp3_exo3.py
new file mode 100755 (executable)
index 0000000..3476f6f
--- /dev/null
@@ -0,0 +1,180 @@
+#!/usr/bin/env python3
+
+# -*- coding: utf-8 -*-
+import numpy as np
+from numpy.random import rand
+import pylab as pl
+
+
+def generateData(n):
+    """
+    Generates a 2D linearly separable dataset with 2n samples.
+    The third element of the sample is the label
+    """
+    linear_offset = 0.6
+    xb = (rand(n) * 2 - 1) / 2 - linear_offset
+    yb = (rand(n) * 2 - 1) / 2 + linear_offset
+    xr = (rand(n) * 2 - 1) / 2 + linear_offset
+    yr = (rand(n) * 2 - 1) / 2 - linear_offset
+    inputs = []
+    for i in range(n):
+        inputs.append([xb[i], yb[i], -1])
+        inputs.append([xr[i], yr[i], 1])
+    return inputs
+
+
+def generateData2(n):
+    """
+    Generates a 2D linearly separable dataset with 2n samples.
+    The third element of the sample is the label
+    """
+    xb = (rand(n) * 2 - 1) / 2 + 0.5
+    yb = (rand(n) * 2 - 1) / 2
+    xr = (rand(n) * 2 - 1) / 2 + 1.5
+    yr = (rand(n) * 2 - 1) / 2 - 0.5
+    inputs = []
+    for i in range(n):
+        inputs.append([xb[i], yb[i], -1])
+        inputs.append([xr[i], yr[i], 1])
+    return inputs
+
+
+def generateData3(n):
+    """
+    Generates a 2D linearly separable dataset with about 2n samples.
+    The third element of the sample is the label
+    """
+    # (xb, yb) est dans le carré centré à l’origine de côté 1
+    xb = (rand(n) * 2 - 1) / 2
+    yb = (rand(n) * 2 - 1) / 2
+    # (xr, yr) est dans le carré centré à l’origine de côté 3
+    xr = 3 * (rand(4 * n) * 2 - 1) / 2
+    yr = 3 * (rand(4 * n) * 2 - 1) / 2
+    inputs = []
+    for i in range(n):
+        inputs.append([xb[i], yb[i], -1])
+    for i in range(4 * n):
+        # on ne conserve que les points extérieurs au carré centré à l’origine
+        # de côté 2
+        if abs(xr[i]) >= 1 or abs(yr[i]) >= 1:
+            inputs.append([xr[i], yr[i], 1])
+    return inputs
+
+
+def readData(file):
+    f = open(file, "r")
+    training_set = []
+    x = f.readline()
+    while x:
+        x_eval = eval(x)
+        training_set.append([x_eval[0][0], x_eval[0][1], x_eval[1]])
+        x = f.readline()
+    f.close()
+    return training_set
+
+
+training_set_size = 150
+# training_set = generateData3(training_set_size)
+training_set = readData("learn.data")
+data = np.array(training_set)
+X = data[:, 0:2]
+Y = data[:, -1]
+
+
+def perceptron_nobias(X, Y):
+    w = np.zeros([len(X[0])])
+    # Go in the loop at least one time
+    classification_error = 1
+    while not classification_error == 0:
+        classification_error = 0
+        for x, y in zip(X, Y):
+            if y * np.dot(w, x) <= 0:
+                classification_error += 1
+                w = w + y * x
+        print(classification_error)
+    return w
+
+
+def complete(sample):
+    new_sample = np.insert(sample, len(sample[0]), [1], axis=1)
+    return np.array(new_sample)
+
+
+def plongement_phi(sample_element):
+    return [1, sample_element[0], sample_element[1], sample_element[0]**2,
+            sample_element[0] * sample_element[1], sample_element[1]**2]
+
+
+def apply_plongement(sample, p):
+    output = []
+    for i in range(sample.shape[0]):
+        current = p(sample[i])
+        output.append(current)
+    return np.array(output)
+
+
+def f_from_k(coeffs, support_set, k, x):
+    output = 0
+    for c, s in zip(coeffs, support_set):
+        output += c * s[1] * k(s[0], x)
+    return output
+
+
+def k1(X1, X2):
+    return 1 + X1[0] * X2[0] + X1[1] * X2[1] + X1[0]**2 * X2[0]**2 \
+             + X1[0] * X1[1] * X2[0] * X2[1] + X1[1]**2 * X2[1]**2
+
+
+def kg(x, y):
+    # sigma = 20  # do not converge
+    # sigma = 10  # do not converge
+    sigma = 1  # overfitting
+    # sigma = 0.5  # overfitting
+    # sigma = 0.2  # overfitting
+    return np.exp(-((x[0] - y[0])**2 + (x[1] - y[1])**2) / sigma**2)
+
+
+def perceptron_k(X, Y, k):
+    coeffs = []
+    support_set = []
+    # Go in the loop at least one time
+    classification_error = 1
+    while not classification_error == 0:
+        classification_error = 0
+        for x, y in zip(X, Y):
+            if y * f_from_k(coeffs, support_set, k, x) <= 0:
+                if x not in support_set:
+                    support_set.append((x, y))
+                    coeffs.append(1)
+                else:
+                    coeffs[support_set.index((x, y))] += 1
+                classification_error += 1
+        print(classification_error)
+    return np.array(coeffs), np.array(support_set)
+
+
+def f(w, x, y):
+    return w[0] + w[1] * x + w[2] * y + w[3] * x**2 + w[4] * x * y + w[5] * y**2
+
+
+pl.scatter(X[:, 0], X[:, 1], c=Y)
+pl.title(u"Perceptron - prolontaged hyperplan")
+
+# k = k1
+# coeffs, support_set = perceptron_k(X, Y, k)
+k = kg
+coeffs, support_set = perceptron_k(X, Y, k)
+res = training_set_size
+for x in range(res):
+    for y in range(res):
+        if abs(f_from_k(coeffs, support_set, k, [-3 / 2 + 3 * x / res, -3 / 2 + 3 * y / res])) < 0.01:
+            pl.plot(-3 / 2 + 3 * x / res, -3 / 2 + 3 * y / res, 'xr')
+
+# X = apply_plongement(X, plongement_phi)
+# w = perceptron_nobias(X, Y)
+# for x in range(res):
+#     for y in range(res):
+#         if abs(f(w, -3 / 2 + 3 * x / res, -3 / 2 + 3 * y / res)) < 0.01:
+#             pl.plot(-3 / 2 + 3 * x / res, -3 / 2 + 3 * y / res, 'xb')
+
+pl.show()