diff --git a/iris-classes.png b/iris-classes.png new file mode 100644 index 0000000000000000000000000000000000000000..633c8e96e09a192f82844e943403dabc4b86c20b Binary files /dev/null and b/iris-classes.png differ diff --git a/main.py b/main.py index 244a9ac1090c3be185e65422a368820090166e5c..0fb15e801a2d269bb00a4bd33c29c0ea183467ea 100644 --- a/main.py +++ b/main.py @@ -17,7 +17,7 @@ def load_and_normalize_mnist(): def load_and_normalize_iris(): iris = load_iris() - X, y = shuffle(iris.data, iris.target, random_state=42) + X, y = shuffle(iris.data, iris.target) X = MinMaxScaler().fit_transform(X) return X, y @@ -64,7 +64,7 @@ def visualize_neuron_weights(som, som_size): plt.show() def evaluate_kmeans(X_train, y_train, X_test, y_test, n_clusters): - kmeans = KMeans(n_clusters=n_clusters, random_state=42) + kmeans = KMeans(n_clusters=n_clusters) kmeans.fit(X_train) cluster_mapping = {} @@ -106,7 +106,7 @@ if __name__ == "__main__": X_test, y_test = X[train_size:], y[train_size:] # Entraîner la SOM - som_size = (6, 6) + som_size = (5, 5) som = train_som(X_train, som_size) bmu_classes = map_neurons_to_classes(som, X_train, y_train) @@ -123,4 +123,48 @@ if __name__ == "__main__": print(f"KMeans Accuracy: {kmeans_accuracy * 100:.2f}%") else: + mnist_kmeans_total = 0 + iris_kmeans_total = 0 + mnist_som_total = 0 + iris_som_total = 0 + + count = 100 + + for i in range(count): + print(i) + X_train, y_train, X_test, y_test = load_and_normalize_mnist() + som_size = (10, 10) + som = train_som(X_train[:1000], som_size) + bmu_classes = map_neurons_to_classes(som, X_train[:1000], y_train[:1000]) + y_pred = predict(som, X_test[:1000], bmu_classes) + som_accuracy = accuracy_score(y_test[:1000], y_pred) + kmeans_accuracy = evaluate_kmeans(X_train[:1000], y_train[:1000], X_test[:1000], y_test[:1000], n_clusters=10) + mnist_kmeans_total += kmeans_accuracy + mnist_som_total += som_accuracy + print(f"SOM Accuracy (MNIST): {som_accuracy * 100:.2f}%") + print(f"KMeans Accuracy (MNIST): {kmeans_accuracy * 100:.2f}%") + X, y = load_and_normalize_iris() + + train_size = int(0.8 * len(X)) + X_train, y_train = X[:train_size], y[:train_size] + X_test, y_test = X[train_size:], y[train_size:] + + # Entraîner la SOM + som_size = (6, 6) + som = train_som(X_train, som_size) + + bmu_classes = map_neurons_to_classes(som, X_train, y_train) + y_pred = predict(som, X_test, bmu_classes) + som_accuracy = accuracy_score(y_test, y_pred) + kmeans_accuracy = evaluate_kmeans(X_train, y_train, X_test, y_test, n_clusters=3) + iris_kmeans_total += kmeans_accuracy + iris_som_total += som_accuracy + print(f"SOM Accuracy (Iris): {som_accuracy * 100:.2f}%") + print(f"KMeans Accuracy (Iris): {kmeans_accuracy * 100:.2f}%") + + print("--------------------------------") + print(f"SOM Accuracy (MNIST): {mnist_som_total / count *100:.2f}%") + print(f"KMeans Accuracy (MNIST): {mnist_kmeans_total / count *100:.2f}%") + print(f"SOM Accuracy (Iris): {iris_som_total / count *100:.2f}%") + print(f"KMeans Accuracy (Iris): {iris_kmeans_total / count *100:.2f}%") print("Dataset non reconnu. Choisissez 'mnist' ou 'iris'.") diff --git a/poids neuronnes.png b/poids neuronnes.png new file mode 100644 index 0000000000000000000000000000000000000000..fdc4112bf2e065fa90f2c4a6b022aeb788a9904b Binary files /dev/null and b/poids neuronnes.png differ diff --git a/rapport.md b/rapport.md new file mode 100644 index 0000000000000000000000000000000000000000..e23a4c57a86ce8da442daad887e37054686e9332 --- /dev/null +++ b/rapport.md @@ -0,0 +1,61 @@ +# Rapport Self-Organizing Map (SOM) + +auteurs: Leo Harb et Ivan Pavlovich + +Ce rapport présente nos résultats pour le sujet 2 du tp final du cours d'IA et ML. les **Self-Organizing Maps (SOM)** et **KMeans**, testées sur les datasets MNIST et Iris. + +## Préparation des données + +### MNIST + +1. Les images de chiffres ont été transformées en vecteurs (28x28 → 784). +2. Les valeurs des pixels ont été normalisées entre \[0, 1\]. +3. Un échantillon de 1000 images a été utilisé pour les tests. + +### Iris + +1. Les données sur les fleurs (dimensions des pétales et sépales) ont été chargées. +2. Les données ont été mélangées aléatoirement. +3. Les valeurs ont été mises à l'échelle entre \[0, 1\]. +4. Les données ont été divisées en un ensemble d'entraînement (80%) et un ensemble de test (20%). + +## Résultats + +### MNIST + +| Méthode | Précision | +| ---------- | --------- | +| **SOM** | 72.60% | +| **KMeans** | 48.60% | + +- **Carte des classes SOM** : Une carte a montré comment les neurones de la SOM se répartissent pour représenter différentes classes de chiffres. +- **Poids des neurones** : Les poids des neurones ont été visualisés sous forme d’images, montrant les caractéristiques générales des chiffres. + +### Iris + +| Méthode | Précision | +| ---------- | --------- | +| **SOM** | 93.33% | +| **KMeans** | 86.67% | + +- **Carte des classes SOM** : Une carte montre que les neurones se regroupent clairement en trois classes correspondant aux espèces d’Iris. + +## Discussion + +### SOM + +- Pour MNIST, la SOM atteint 72.60%, ce qui montre qu’elle peut bien organiser des données complexes comme des chiffres manuscrits. +- Pour Iris, la SOM atteint 93.33%, ce qui prouve qu’elle est très efficace pour des données plus simples et bien organisées. + +### KMeans + +- Pour MNIST, KMeans n’atteint que 48.60%, montrant ses limites pour des données complexes. +- Pour Iris, KMeans fonctionne bien (86.67%) mais reste moins précis que la SOM. + +### Comparaison + +La SOM est meilleure que KMeans pour les deux datasets, car elle peut mieux organiser les données en utilisant des relations plus complexes. + +## Conclusion + +La SOM est plus performante que KMeans, surtout pour des données difficiles comme MNIST. Elle est aussi très efficace pour des données simples comme Iris. diff --git "a/r\303\251partition-classes.png" "b/r\303\251partition-classes.png" new file mode 100644 index 0000000000000000000000000000000000000000..25ea6932cfd79c3d0a40c37f80807160996cbaca Binary files /dev/null and "b/r\303\251partition-classes.png" differ