====== 12. Aplikace I. ====== # Import modulu import numpy as np # modul pro praci s vektory/maticemi import pandas as pd # modul na analyzu dat import matplotlib.pyplot as plt # modul pro kresleni grafu # magicky vyraz pro vykreslovani dat %matplotlib inline ===== NumPy ===== Numpy logo * Knihovna Numpy umožňuje **praktické**, **rychlé** a **pohodlné** řešení matematických úloh * Domovská stránka projektu: https://numpy.org/ * Vhodné zejméma v případě technických výpočtů (zpracování signálů, ale nejen to) * Podstatou Numpy je datový typ ndarray (1D a více rozměrná pole prvků stejného typu a stejné dimenzionality v každém směru) * Práce s tímto polem je v mnohém velmi odlišná od práce s datovým typem seznam v Pythonu ==== 1D ==== pole = np.array([1,2,3],dtype=float) print(pole) print(type(pole)) print('dimenze pole', pole.ndim) print('tvar pole', pole.shape) pole.dtype ==== 2D ==== pole = np.arange(0,10) matice = pole.reshape(2,5) # pretvaruje 1D pole na 2D pole s 2 radky a 5 sl. print(matice) print(matice.transpose()) # transponuje matici, pripadne matice.T * Narování pole do 1D: ''%%ravel()%%'' (vraci odkaz) a ''%%flatten()%%'' (vraci kopii) matice2 = matice.copy() print('Originalni matice:\n', matice2,'\n') pole2 = matice2.flatten() # prevod z matice na vektor pole2[0] = 10 # uprava prvniho prvku print('Flatten\nVektor: ',pole2,'\n') print('Originalni matice:\n', matice2,'\n') pole3 = matice2.ravel() pole3[0] = 10 print('Ravel\nVektor: ',pole3,'\n') print('Originalni matice:\n', matice2,'\n') ==== Indexování ==== print(matice2[0,0]) print(matice2[0][0]) print(matice2[matice2>5]) ==== Matematické operace ==== vektor1 = np.array([1,2,3,4]) vektor2 = vektor1.copy() + 2 print(vektor1, vektor2,'\n') # scitani prvek po prvku print(vektor1+vektor2,'\n') # nasobeni prvek po prvku print(vektor1*vektor2) print(np.multiply(vektor1,vektor2),'\n') print(vektor1@vektor2) # skalarni soucin v pripade dvou vektoru, maticove nasobeni v pripade matic print(np.dot(vektor1,vektor2)) # skalarni soucin / dot product print(np.matmul(vektor1,vektor2),'\n') # maticove nasobeni / skalarni soucin print(np.outer(vektor1,vektor2),'\n') # vektorovy soucin / outer product mat = vektor1.reshape(2,2) print('determinant matice: ', np.linalg.det(mat),'\n') # vsimnete si vysledku (problem s presnosti, vysledek by mel byt -2) print('inversni matice') inv_m = np.linalg.inv(mat) print(inv_m,'\n') # problem s presnosti print(mat@inv_m) print(np.dot(mat,inv_m)) # skalarni soucin / dot product ===== Matplotlib a pandas ===== Matplotlib logo * Nejpoužívanější nástroj na vizualizaci dat * Práce s objekty ''%%figure%%'', ''%%axes%%'', ''%%line%%'',... * https://matplotlib.org/ pandas logo * Nástroj na manipulaci/analýzu dat * Práce s tzv. DataFrames * https://pandas.pydata.org ==== Načítání dat (csv) ==== df = pd.read_csv('nfl_2013.csv') # https://gist.github.com/craigmbooth/5a9be04fe72d77fa3cff # mozno specifikovat jaky datovy typ je v kazdem sloupci #df = pd.read_csv('nfl_2013.csv', dtype={'cislo': int, 'pozice':str, 'jmeno':str, 'vyska_inch':float, 'vaha_lbs':float, 'team':str}) df.head() # .head ukaze prvnich N prvku, kde vychozi hodnota N=5 #df.tail() # jako .head, ale ukazuje poslednich N prvku ==== Dopočet dat ==== df['vyska_cm'] = df['vyska_inch'] * 2.54 df['vaha_kg'] = df['vaha_lbs'] * 0.4536 df['vek'] = (pd.to_datetime('1/1/2013') - pd.to_datetime(df['datum_narozeni'])).astype(' ==== Informace o daném dataframu ==== print(df.columns,'\n') # vypis velicin print(df.index,'\n') # vypis poctu prvku print(df.dtypes,'\n') # vypis datovych typu pro jednotlive sloupce df.info() # podobne jako drive uvedene metody df.describe() #import qgrid #widget = qgrid.show_grid(df, show_toolbar=True) #widget ===== Vykreslovani dat ===== osa_x = 'vaha_kg' osa_y = 'vyska_cm' _= df.plot.scatter( x=osa_x, y=osa_y, alpha=0.1, #c='b', title='Korelace: {0:.3f}'.format(df[osa_x].corr(df[osa_y])) ) === Korelace === corr = df.corr() corr.style.background_gradient() #cmap='coolwarm_r' === Vykresleni pomoci Matplotlibu === osa_x = 'vaha_kg' osa_y = 'vyska_cm' #plt.scatter(x=osa_x,y=osa_y,data=df, alpha=0.1) #plt.title('Korelace: {0:.3f}'.format(df[osa_x].corr(df[osa_y]))) #plt.show() # dopocet trendu (pomoci polynomu N-teho radu) deg = 2 # polynom druheho radu pfit = np.polynomial.polynomial.polyfit(df[osa_x], df[osa_y], deg) y_fitted = np.polynomial.polynomial.polyval(df[osa_x],pfit) fig, ax = plt.subplots() ax.scatter(x=osa_x,y=osa_y,data=df, alpha=0.1, color='teal') ax.plot(df[osa_x],y_fitted,'.', alpha=0.1,color='black') # hodnoty polynomu ziskaneho fitovanim polynomu 2 radu do bodu ax.set_xlabel(osa_x) ax.set_ylabel(osa_y) ax.set_title('Korelace: {0:.3f}'.format(df[osa_x].corr(df[osa_y]))) plt.show() === Histogram === # https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.hist.html _ = df.hist(layout=(1,6), figsize=(20,3), density=False) # https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.loc.html #df.loc[df['pozice']=='C']['vyska_cm'].plot.hist(subplots=False, alpha=0.4) df.loc[df['vek']>25]['vyska_cm'].plot.hist(subplots=False) _ = df.groupby(by='pozice')['vyska_cm'].plot.hist(subplots=False, alpha=0.4) # Histogramy podle pozici fig, ax = plt.subplots(5, 5, figsize=(20, 10)) for id, pozice in enumerate(pd.unique(df['pozice'])): #for r in range(5): # for c in range(5): c = id%5 r = id//5 _, bins, _ = ax[r, c].hist(df.groupby(by='pozice').get_group(pozice)['vyska_cm'], density=False, bins=10) #_, bins, _ = ax[r, c].hist(df.groupby(by='pozice').get_group(pozice)['vek']) #ax[r, c].set_xticks(bins) ax[r, c].set_title(pozice) plt.subplots_adjust(hspace=.5, wspace=.5) plt.show() osa_x = 'vaha_kg' osa_y = 'vyska_cm' podminka = df['vek']<=25 #podminka = df['pozice']=='RB' #podminka = df['team']=='ATL' fig, axs = plt.subplots(1,2) axs[0].hist2d(df.loc[podminka][osa_x], df.loc[podminka][osa_y], bins=20) axs[1].hist2d(df.loc[~podminka][osa_x], df.loc[~podminka][osa_y], bins=20) axs[0].set(xlim=(min(df[osa_x]),max(df[osa_x]))) axs[1].set(xlim=(min(df[osa_x]),max(df[osa_x]))) axs[0].set(ylim=(min(df[osa_y]),max(df[osa_y]))) axs[1].set(ylim=(min(df[osa_y]),max(df[osa_y]))) plt.show() === Box plot === * https://en.wikipedia.org/wiki/Box_plot _ = df.boxplot(column='vek', by='pozice', figsize=(20,10), grid=False) #_ = df.boxplot(column='vyska_cm', by='team', figsize=(20,10), grid=False) === Převod do numpy === np_table = df.to_numpy() # prevod do numpy matice print(type(np_table)) print(np_table.shape) ====== Rozpoznávání ručně psaných čísel ====== Příklad je postavený na [[https://scikit-learn.org/stable/auto_examples/classification/plot_digits_classification.html#sphx-glr-auto-examples-classification-plot-digits-classification-py|jednom z ukázkových příkladů]] dostupných na [[https://scikit-learn.org/stable/auto_examples/index.html|webu]]. ===== scikit-learn ===== scikit-learn logo * Knihovna zaměřená na strojové učení * Dá se částečně použít i na neuronové sítě, avšak pouze do malé míry * Frameworky zaměřené na návrh neuronových sítí: [[https://www.tensorflow.org|Tensorflow]], [[https://pytorch.org|PyTorch]], aj. from sklearn import datasets, svm, metrics from sklearn.neural_network import MLPClassifier from sklearn.model_selection import train_test_split digits = datasets.load_digits() # nacteni interniho datasetu # dataset obsahuje cernobile snimky o velikosti 8x8 pixelu # Vykresleni 4 snimku _, axes = plt.subplots(nrows=1, ncols=4, figsize=(10, 3)) for ax, image, label in zip(axes, digits.images, digits.target): ax.set_axis_off() ax.imshow(image, cmap=plt.cm.gray_r, interpolation="nearest") ax.set_title("Label: %i" % label) # dataset obsahuje vice klicu - hlavni jsou images a target print(digits.keys()) ===== Klasifikace ===== Rozpoznávání čísel (rostlin, zvířat, lidí, věcí, apod[[https://youtu.be/u-PHP7TRu7A|.]]), patří pod tzv. klasifikaci. Cílem je predikovat co za číslo je na daném vstupním obrázku (rozložení pravděpodobnosti). Pro správný trénink se z pravidla rozdělí dataset na trénovací a testovací množinu. Cílem je navrhnout takový algoritmus/model, který bude dobře fungovat nejen na známe trénovací množině, ale také na //neznáme// testovací množině. ==== SVM ==== * SVM = support vector machinces - https://en.wikipedia.org/wiki/Support_vector_machine * SVM převedou vstupní znaky do roviny, kterou budou následně dělit tak, aby jednotlivé body spadaly co nejlépe do jednotlivých klasifikačních kategorii * Interaktivni ukazka napr. na https://greitemann.dev/svm-demo # převod snímků na vektory hodnot n_samples = len(digits.images) data = digits.images.reshape((n_samples, -1)) # Tvorba klasifikátoru # https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html?highlight=svc#sklearn.svm.SVC clf = svm.SVC() ''' # Uprava vstupnich parametru clf = svm.SVC( C=0.5, kernel='poly', gamma=0.005, verbose=False, max_iter=1 ) ''' # Rozdeleni dat - dle poctu delime na 50/50, pripadne casteji na 70/30 nebo 80/20 X_train, X_test, y_train, y_test = train_test_split( data, digits.target, test_size=0.5, shuffle=False ) # Trenink (s vyuzitim vychozich hodnot pro vstupni parametry) clf.fit(X_train, y_train) # Predikce na testovacich datech predicted = clf.predict(X_test) # Hodnoceni uspesnosti predikce na trenovacich a testovacich datech print("Training set score: %f" % clf.score(X_train, y_train)) print("Test set score: %f" % clf.score(X_test, y_test)) Vizualizace vysledku _, axes = plt.subplots(nrows=1, ncols=4, figsize=(10, 3)) for ax, image, prediction in zip(axes, X_test, predicted): ax.set_axis_off() image = image.reshape(8, 8) ax.imshow(image, cmap=plt.cm.gray_r, interpolation="nearest") ax.set_title(f"Predikce: {prediction}") Hodnocení navrženého klasifikátoru pomocí metrik print( f"Classification report for classifier {clf}:\n" f"{metrics.classification_report(y_test, predicted)}\n" ) Výpočet tzv. confusion matrix (neboli [[https://cw.fel.cvut.cz/b181/_media/courses/a6m33dvz/dvz2016-05a-roc.pdf|matice záměn]]) disp = metrics.ConfusionMatrixDisplay.from_predictions(y_test, predicted) disp.figure_.suptitle("Confusion Matrix") print(f"Confusion matrix:\n{disp.confusion_matrix}") plt.show() ==== NN ==== Interaktivní úvod do neuronových sítí dostupný na http://playground.tensorflow.org/, případně na http://www.r2d3.us. import warnings from sklearn.exceptions import ConvergenceWarning # https://scikit-learn.org/stable/modules/generated/sklearn.neural_network.MLPClassifier.html mlp = MLPClassifier() ''' mlp = MLPClassifier( random_state=1, max_iter=200, activation='relu', solver='adam', batch_size=16, alpha=0.5, learning_rate_init=0.0001, learning_rate='adaptive', hidden_layer_sizes=(10,) ) ''' with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=ConvergenceWarning, module="sklearn") mlp.fit(X_train, y_train) print("Training set score: %f" % mlp.score(X_train, y_train)) print("Test set score: %f" % mlp.score(X_test, y_test)) # Vykresleni (deseti) koeficientu navrzene site fig, axes = plt.subplots(2, 5) # use global min / max to ensure all weights are shown on the same scale vmin, vmax = mlp.coefs_[0].min(), mlp.coefs_[0].max() for coef, ax in zip(mlp.coefs_[0].T, axes.ravel()): ax.matshow(coef.reshape(8, 8), cmap=plt.cm.gray, vmin=0.5 * vmin, vmax=0.5 * vmax) ax.set_xticks(()) ax.set_yticks(()) ==== MNIST_784 ==== # Nacteni dat z https://www.openml.org/d/554 #X, y = datasets.fetch_openml("mnist_784", version=1, return_X_y=True, as_frame=False) #np.savez_compressed('mnist_784', X=X, y=y) # ulozeni datasetu jako npz #X = X / 255.0 # Nacteni lokalne ulozeneho npz datasetu data_mnist = np.load('mnist_784.npz',allow_pickle=True) X_all = data_mnist['X'] X = X_all[:5000] / 255.0 y_all = data_mnist['y'] y = y_all[:5000] _, axes = plt.subplots(nrows=1, ncols=4, figsize=(10, 3)) for ax, image, label in zip(axes, X, y): ax.set_axis_off() ax.imshow(image.reshape(28,28), cmap=plt.cm.gray_r, interpolation="nearest") ax.set_title("Label: %s" % label) # vytvoreni klasifikatoru clf = svm.SVC() ''' # Uprava vstupnich parametru clf = svm.SVC( C=0.5, kernel='poly', gamma=0.005, verbose=False, max_iter=1 ) ''' # Rozdeleni na trenovaci a testovaci sadu X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.5, shuffle=True ) # Trenink clf.fit(X_train, y_train) # Predikce predicted = clf.predict(X_test) # Hodnoceni uspesnosti predikce na trenovacich a testovacich datech print("Training set score: %f" % clf.score(X_train, y_train)) print("Test set score: %f" % clf.score(X_test, y_test)) import warnings from sklearn.exceptions import ConvergenceWarning ''' mlp = MLPClassifier( hidden_layer_sizes=(40,), max_iter=100, alpha=1e-4, solver="sgd", verbose=10, random_state=1, learning_rate_init=0.02, ) ''' ''' mlp = MLPClassifier( random_state=1, max_iter=100, activation='relu', solver='adam', batch_size=128, alpha=1, learning_rate_init=0.003, learning_rate='adaptive', hidden_layer_sizes=(10,) ) ''' mlp = MLPClassifier( random_state=1, max_iter=100, activation='tanh', solver='adam', #batch_size=128, alpha=1e-4, learning_rate_init=0.02, learning_rate='adaptive', hidden_layer_sizes=(40,) ) with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=ConvergenceWarning, module="sklearn") mlp.fit(X_train, y_train) print("Training set score: %f" % mlp.score(X_train, y_train)) print("Test set score: %f" % mlp.score(X_test, y_test)) fig, axes = plt.subplots(2, 5) # use global min / max to ensure all weights are shown on the same scale vmin, vmax = mlp.coefs_[0].min(), mlp.coefs_[0].max() for coef, ax in zip(mlp.coefs_[0].T, axes.ravel()): ax.matshow(coef.reshape(28, 28), cmap=plt.cm.gray, vmin=0.5 * vmin, vmax=0.5 * vmax) ax.set_xticks(()) ax.set_yticks(()) # predikce na testovacim setu predicted = mlp.predict(X_test) # nalezeni 10 chybnych klasifikaci id_wrong = [] for id, pred_num in enumerate(predicted.tolist()): if y_test[id] != pred_num: id_wrong.append(id) if len(id_wrong) == 10: break print(id_wrong) # Predikce prvnich 10 cisel pred_list = predicted.tolist() print('Target: ',y_test[id_wrong]) print('Predicted: ',predicted[id_wrong]) _, axes = plt.subplots(nrows=1, ncols=10, figsize=(50, 5)) for ax, image, prediction, actual in zip(axes, X_test[id_wrong], predicted[id_wrong], y_test[id_wrong]): image = image.reshape(28, 28) ax.imshow(image, cmap=plt.cm.gray_r, interpolation="nearest") ax.set_title(f"Prediction: {prediction}, actual:{actual}") print( f"Classification report for classifier {clf}:\n" f"{metrics.classification_report(y_test, predicted)}\n" ) disp = metrics.ConfusionMatrixDisplay.from_predictions(y_test, predicted) disp.figure_.suptitle("Confusion Matrix") plt.show()