{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Klasyfikacja w Pythonie" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**zad. 1** Które z poniższych problemów jest problemem regresji, a które klasyfikacji?\n", " 1. Sprawdzenie, czy wiadomość jest spamem.\n", " 1. Przewidzenie oceny (od 1 do 5 gwiazdek) na podstawie komentarza.\n", " 1. OCR cyfr: rozpoznanie cyfry z obrazka.\n", " \n", " Jeżeli problem jest klasyfikacyjny, to jakie mamy klasy?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. klasyfikacja\n", "2. można traktować jako klasyfikację lub regresję. Jeżeli jako regresję to należy sprowadzić liczbę rzeczywistą do jednej z {1,2,3,4,5}\n", "3. klasyfikacja" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Miary dla klasyfikacji" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Istnieje wieje miar (metryk), na podstawie których możemy ocenić jakość modelu. Podobnie jak w przypadku regresji liniowej potrzebne są dwie listy: lista poprawnych klas i lista predykcji z modelu. Najpopularniejszą z metryk jest trafność, którą definiuje się w następujący sposób:\n", " $$ACC = \\frac{k}{N}$$ \n", " \n", " gdzie: \n", " * $k$ to liczba poprawnie zaklasyfikowanych przypadków,\n", " * $N$ liczebność zbioru testującego." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**zadanie** Napisz funkcję, która jako parametry przyjmnie dwie listy (lista poprawnych klas i wyjście z klasyfikatora) i zwróci trafność." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ACC: 0.4\n" ] } ], "source": [ "def accuracy_measure(true, predicted):\n", " return sum([1 if t==p else 0 for t,p in zip(true, predicted)]) / len(true)\n", "\n", "true_label = [1, 1, 1, 0, 0]\n", "predicted = [0, 1, 0, 1, 0]\n", "print(\"ACC:\", accuracy_measure(true_label, predicted))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Klasyfikator $k$ najbliższych sąsiadów *(ang. k-nearest neighbors, KNN)*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Klasyfikator [KNN](https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm), który został wprowadzony na ostatnim wykładzie, jest bardzo intuicyjny. Pomysł, który stoi za tym klasyfikatorem jest bardzo prosty: Jeżeli mamy nowy obiekt do zaklasyfikowania, to szukamy wśród danych trenujących $k$ najbardziej podobnych do niego przykładów i na ich podstawie decydujemy (np. biorąc większość) do jakie klasy powinien należeć dany obiekt." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "** Przykład 1** Mamy za zadanie przydzielenie obiektów do dwóch klas: trójkątów lub kwadratów. Rozpatrywany obiekt jest zaznaczony zielonym kółkiem. Przyjmując $k=3$, mamy wśród sąsiadów 2 trójkąty i 1 kwadrat. Stąd obiekt powinienm zostać zaklasyfikowany jako trójkąt. Jak zmienia się sytuacja, gdy przyjmiemy $k=5$?\n", "\n", "![Przykład 1](./KnnClassification.svg.png)\n", "\n", "( Grafika pochodzi z https://pl.wikipedia.org/wiki/K_najbli%C5%BCszych_s%C4%85siad%C3%B3w )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Herbal Iris" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Herbal Iris* jest klasycznym zbiorem danych w uczeniu maszynowym, który powstał w 1936 roku. Zawiera on informacje na 150 egzemplarzy roślin, które należą do jednej z 3 odmian." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**zad. 2** Wczytaj do zmiennej ``data`` zbiór *Herbal Iris*, który znajduje się w pliku ``iris.data``. Jest to plik csv.\n", "\n", "Kolumny są następujące:\n", "\n", "1. sepal length in cm\n", "2. sepal width in cm\n", "3. petal length in cm\n", "4. petal width in cm\n", "5. class: \n", " * Iris Setosa\n", " * Iris Versicolour\n", " * Iris Virginica" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5.1,3.5,1.4,0.2,Iris-setosa\r\n", "4.9,3.0,1.4,0.2,Iris-setosa\r\n", "4.7,3.2,1.3,0.2,Iris-setosa\r\n", "4.6,3.1,1.5,0.2,Iris-setosa\r\n", "5.0,3.6,1.4,0.2,Iris-setosa\r\n", "5.4,3.9,1.7,0.4,Iris-setosa\r\n", "4.6,3.4,1.4,0.3,Iris-setosa\r\n", "5.0,3.4,1.5,0.2,Iris-setosa\r\n", "4.4,2.9,1.4,0.2,Iris-setosa\r\n", "4.9,3.1,1.5,0.1,Iris-setosa\r\n" ] } ], "source": [ "!head iris.data" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "data = pd.read_csv('iris.data', names=('sepal_length', 'sepal_width', 'petal_length', 'petal_width','class'),index_col=False)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " | sepal_length | \n", "sepal_width | \n", "petal_length | \n", "petal_width | \n", "class | \n", "
---|---|---|---|---|---|
0 | \n", "5.1 | \n", "3.5 | \n", "1.4 | \n", "0.2 | \n", "Iris-setosa | \n", "
1 | \n", "4.9 | \n", "3.0 | \n", "1.4 | \n", "0.2 | \n", "Iris-setosa | \n", "
2 | \n", "4.7 | \n", "3.2 | \n", "1.3 | \n", "0.2 | \n", "Iris-setosa | \n", "
3 | \n", "4.6 | \n", "3.1 | \n", "1.5 | \n", "0.2 | \n", "Iris-setosa | \n", "
4 | \n", "5.0 | \n", "3.6 | \n", "1.4 | \n", "0.2 | \n", "Iris-setosa | \n", "
... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "
145 | \n", "6.7 | \n", "3.0 | \n", "5.2 | \n", "2.3 | \n", "Iris-virginica | \n", "
146 | \n", "6.3 | \n", "2.5 | \n", "5.0 | \n", "1.9 | \n", "Iris-virginica | \n", "
147 | \n", "6.5 | \n", "3.0 | \n", "5.2 | \n", "2.0 | \n", "Iris-virginica | \n", "
148 | \n", "6.2 | \n", "3.4 | \n", "5.4 | \n", "2.3 | \n", "Iris-virginica | \n", "
149 | \n", "5.9 | \n", "3.0 | \n", "5.1 | \n", "1.8 | \n", "Iris-virginica | \n", "
150 rows × 5 columns
\n", "KNeighborsClassifier(n_neighbors=3)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
KNeighborsClassifier(n_neighbors=3)