{"nbformat":4,"nbformat_minor":0,"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.5.1"},"colab":{"name":"Γκαουσιανά Μοντέλα Μείξης.ipynb","provenance":[{"file_id":"https://github.com/jakevdp/PythonDataScienceHandbook/blob/master/notebooks/05.12-Gaussian-Mixtures.ipynb","timestamp":1575229498938}]}},"cells":[{"cell_type":"markdown","metadata":{"id":"Uj_91lm-_Sfr"},"source":["# Γκαουσιανά Μοντέλα Μείξης\n","\n","Ο αλγόριθμος συσταδοποίησης $k$-μέσων που είδαμε σε προηγούμενο εργαστήριο μπορεί να είναι απλός και εύκολα κατανοητός, ωστόσο η απλότητά του μπορεί να οδηγήσει σε συσταδοποιήσεις που έχουν μη-επιθυμητά χαρακτηριστικά.\n","\n","Πιο συγκεκριμένα, η μη-πιθανοτική φύση του αλγορίθμου των $k$-μέσων καθώς και η χρήση απλών μετρικών απόστασης από το κέντρο της εκάστοτε συστάδας επιβάλλει περιορισμούς στο είδος των δεδομένων που μπορεί να περιγράψει ικανοποιητικά. \n","\n","Σε αυτό το notebook θα εξετάσουμε τα *Γκαουσιανά Μοντέλα Μείξης* (Gaussian Mixture Models - GMMs), τα οποία μπορούν να θεωρηθούν ως επέκταση του αλγορίθμου $k$-μέσων, αλλά και ως ένα ισχυρό εργαλείο εκτίμησης, πέρα από την απλή συσταδοποίηση.\n","\n","Ξεκινάμε εισάγοντας κάποιες βασικές βιβλιοθήκες, κλάσεις και μεθόδους \n","που πρόκειται να χρησιμοποιήσουμε στη συνέχεια\n"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"HXdtueCY_Sfv"},"source":["%matplotlib inline\n","from matplotlib.patches import Ellipse\n","from scipy.spatial.distance import cdist\n","from sklearn.cluster import KMeans\n","from sklearn.datasets import load_digits, make_blobs, make_moons\n","from sklearn.decomposition import PCA\n","from sklearn.mixture import GaussianMixture\n","\n","import matplotlib.pyplot as plt\n","import numpy as np\n","import seaborn as sns \n","\n","sns.set()"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"FOR8prarVtcq"},"source":["Επίσης ορίζουμε και ορισμένες βοηθητικές συναρτήσεις"]},{"cell_type":"code","metadata":{"id":"ZOFbQNMZVzJs"},"source":["def plot_kmeans(kmeans, X, n_clusters=4, rseed=0, ax=None):\n"," \"\"\"\n"," Οπτικοποίηση της συσταδοποίσης του αλγορίθμου k-μέσων\n"," \"\"\"\n"," labels = kmeans.fit_predict(X)\n","\n"," # σχεδίαση των δειγμάτων εισόδου\n"," ax = ax or plt.gca()\n"," ax.axis('equal')\n"," ax.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis', zorder=2)\n","\n"," # οπτικοποίηση της αναπαράστασης του μοντέλου KMeans\n"," centers = kmeans.cluster_centers_\n"," radii = [cdist(X[labels == i], [center]).max() \n"," for i, center in enumerate(centers)]\n"," for c, r in zip(centers, radii):\n"," ax.add_patch(plt.Circle(c, r, fc='#CCCCCC', lw=3, alpha=0.5, zorder=1))\n","\n","\n","def draw_ellipse(position, covariance, ax=None, **kwargs):\n"," \"\"\"\n"," Σχεδιασμός μιας έλλειψης με δεδομένη θέση και συνδιασπορά\n"," \"\"\"\n"," ax = ax or plt.gca()\n"," \n"," # Μετασχηματισμός της συνδιασποράς σε κύριους άξονες\n"," if covariance.shape == (2, 2):\n"," U, s, Vt = np.linalg.svd(covariance)\n"," angle = np.degrees(np.arctan2(U[1, 0], U[0, 0]))\n"," width, height = 2 * np.sqrt(s)\n"," else:\n"," angle = 0\n"," width, height = 2 * np.sqrt(covariance)\n"," \n"," # Σχεδίαση της έλλειψης\n"," for nsig in range(1, 4):\n"," ax.add_patch(Ellipse(position, nsig * width, nsig * height, angle, \n"," **kwargs))\n"," \n"," \n","def plot_gmm(gmm, X, label=True, ax=None):\n"," \"\"\"\n"," Οπτικοποίηση της συσταδοποίσης των GMM\n"," \"\"\"\n"," ax = ax or plt.gca()\n"," labels = gmm.fit(X).predict(X)\n"," if label:\n"," ax.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis', zorder=2)\n"," else:\n"," ax.scatter(X[:, 0], X[:, 1], s=40, zorder=2)\n"," ax.axis('equal')\n"," \n"," w_factor = 0.2 / gmm.weights_.max()\n"," for pos, covar, w in zip(gmm.means_, gmm.covariances_, gmm.weights_):\n"," draw_ellipse(pos, covar, alpha=w * w_factor)\n","\n","def plot_digits(data):\n"," \"\"\"\n"," Σχεδιάση αριθμητικών ψηφίων\n"," \"\"\"\n"," fig, ax = plt.subplots(10, 10, figsize=(8, 8), subplot_kw=dict(xticks=[], \n"," yticks=[]))\n"," fig.subplots_adjust(hspace=0.05, wspace=0.05)\n"," for i, axi in enumerate(ax.flat):\n"," im = axi.imshow(data[i].reshape(8, 8), cmap='binary')\n"," im.set_clim(0, 16)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"asAFnhF9_Sf3"},"source":["## Οι \"αδυναμίες\" του αλγορίθμου $k$-μέσων\n","\n","Όπως είδαμε και σε προηγούμενο εργαστήριο, αν τα δεδομένα μας είναι \"απλά\" και καλά διαχωρισμένα μεταξύ τους, ο αλγόριθμος $k$-μέσων καταλήγει σε συσταδοποιήσεις που βγάζουν \"νόημα\". Ας δημιουργήσουμε 400 δείγματα δεδομένων στο δισδιάστατο χώρο, τα οποία χωρίζονται σε 4 περιοχές και ας τα απεικονίσουμε σε ένα διάγραμμα"]},{"cell_type":"code","metadata":{"id":"Ac9c5SQAXwMH"},"source":["X, y_true = make_blobs(n_samples=400, centers=4, cluster_std=0.6, \n"," random_state=0)\n","X = X[:, ::-1] \n","plt.scatter(X[:, 0], X[:, 1], s=40, cmap='viridis');"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"fbP9s5KHXxAa"},"source":["Αν τρέξουμε τον αλγόριθμο των $4$-μέσων, παρατηρούμε ότι ανακαλύπτει συστάδες που ταιριάζουν με αυτές που βρίσκουμε και εμείς οπτικά."]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"3-gDT3XU_Sf4"},"source":["# Αλγόριθμος 4-μέσων\n","kmeans = KMeans(4, random_state=0)\n","labels = kmeans.fit(X).predict(X)\n","\n","# Σχεδίαση συστάδων\n","plt.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis');\n"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"0mQj7cMI_Sf_"},"source":["Κοιτάζοντας το παραπάνω σχήμα, μπορούμε να συμπεράνουμε ότι η τοποθέτηση ορισμένων σημείων εντός μιας συστάδας είναι πιο \"σίγουρη\" από άλλα. Για παράδειγμα, φαίνεται να υπάρχει μια μικρή επικάλυψη μεταξύ των δύο μεσαίων συστάδων (μωβ και κίτρινης), τέτοια ώστε να μην έχουμε απόλυτη εμπιστοσύνη για την χωροθέτηση των σημείων στο όριο τους. Δυστυχώς, ο αλγόριθμος των $k$-μέσων δεν διαθέτει κάποιον εγγενή τρόπο για να μετράει την πιθανότητα (ή την αβεβαιότητα) της ανάθεσης των δειγμάτων στην εκάστοτε συστάδα. \n","\n","Ένας τρόπος θεώρησης των αναθέσεων που κάνει ο αλγόριθμος των $k$-μέσων είναι ότι αυτές εντάσσονται σε έναν κύκλο (ή, σε περίπτωση περισσότερων διαστάσεων, σε μια υπερ-σφαίρα) με κέντρο το κέντρο της συστάδας και μήκος ακτίνας που καθορίζεται από το πιο απομακρυσμένο σημείο της. Η ακτίνα αυτή λειτουργεί ως ένα \"σκληρό\" κατώφλι για τα δείγματα που χαρακτηρίζονται μέλη της συστάδας: κάθε σημείο που βρίσκεται εκτός του κύκλου δεν θεωρείται μέλος.\n","\n","Μπορούμε να οπτικοποιήσουμε τη συγκεκριμένη ανάθεση, όπως παρακάτω:"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"WdhbDHxP_SgI"},"source":["plot_kmeans(kmeans, X)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"4PQbldo2_SgL"},"source":["Παρατηρούμε δηλαδή πως ο αλγόριθμος των $k$-μέσων κατασκευάζει κυκλικές (σφαιρικές) συστάδες. \n","\n","Ας μετασχηματίσουμε τα δεδομένα, \"τραβώντας\" τα κατά τον άξονα των $x$."]},{"cell_type":"code","metadata":{"id":"Ggo8-DopXIs7"},"source":["rng = np.random.RandomState(13)\n","X_stretched = np.dot(X, rng.randn(2, 2))\n","plt.scatter(X_stretched[:, 0], X_stretched[:, 1], s=40, cmap='viridis');"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"5epHbl-yXMfR"},"source":["Ας ξανατρέξουμε τον αλγόριθμο των $4$-μέσων στα νέα, \"τραβηγμένα\" δείγματα δεδομένων"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"bDbBpiVd_SgM"},"source":["kmeans = KMeans(n_clusters=4, random_state=0)\n","plot_kmeans(kmeans, X_stretched)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"1hvX8NMM_SgO"},"source":["Παρατηρούμε ότι πλέον ο αλγόριθμος των $4$-μέσων έχει \"ανακατέψει\" τα δείγματα εντός των συστάδων και έχει κάνει αναθέσεις στις περιπτώσεις της πράσινης, κίτρινης και μπλε συστάδας που δεν είναι σύμφωνες με αυτό που παρατηρούμε εμείς οπτικά.\n","\n","Αυτό οφείλεται στο γεγονός ότι οι νέες συστάδες που έχουν δημιουργηθεί μετά τον μετασχηματισμό των δεδομένων έπαψαν πλέον να είναι κυκλικές και έγιναν ελλειψοειδείς. Ωστόσο, ο αλγόριθμος των $k$-μέσων δεν μπορεί να προσαρμοστεί στη νεά δομή των δεδομένων: αντίθετα προσπαθεί να τα κάνει να χωρέσουν εντός των 4 κυκλικών συστάδων κάνοντας εν τέλει αναθέσεις που δεν τις θεωρούμε ορθές. \n","\n","Μια λύση σε αυτό το πρόβλημα θα μπορούσε να είναι η χρήση τεχνικών όπως η *ανάλυση κυρίων συνιστωσών* (principal component analysis - PCA) για να προβάλλουμε τα δεδομένα μας σε ένα νέο χώρο, όπου θα είναι περισσότερο κυκλικά. Ωστόσο, αυτή η πρακτική δεν είναι εγγυημένο ότι θα λειτουργεί σε κάθε περίπτωση.\n","\n","Συνεπώς, χρειάζεται να βρούμε τρόπους αντιμετώπισης των δύο κύριων αδυναμιών του αλγορίθμου των $k$-μέσων:\n","\n","1. Της έλλειψης προσαρμοστικότητας, όσον αφορά το σχήμα των συστάδων.\n","2. Της μη-πιθανοτικής ανάθεσης των δειγμάτων στις συστάδες.\n","\n","Αυτές τις δύο αδυναμίες αντιμετωπίζει μια άλλη κατηγορία αλγορίθμων συσταδοποίησης, τα γκαουσιανά μοντέλα μείξης."]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"i2nPbGgD_SgP"},"source":["## Τα γκαουσιανά μοντέλα μείξης\n","\n","Ένα γκαουσιανό μοντέλο μείξης προσπαθεί να βρει μια μείξη πολυδιάστατων γκαουσιανών κατανομών, οι οποίες μπορούν να μοντελοποιήσουν κάθε σύνολο δεδομένων.\n","\n","Στην απλούστερη περίπτωση, τα GMM μπορούν να χρησιμοποιηθούν για την εύρεση παρόμοιας μορφής συστάδων (σφαιρικές) με τον αλγόριθμο των $k$-μέσων."]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"Gl3sMneh_SgQ"},"source":["gmm = GaussianMixture(n_components=4).fit(X)\n","labels = gmm.predict(X)\n","plt.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis');"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"DLmQwd32_SgU"},"source":["Ωστόσο, ο πιθαντικός τους χαρακτήρας τους επιτρέπει να κάνουν (πιθανοτικές) αναθέσεις. Στην περίπτωση του scikit-learn, αυτό υλοποιείται με την μέθοδο ``predict_proba``, η οποία επιστρέφει έναν πίνακα μεγέθους ``[n_samples, n_clusters]``, που περιέχει την πιθανότητα ενός σημείου να ανήκει σε μια συστάδα."]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"KgIYhiih_SgW"},"source":["probs = gmm.predict_proba(X)\n","print(probs[:5].round(3))"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"3kokyLzg_Sga"},"source":["Μπορούμε να οπτικοποιήσουμε αυτή την πιθανότητα (ή εναλλακτικά ασάφεια), μεταβάλλοντας για κάθε σημείο την ακτίνα του ανάλογα με τη βεβαιότητα τις πρόβλεψης.\n"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"gXclVwGl_Sgb"},"source":["# ο τετραγωνισμός της πιθανότητας θα κάνει πιο εμφανείς τις διαφορές\n","size = 50 * probs.max(1) ** 2 \n","plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', s=size);"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"B16EKueM_Sgh"},"source":["Έτσι, στο παραπάνω σχεδιάγραμμα, τα σημεία που είναι στο όριο μεταξύ των δύο συστάδων στο κέντρο, έχουν μικρότερη ακτίνα.\n","\n","Γενικότερα, τα GMM λειτουργούν όπως και ο αλγόριθμος των $k$-μέσων, δηλαδή βασίζονται σε μια διαδικασία *αναμονής-μεγιστοποίησης* (expectation-maximation ή EM), της οποίας τα βήματα περιγράφονται σε αδρές γραμμές παρακάτω:\n","\n","1. Ξεκίνα με μια αρχική υπόθεση για την θέση και το σχήμα των συστάδων\n","\n","2. Επανέλαβε τα δύο παρακάτω βήματα μέχρι τη σύγκλιση:\n","\n"," 1. Βήμα **Αναμονής** (expectation): για κάθε δείγμα, βρες τα βάρη που κωδικοποιούν την πιθανότητα συμμετοχής του κάθε δείγματος σε κάθε συστάδα\n"," 2. Βήμα **Μεγιστοποίησης** (maximization): Ενημέρωσε την τοποθεσία και το σχήμα της κάθε συστάδας, χρησιμοποιώντας **όλα** τα δείγματα δεδομένων\n"," \n","Το αποτέλεσμα αυτής της διαδικασίας είναι ότι πλέον η κάθε συστάδα δεν χαρακτηρίζεται από μια σφαίρα με σκληρό κατώφλι, αλλά από ένα πιο ομαλό γκαουσιανό μοντέλο. \n","\n","Όπως και στην περίπτωση του αλγορίθμου $k$-μέσων, τα GMM ενδέχεται να μην προσεγγίσουν τη βέλτιστη λύση και για αυτό το λόγο στην πράξη απαιτούνται πολλαπλές τυχαίες αρχικοποιήσεις. \n","\n","Ας σχεδιάσουμε τις περιοχές των δεδομένων που εντοπίζει το γκαουσιανό μας μοντέλο"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"ExsZJiV8_Sgn"},"source":["plot_gmm(gmm, X)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"Ww-R8ulG_Sgr"},"source":["Όπως και προηγουμένως, ας δοκιμάσουμε να συσταδοποιήσουμε με GMM τα \"τραβηγμένα\" δεδομένα"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"5HcsqxEz_Sgs"},"source":["gmm = GaussianMixture(n_components=4, covariance_type='full', random_state=42)\n","plot_gmm(gmm, X_stretched)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"lBPr07Lg_Sgx"},"source":["Παρατηρούμε ότι τα GMM προσαρμόστηκαν στα χαρακτηριστικά των δεδομένων μας, πετυχαίνοντας σχεδόν βέλτιστη συσταδοποίηση. Συνεπώς, μπορούμε να ισχυριστούμε ότι τα GMM αντιμετώπισαν επιτυχώς και τις δύο κύριες αδυναμίες του αλγορίθμου των $k$-μέσων"]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"PxyDKde8_Sgx"},"source":["### Επιλογή του τύπου της συνδιασποράς\n","\n","Μια πιο προσεκτική ματιά στα αμέσως προηγούμενα κελιά κώδικα, μας φανερώνει ότι η παράμετρος ``covariance_type`` άλλαξε στις διαφορετικές περιπτώσεις.\n","\n","Η συγκριμένη επιλογή καθορίζει τους βαθμούς της ελευθερίας όσον αφορά το σχήμα κάθε συστάδας και για αυτό πρέπει να καθορίζεται προσεκτικά, ανάλογα με την περίσταση. Η default τιμή της είναι ``covariance_type=\"diag\"``, το οποίο επιτρέπει το μέγεθος της συστάδας να καθορίζεται ανεξάρτητα σε κάθε διάσταση, ωστόσο οι άξονες της έλλειψης θα πρέπει να ευθυγραμμίζονται με τους άξονες των δεδομένων.\n","\n","Στην περίπτωση που θέσουμε ``covariance_type=\"spherical\"``, τότε το μέγεθος της κάθε συστάδας θα πρέπει να είναι ίδιο σε όλες τις διαστάσεις, οπότε και οδηγούμαστε σε σφαιρικές συστάδες. \n","\n","Τέλος, στην περίπτωση που θέσουμε ``covariance_type=\"full\"``, τότε η κάθε συστάδα μπορεί να λάβει ένα ελλειψοειδές σχήμα οποιουδήποτε προσανατολισμού. "]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"__5K8O0y_Sgy"},"source":["![(Covariance Type)](https://github.com/jakevdp/PythonDataScienceHandbook/blob/master/notebooks/figures/05.12-covariance-type.png?raw=1)"]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"6Kltd_tt_Sgz"},"source":["## Χρήση των GMM ως εκτιμητών πυκνότητας\n","\n","Παρότι τα GMM μπορούν να συσταδοποιήσουν ένα χώρο δεδομένων η πρωταρχική τους χρήση είναι ως *εκτιμητές πυκνότητας*, δηλαδή ως *παραγωγικά πιθανοτικά μοντέλα* (generative probabilistic models) τα οποία περιγράφουν την κατανομή των δεδομένων.\n","\n","Αυτό γίνεται ευκολότερα κατανοητό στο παρακάτω παράδειγμα, όπου δημιουργούμε συνθετικά δεδομένα με την χρήση της μεθόδου ``make_moons`` του scikit-learn"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"943lAemU_Sg0"},"source":["\n","Xmoon, ymoon = make_moons(200, noise=.05, random_state=0)\n","plt.scatter(Xmoon[:, 0], Xmoon[:, 1]);"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"sLixx8GH_Sg3"},"source":["Αν προσπαθήσουμε να συσταδοποιήσουμε αυτόν τον χώρο με ένα GMM 2 στοιχείων, τότε το αποτέλεσμα που παίρνουμε δεν είναι ικανοποιητικό"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"n-lYq4nj_Sg4"},"source":["gmm2 = GaussianMixture(n_components=2, covariance_type='full', random_state=0)\n","plot_gmm(gmm2, Xmoon)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"sYQo5ziM_Sg8"},"source":["Αν, ωστόσο, χρησιμοποιήσουμε περισσότερα στοιχεία και αγνοήσουμε τις ετικέτες των δεδομένων, λαμβάνουμε μια πολύ ικανοποιητική προσέγγιση της κατανομής του χώρου δεδομένων"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"Vi3KDWt5_Sg9"},"source":["gmm16 = GaussianMixture(n_components=16, covariance_type='full', random_state=0)\n","plot_gmm(gmm16, Xmoon, label=False)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"zhqihr6i_ShJ"},"source":["Σε αυτή την περίπτωση, η μείξη 16 γκαουσιανών δεν μας βοηθά στο να συσταδοποιήσουμε τον χώρο, αλλά να μοντελοποιήσουμε την ολική *κατανομή* των δειγμάτων. Άρα παίρνουμε ένα παραγωγικό μοντέλο της κατανομής, υπό την έννοια ότι τα GMM μας δίνουν τη δυνατότητα να δημιουργήσουμε νέα δείγματα δεδομένων, τα οποία υπακούν στην κατανομή των δεδομένων που ήδη έχουμε.\n","\n","Συμπερασματικά, μπoρούμε να ισχυριστούμε ότι με τα GMM μπορoύμε να μοντελοποιήσουμε την οποιαδήποτε (πολυδιάστατη) κατανομή δεδομένων."]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"mqAe2SMW_ShR"},"source":["### Προσδιορισμός του πλήθους των στοιχείων\n","\n","Ένα ζήτημα που προκύπτει είναι ο ακριβής προσδιορισμός του πλήθους των στοιχείων που χρειάζονται για να προσεγγίσουν την υποκείμενη κατανομή των δεδομένων. Είδαμε πως στην περίπτωση που χρησιμοποιούμε λίγα στοιχεία, έχουμε ένα είδος *υπο-προσαρμογής* (underfitting). \n","\n","Αν, ωστόσο, το πλήθος των στοιχείων είναι πολύ μεγαλύτερο, τότε μπορεί πολύ εύκολα να καταλήξουμε στο άλλο άκρο, αυτό της *υπερ-προσαρμογής* (overfitting), δηλαδή πλέον να μην προσεγγίζουμε τη συνολική *πιθανοφάνεια* των δεδομένων, αλλά την πιθανότητα ύπαρξης συγκεκριμένων δειγμάτων δεδομένων.\n","\n","Για να αποφύγουμε αυτές τις δύο περιπτώσεις, συνήθως χρησιμοποιούμε ορισμένα κριτήρια, όπως τα [Akaike information criterion (AIC)](https://en.wikipedia.org/wiki/Akaike_information_criterion) ή το [Bayesian information criterion (BIC)](https://en.wikipedia.org/wiki/Bayesian_information_criterion). Και τα δύο προαναφερόμενα κριτήρια υποστηρίζονται απ' την κλάση ``GaussianMixture`` του scikit-learn, οπότε θα σχεδιάσουμε τις τιμές τους ανάλογα με το πλήθος των στοιχείων του μοντέλου."]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"Dk5WaiPa_ShS"},"source":["n_components = np.arange(1, 21)\n","models = [GaussianMixture(n, covariance_type='full', random_state=0).fit(Xmoon)\n"," for n in n_components]\n","\n","bics = [m.bic(Xmoon) for m in models]\n","aics = [m.aic(Xmoon) for m in models]\n","\n","plt.plot(n_components, bics, label='BIC')\n","plt.plot(n_components, aics, label='AIC')\n","plt.legend(loc='best')\n","plt.xlabel('Πλήθος στοιχείων');"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"P3BNfwmlfRsy"},"source":["print('Ελαχιστοποίηση AIC στα {} στοιχεία του GMM'.format(\n"," n_components[aics.index(min(aics))])\n",")\n","print('Ελαχιστοποίηση BIC στα {} στοιχεία του GMM'.format(\n"," n_components[bics.index(min(bics))])\n",")"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"sgC88UKD_ShU"},"source":["Το βέλτιστο πλήθος των στοιχείων είναι αυτό που ελαχιστοποιεί είτε το AIC είτε το BIC, ανάλογα με το ποια προσέγγιση χρησιμοποιούμε σε κάθε περίπτωση. Σύμφωνα με το AIC η βέλτιστη επιλογή είναι στα 11 στοιχεία, ενώ σύμφωνα με το BIC, η βέλτιστη επιλογή είναι τα 6 στοιχεία (εν γένει, το BIC προτείνει απλούστερα μοντέλα σε σύγκριση με το AIC).\n","\n","Ας σχεδιάσουμε παρακάτω και τις δύο περιπτώσεις, ξεκινώντας με το απλούστερο μοντέλο"]},{"cell_type":"code","metadata":{"id":"zcKnJLqv58nF"},"source":["gmm6 = GaussianMixture(n_components=6, covariance_type='full', random_state=0)\n","plot_gmm(gmm6, Xmoon, label=False)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"lj6-a6fj6D-W"},"source":["Τέλος, ας σχεδιάσουμε το βέλτιστο παραγωγικό μοντέλο σύμφωνα με το AIC"]},{"cell_type":"code","metadata":{"id":"a18-Xzdf6JPX"},"source":["gmm11 = GaussianMixture(n_components=12, covariance_type='full', random_state=0)\n","plot_gmm(gmm11, Xmoon, label=False)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"lrYss7Lm_ShV"},"source":["## Δημιουργία νέων δεδομένων με το GMM\n","\n","Μέχρι στιγμής, έχουμε δει πως τα GMM χρησιμοποιούνται για τη συσταδοποίηση δεδομένων καθώς και ως εκτιμητές πυκνότητας. Στη συνέχεια, θα δούμε και πως μπορούν να λειτουργήσουν ως παραγωγικά μοντέλα, δημιουργώντας νέα δείγματα δεδομένων σύμφωνα με την υποκείμενη κατανομή που έχουν προσεγγίσει.\n","\n","Στο παράδειγμα που ακολουθεί, θα φορτώσουμε ένα σύνολο δεδομένων *οπτικής αναγνώρισης χαρακτήρων* (optical character recognition - OCR) και πιο συγκεκριμένα, αριθμητικών ψηφίων, όπως αυτά έχουν γραφτεί από διαφορετικούς ανθρώπους. Επίσης θα εμφανίσουμε τα πρώτα 100 από αυτά"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"tepPfAp-_ShX"},"source":["digits = load_digits()\n","print(digits.data.shape)\n","plot_digits(digits.data)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"N1pvinan_Shb"},"source":["Συνολικά έχουμε σχεδόν 1.800 ψηφία σε 64 διαστάσεις και επιθυμούμε να φτιάξουμε ένα GMM για να μπορούμε να δημιουργούμε δικά μας ψηφία. Επειδή σε ένα τόσο μεγάλο χώρο το GMM ενδέχεται να καθυστερήσει πολύ, πρώτα θα τα απεικονίσουμε σε ένα χώρο μικρότερων διαστάσεων, χρησιμοποιώντας PCA και ζητώντας να διατηρηθεί στο νέο χώρο το 97% της διακύμανσης των αρχικών δεδομένων"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"UHy59Kj3_Shg"},"source":["pca = PCA(0.97, whiten=True)\n","data = pca.fit_transform(digits.data)\n","data.shape"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"LCjNgWmg_Shi"},"source":["Βλέπουμε ότι πετυχαίνουμε μια μείωση των διαστάσεων σχεδόν στο μισό, με ελάχιστη απώλεια πληροφορίας. Σε αυτόν τον μειωμένο χώρο διαστάσεων, ας χρησιμοποιήσουμε το κριτήριο AIC για να προσεγγίσουμε το πλήθος των στοιχείων του GMM"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"yACLL3Gb_Shj"},"source":["n_components = np.arange(50, 210, 10)\n","models = [GaussianMixture(n, covariance_type='full', random_state=0) \n","for n in n_components]\n","aics = [model.fit(data).aic(data) for model in models]\n","plt.plot(n_components, aics);"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"_FiVYCRkd0ec"},"source":["print('Ελαχιστοποίηση AIC στα {} στοιχεία του GMM'.format(\n"," n_components[aics.index(min(aics))])\n",")"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"NVrqgoGL_Shm"},"source":["Απ' ότι φαίνεται, το κριτήριο αυτό ελαχιστοποιείται στα 180 στοιχεία, τα οποία και θα χρησιμοποιήσουμε."]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"pYyNU_2i_Shn"},"source":["gmm = GaussianMixture(180, covariance_type='full', random_state=0)\n","gmm.fit(data)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"sNwoq_7G_Shq"},"source":["Κατόπιν θα δειγματοληπτίσουμε 100 νέα δείγματα δεδομένων, χρησιμοποιώντας το GMM ως παραγωγικό μοντέλο"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"RDsFc1uS_Shq"},"source":["data_new = gmm.sample(len(data))\n","t1 = data_new[0]"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"f9LeH8RY_Sht"},"source":["Τέλος θα χρησιμοποιήσουμε τον αντίστροφο μετασχηματισμό για να μεταβούμε από το χώρο των χαμηλότερων διαστάσεων στον αρχικό χώρο και θα εμφανίσουμε τα ψηφία που δημιουργήσαμε"]},{"cell_type":"code","metadata":{"deletable":true,"editable":true,"id":"T-TJRCFP_Sht"},"source":["digits_new = pca.inverse_transform(t1)\n","plot_digits(digits_new)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"deletable":true,"editable":true,"id":"t7euFjAN_Shv"},"source":["Από το αποτέλεσμα μπορούμε να κρίνουμε πως φαίνονται σαν κανονικά ψηφία του συνόλου δεδομένων μας (και όχι ως θόρυβος)!\n","\n","Συνοψίζοντας, αυτό που πετύχαμε στη συγκεκριμένη περίπτωση είναι το εξής: μοντελοποιήσαμε την υποκείμενη κατανομή δεδομένων ενός δείγματος χειρόγραφων αριθμητικών ψηφίων με ένα GMM και έτσι μπορέσαμε να παράξουμε νέα χειρόγραφα ψηφία, τα οποία δεν υπάρχουν στην αρχική συλλογή δεδομένων. Με άλλα λόγια, κατορθώσαμε να μάθουμε τα στατιστικά χαρακτηριστικά των χειρόγραφων ψηφίων."]}]}