Zapisz jako PDF
Transkrypt
Zapisz jako PDF
Uczenie_maszynowe_i_sztuczne_sieci_neuronowe_cw/Bayes Naiwny klasyfikator Bayesa Z klasyfikatorem tym zapoznamy się próbując klasyfikować gatunki irysów. Jest to klasyczny już problem, często wykorzystywany przy porównywaniu różnych technik klasyfikacji. Więcej o pochodzeniu tych danych i problemie można przeczytać tu [1] Kod napiszemy w oparciu o implementacje klasyfikatora Bayesa z biblioteki scikit-learn [2] Zaczerpniemy stamtąd: obiekt klasyfikatora GaussianNB zbiór danych funkcje do oceny jakości Zatem importujemy: # -*- coding: utf-8 -*from sklearn import datasets from sklearn.naive_bayes import GaussianNB import matplotlib.pyplot as plt import numpy as np from sklearn.metrics import accuracy_score, classification_report, confusion_matrix Przyda nam się potem funkcja rysująca dwuwymiarowe rozkłady Gaussa def plot_gauss(mu,sigma,xx,yy): ''' Funkcja rysująca kontury funkcji gęstości prawdopodobieństwa dwuwymiarowego rozkładu Gaussa''' XX = np.c_[xx.ravel(), yy.ravel()] R = XX - mu invS = np.linalg.inv(np.diag(sigma)) z = np.zeros(len(R)) for i in range(len(R)): z[i] = np.exp(-0.5*np.dot( R[i,:].T,np.dot(invS,R[i,:]))) z.shape = xx.shape plt.contourf(xx,yy,z,alpha = 0.5) plt.plot(mu[],mu[1],'o') Zapoznajemy się z danymi i wybieramy ich podzbiór do dalszej zabawy: #ładujemy dane iris = datasets.load_iris() #https://en.wikipedia.org/wiki/Iris_flower_data_set # zapoznajemy się z tymi danymi print iris['DESCR'] # rysujemy zależniści między cechami # przygotowujemy własną mapę kolorów color_map = {-1: (1, 1, 1), : (, , .9), 1: (1, , ), 2: (.5, .5, )} # wytwarzamy wektor, który każdemu wierszowi w tabeli danych przypisze kolor odpowiadający gatunkowi irysa colors = [color_map[y] for y in iris.target] plt.figure(1) plt.title(u'rozkłady cech w klasach') for i, name in enumerate(iris['feature_names']): for j, name in enumerate(iris['feature_names']): plt.subplot(4,4,i*4+j+1) plt.scatter(iris.data[:,i],iris.data[:,j],c = colors) # wybieramy cechy 2 i 3 i normalizujemy je X = np.zeros((iris.data.shape[],2)) X[:,] = (iris.data[:,2] - np.mean(iris.data[:,2]))/np.std(iris.data[:,2]) X[:,1] = (iris.data[:,3] - np.mean(iris.data[:,3]))/np.std(iris.data[:,3]) plt.figure(2) plt.scatter(X[:,],X[:,1],c = colors) plt.title('Wybrane cechy po normalizacji') plt.show() Poniżej znajduje się kod służący klasyfikacji. Proszę go uzupełnić zgodnie z komentarzami i dokumentacją [3] ######################################################### gnb =... # stwórz instancję klasyfikatora ... # dofituj parametry klasyfikatora Gaussian Naive Bayes # przedstaw rozkłady Gaussa, które zostały dopasowane do danych, skorzystaj z funkcji plot_gauss() # średnie tych rozkładów są w gnb.theta_ # standardowe odchylenia są w gnb.sigma_ # przygotowanie siatki na której będą rysowane kontury Gaussów x_min, x_max = -3,3 y_min, y_max = -3,3 xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1), np.arange(y_min, y_max, 0.1)) plt.figure(4) for i in range(3): plot_gauss(...,...,xx,yy) # dorzućmy do rysunku jeszcze oryginalne dane plt.scatter(...,...,c = colors) plt.title(u'Rozkłady Gaussa dopasowane do danych') plt.show() # rysowanie wyników klasyfikacji # przekształcamy siatkę w macierz dwukolumnową - kolumny odpowiadają cechom XX = np.c_[xx.ravel(), yy.ravel()] # dla każdego punktu siatki oblicz predykcję klasyfikatora Z = .... # te predykcje narysujemy w przestrzeni cech za pomocą funkcji plt.figure(3) Z = Z.reshape(xx.shape) plt.contourf(..., ..., ..., cmap=plt.cm.Paired) # i dorzucamy oryginalne punkty plt.scatter... plt.title(u'Podział przestrzeni cech na klasy') plt.show() plt.contourf # Teraz zajmiemy się ewaluacją dopasowanego modelu. Skorzystamy z # http://scikit-learn.org/stable/modules/model_evaluation.html # upewnij się, że dokładnie rozumiesz co zwracają te funkcje # porównaj z definicjami z wykładu # http://haar.zfb.fuw.edu.pl/edu/index.php/Uczenie_maszynowe_i_sztuczne_sieci_n euronowe/Wykład_Ocena_jakości_klasyfikacji print("classification report:") print(classification_report...) print("confusion matrix:") print(confusion_matrix...) Klasyfikacja tekstów Ten przykład demonstruje jak można poradzić sobie z klasyfikacją tematyczną dokumentów stosując technikę "worek ze słowami". O tej technice więcej można przeczytać tu: [4] W skrócie: tekst jest zamieniany na pojedyncze słowa. ze słów otrzymanych dla dużej ilości tekstów tworzony jest słownik - wektor możliwych słów dla konkretnego tekstu zliczana jest ilość wystąpień każdego ze te zliczenia mogą być normalizowane na różne sposoby O metodzie tej mówi się "worek ze słowami", bo zaniedbujemy w niej kolejność słów w dokumencie i wszelkie korelacje między ich wzajemnymi pozycjami. Często stosowana wersja normalizacji to tzw. transformacja tf-idf (term frequency - inverse document frequency)[5]. Transformacja ta zasadza się na iloczynie wagi i specyficzności danego słowa. W najprostszym przypadku: waga danego słowa jest proporcjonalna do częstości występowania słowa w dokumencie specyficzność słowa może być określona jako odwrotnie proporcjonalna do liczby dokumentów, w których występuje Możliwe są różne wersje funkcji stosowanych w obu składnikach. Dane pochodzą z 20 list dyskusyjnych. Jako klasyfikator wykorzystamy naiwny klasyfikator Bayesa dla rozkładów wielorakich: MultinomialNB. Proszę uzupełnić poniższy kod: # -*- coding: utf-8 -*# Przykład oparty na kodzie z: # http://scikit-learn.org/stable/auto_examples/text/document_classification_20n ewsgroups.html # Authors: Peter Prettenhofer <[email protected]> # Olivier Grisel <[email protected]> # Mathieu Blondel <[email protected]> # Lars Buitinck <[email protected]> # License: BSD 3 clause # adaptacja: Jarosław Żygierewicz import numpy as np from sklearn.datasets import fetch_20newsgroups from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.metrics import accuracy_score, classification_report, confusion_matrix # W całym zbiorze danych jest 20 list dyskusyjnych, tu wykorzystamy podzbiór: # kategorie dla których zbudujemy klasyfikator categories = [ 'alt.atheism', 'talk.religion.misc', 'comp.graphics', 'sci.space' ] # Ładujemy dane z newsgroups dataset dla wybranch kategorii # korzystamy z funkcji sklearn.datasets.fetch_20newsgroups # http://scikit-learn.org/stable/modules/generated/sklearn.datasets.fetch_20new sgroups.html#sklearn.datasets.fetch_20newsgroups data_train = fetch_20newsgroups(subset='train', categories=categories, shuffle=True, random_state=42, remove=('headers', 'footers', 'quotes')) data_test = fetch_20newsgroups(subset='test', categories=categories, shuffle=True, random_state=42, remove=('headers', 'footers', 'quotes')) categories = data_train.target_names # zobaczmy jak wyglądają przykładowe dane id =57 print data_train.data[id] # lista wiadomości print data_train.target[id] # lista kodów tematycznych print categories[data_train.target[id]] # nazwy kategorii odpowiadających kodom # upraszczamy nazewnictwo y_train, y_test = data_train.target, data_test.target # przekodowujemy wiadomości na wekotry cech # korzystamy z funkcji: sklearn.feature_extraction.text.TfidfVectorizer # http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.t ext.TfidfVectorizer.html#sklearn.feature_extraction.text.TfidfVectorizer vectorizer = ....# stwórz instancje obiektu TfidfVectorizer X_train = ....# naucz vctorizer słownika i przetransformuj dane uczące. # wypisz rozmiary danych treningowych print("Dane treningowe: n_samples: %d, n_features: %d" % X_train.shape) # Dane uczące są przechowywane w macierzy rzadkiej (sparse matrix) # proszę podejrzeć jak wyglądają tak przekodowane dane: print ... X_test = ... # wektoryzujemy też dane testowe print("Dane testowe: n_samples: %d, n_features: %d" % X_test.shape) print # odwrotne mapowanie z cech na słowa feature_names = vectorizer.get_feature_names() feature_names = np.asarray(feature_names) # tworzymy instancję i uczymy klasyfikator MultinomialNB clf = ... clf.... # Benchmark: tu będziemy korzystać z funkcji zaimplementowanych w # http://scikit-learn.org/stable/modules/classes.html#module-sklearn.metrics pred = clf.... # obliczamy predykcję dla tekstów ze zbioru testowego accur = ... # dokladność print("dokładność: %0.3f" % accur) print("classification report:") # wypisz raport klasyfikacji print(...) print("Macierz błędów") # wypisz macierz (confusion matrix) print(...) # wypiszemy teraz po 10 najbardziej znaczących słów w każdej klasie print("top 10 keywords per class:") for i, category in enumerate(categories): top10 = np.argsort(clf.coef_[i])[-10:] print("%s: %s" % (category, " ".join(feature_names[top10]))) print Uczenie_maszynowe_i_sztuczne_sieci_neuronowe_cw/Bayes