X-Git-Url: https://git.piment-noir.org/?p=TP_AA.git;a=blobdiff_plain;f=TP3%2Fexo3%2Ftp3_exo3.py;fp=TP3%2Fexo3%2Ftp3_exo3.py;h=3476f6fc85d36e36397bc417d1d0a24c91701558;hp=0000000000000000000000000000000000000000;hb=9fa4e985cd669b39149628215e437b72a66e7b49;hpb=26fd2383c38aa862fd24bdfadf3ba219fa1cd4dd diff --git a/TP3/exo3/tp3_exo3.py b/TP3/exo3/tp3_exo3.py new file mode 100755 index 0000000..3476f6f --- /dev/null +++ b/TP3/exo3/tp3_exo3.py @@ -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()