Uczenie maszynowe i sztuczne sieci neuronowe/Ćwiczenia 9: Różnice pomiędzy wersjami
Linia 122: | Linia 122: | ||
=Klasyfikacja tekstów= | =Klasyfikacja tekstów= | ||
+ | Ten przykład demonstruje jak można poradzić sobie z klasyfiakcją tematyczną dokumentów stosując technikę "worek ze słowami" | ||
+ | '''This is an example showing how scikit-learn can be used to classify documents by topics using a bag-of-words approach. This example uses a scipy.sparse matrix to store the features and demonstrates various classifiers that can efficiently handle sparse matrices. | ||
+ | The dataset used in this example is the 20 newsgroups dataset. It will be automatically downloaded, then cached.''' | ||
+ | |||
+ | # -*- coding: utf-8 -*- | ||
+ | # Przykład oparty na kodzie z: | ||
+ | # http://scikit-learn.org/stable/auto_examples/text/document_classification_20newsgroups.html | ||
+ | # Authors: Peter Prettenhofer <peter.prettenhofer@gmail.com> | ||
+ | # Olivier Grisel <olivier.grisel@ensta.org> | ||
+ | # Mathieu Blondel <mathieu@mblondel.org> | ||
+ | # Lars Buitinck <L.J.Buitinck@uva.nl> | ||
+ | # 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 | ||
+ | |||
+ | # 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_20newsgroups.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] | ||
+ | print data_train.target[id] | ||
+ | print categories[data_train.target[id]] | ||
+ | |||
+ | # 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.text.TfidfVectorizer.html#sklearn.feature_extraction.text.TfidfVectorizer | ||
+ | vectorizer = TfidfVectorizer(sublinear_tf=True, max_df=0.75, stop_words='english') | ||
+ | X_train = vectorizer.fit_transform(data_train.data) | ||
+ | print("Dane treningowe: n_samples: %d, n_features: %d" % X_train.shape) | ||
+ | print | ||
+ | |||
+ | X_test = vectorizer.transform(data_test.data) | ||
+ | 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 | ||
+ | clf = MultinomialNB(alpha=.01) | ||
+ | clf.fit(X_train, y_train) | ||
+ | |||
+ | # Benchmark | ||
+ | pred = clf.predict(X_test) | ||
+ | score = accuracy_score(y_test, pred) | ||
+ | print("accuracy: %0.3f" % score) | ||
+ | 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 | ||
+ | |||
+ | print("classification report:") | ||
+ | print(classification_report(y_test, pred, target_names=categories)) | ||
+ | |||
+ | print("confusion matrix:") | ||
+ | print(confusion_matrix(y_test, pred)) |
Wersja z 15:08, 30 gru 2015
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[0],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), 0: (0, 0, .9), 1: (1, 0, 0), 2: (.5, .5, 0)}
# 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[0],2))
X[:,0] = (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[:,0],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 Gaussian Naive Bayes
... # dofituj parametry klasyfikatora
# 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.contourf
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()
# 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_neuronowe/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 klasyfiakcją tematyczną dokumentów stosując technikę "worek ze słowami" This is an example showing how scikit-learn can be used to classify documents by topics using a bag-of-words approach. This example uses a scipy.sparse matrix to store the features and demonstrates various classifiers that can efficiently handle sparse matrices. The dataset used in this example is the 20 newsgroups dataset. It will be automatically downloaded, then cached.
- -*- coding: utf-8 -*-
- Przykład oparty na kodzie z:
- http://scikit-learn.org/stable/auto_examples/text/document_classification_20newsgroups.html
- Authors: Peter Prettenhofer <peter.prettenhofer@gmail.com>
- Olivier Grisel <olivier.grisel@ensta.org>
- Mathieu Blondel <mathieu@mblondel.org>
- Lars Buitinck <L.J.Buitinck@uva.nl>
- 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
- 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_20newsgroups.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] print data_train.target[id] print categories[data_train.target[id]]
- 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.text.TfidfVectorizer.html#sklearn.feature_extraction.text.TfidfVectorizer
vectorizer = TfidfVectorizer(sublinear_tf=True, max_df=0.75, stop_words='english') X_train = vectorizer.fit_transform(data_train.data) print("Dane treningowe: n_samples: %d, n_features: %d" % X_train.shape) print
X_test = vectorizer.transform(data_test.data) 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
clf = MultinomialNB(alpha=.01) clf.fit(X_train, y_train)
- Benchmark
pred = clf.predict(X_test) score = accuracy_score(y_test, pred) print("accuracy: %0.3f" % score) 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("classification report:") print(classification_report(y_test, pred, target_names=categories))
print("confusion matrix:") print(confusion_matrix(y_test, pred))