import numpy as np
import scipy
import sklearn
import matplotlib.pyplot as plt
from functions import *
from sklearn import manifold, datasets
from sklearn.manifold import TSNE

"""
Explanation: t-SNE Tutorial
End of explanation
"""


def plot_2D_cluster(cluster_size, perplexity):
    pass

"""
Explanation: Zklastrowane punkty w 2D
Działanie t-SNE na dwóch oddalonych od siebie klastrach punktów w 2D
Zadanie 1
Napisz funkcję, która pokaże punkty ze zbioru przed oraz po transformacji t-SNE z zadaną wielkością zbioru oraz perplexity, użyj sklearn.manifold.TSNE inicjalizowane PCA, resztę parametrów pozostaw jako domyślną.
Dokumentacja t-SNE
Funkcje pomocnicze:
point_cluster(cluster_size) - generuje losowe dwa klastry punktów 2D o rozmiarze cluster_size wraz z ich kolorami
plot_2D(data, colors) - rysuje wykres punktów ze współrzędnymi data oraz kolorami z colors
End of explanation
"""


data, colors = point_cluster_multi(100)

plot_2D(data, colors)

"""
Explanation: Korzystając z napisanej funkcji pokaż jak zachowuje się t-SNE dla kilku różnych wielkości klastrów (w granicach 10 - 400) i różnych wartości perplexity
Zadanie 2
Pokaż zależność różnicy (np. jako błędu średniokwadratowego znormalizowanych danych) pomiędzy oryginalnymi, a zredukowanymi odległościami pomiędzy parami punktów w zależności od perplexity. Na wykresie rozróżnij różnicę odległości w bliskim oraz dalekim sąsiedztwie.
Sprawdź jak wygląda wykres dla małych wielkości klastra (np. 10 - 50) oraz dużych (np. 200 - 300). Pokaż co dzieje się z punktami w różnych częściach wykresu.
Zalecany przez autora przedział perplexity to 5 - 50. Sprawdź co dzieje się z ww. różnicą poza tym przedziałem.
Proponowane parametry t-SNE:
- inicjalizacja PCA
- nieco obniżone względem domyślnego learning_rate, np. 500
Pomocne funkcje:
pairwise_distances(points) - zwraca macierz euklidesowych odległości między punktami w której komórka i,j oznacza odległość między punktem i a j
np.where(condition[, x, y]) - dokumentacja
Punkty w wielu wymiarach
Prosty przyklad przedstawiajacy powiększenie mniejszego klastra punktów w wyniku przeprowadzenia redukcji t-SNE
Załadowanie zbioru danych
End of explanation
"""


digits = datasets.load_digits(n_class=6)
X = digits.data

"""
Explanation: Zadanie 3
Przeprowadź redukcję wymiarów przy pomocy t-SNE
Wyświetl reprezentację graficzną zredukowanego zbioru przy pomocy funkcji plot_2D
Zmieniając parametry spróbuj doprowadzić do sytuacji w której niebieskie punkty znajdują sie bliżej siebie w centrum. 
Wykorzystaj zmianę parametru learning_rate.
Zbiór ręcznie napisanych cyfr
Załadowanie zbioru danych
End of explanation
"""


faces = datasets.fetch_olivetti_faces()
draw_faces(faces)

"""
Explanation: Zadanie 4
Przeprowadź redukcję przy pomocy t-SNE
Wyświetl wizualizację zredukowanego zbioru przy pomocy funkcji plot_digits(zbiór zredukowany, pierwotny zbiór cyfr)
Zbiór zdjęć twarzy
Załadowanie zbioru danych
End of explanation
"""


