regresja logistyczna
This commit is contained in:
parent
84cecdc086
commit
68b58f903f
@ -0,0 +1,155 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c75106d7-67aa-4c6c-afd7-d4e135663c60",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Regresja logistyczna"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1d7d4df5-6af4-4ad8-b684-d2cdea71b65e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Na dzisiejszych zajęciach zajmiemy się problemem klasyfikacji danych. Wykorzystamy do tego regresję logistyczną."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9bce9f86-9a0c-49a8-b08b-15ddfe135256",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Wprowadzenie\n",
|
||||
"\n",
|
||||
"Kiedy chcemy zdecydować jak zaklasyfikować jakieś obiekty o konkretnych cechach możemy np. określić 2 lub więcej klas obiektów i obiekty przypisać do tych klas. Natomiast jeśli algorytmy mają to zrobić za nas, przypiszą obiekt do jakiejś klasy na podstawie wyliczonego prawdopodobieństwa należenia do klasy. To znaczy, że jeśli mamy dwie klasy: A i B, to algorytm może np. wyliczyć, że obiekt można zaklasyfikować jako A z prawdopodobieństwem 0.8 a jako B z prawdopodobieństwem 0.2 to oczywiście algorytm przypisze obiektowi klasę A, dlatego że prawdopodobieństwo jest wyższe, choć nie jest równe 1 - nie mamy pewności, że obiekt rzeczywiście należy do klasy A."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d21f295f-dee6-419e-b8f3-f00fd8941448",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Regresja logistyczna jako klasyfikator\n",
|
||||
"\n",
|
||||
"Wiemy już, że będzie nam potrzebne prawdopodobieństwo i wiemy jak ocenić poprawność działania naszego algorytmu. Ale skąd wziąć prawdopodobieństwo?\n",
|
||||
"\n",
|
||||
"Przypomnijmy sobie najpierw jak działała regresja liniowa, którą znamy z poprzednich zajęć. Na podstawie jakiejś cechy lub zestawu cech (zmiennych niezależnych) funkcja ta przybliżała nam wartość zmiennej zależnej od tych cech. Np. procentowy wynik na teście końcowym w kursie względem rozwiązanej liczby ćwiczeń, liczby wejść do kursu, czasu spędzonego w kursie, itp. Załóżmy, że zamiast konkretnego wyniku chcemy przypisać danemu uczniowi etykietę \"zda\" (wartość = 1) lub \"nie zda\" (wartość = 0). Co by było, gdybyśmy zastosowali tutaj regresję liniową? Mogłoby to na wykresie wyglądać mniej więcej tak:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7db5ff10-5a9a-4036-89cb-d3f3413347d5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7ab8d303-437d-4674-84a9-7856a7563688",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"No cóż, widzimy, że tym razem regresja liniowa nie pomoże nam przy estymowaniu wartości przewidywanej, bo w zbiorze uczącym nie będziemy mieli innych wartości zmiennej zależnej niż 0 i 1. Co teraz?\n",
|
||||
"\n",
|
||||
"Może spróbujmy przybliżyć zbiór wartości zmiennej zależnej inną funkcją, np.:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8121eab5-bf59-4994-bef8-08777c9a5728",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "900d42f6-1deb-4eac-a57a-65b0fffe0a8a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Ta funkcja już lepiej pasuje :)\n",
|
||||
"\n",
|
||||
"I o takiej funkcji mówimy, że jest funkcją **regresji logistycznej**. Jest to **funkcja sigmoidalna**. Dla funkcji logistycznej jednej zmiennej wzór w ogólności jest następujący:\n",
|
||||
"\n",
|
||||
"$$ f\\left ( x \\right )=\\frac{1}{1+e^{-x}}$$"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "60c4cb42-d15c-49ea-8d55-aabf17cb5cde",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Natomiast my musimy dopasować tę funkcję do naszego zbioru danych i w tym celu szukamy pewnej funkcji liniowej, która jest argumentem funkcji $e^{-x}$. Na przykład jeśli mamy regresję logistyczną dla jednej zmiennej to szukamy funkcji liniowej $g(x)=ax+b$:\n",
|
||||
"\n",
|
||||
"$$ h\\left ( x \\right )=\\frac{1}{1+e^{-\\left ( ax + b \\right )}}$$"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8e8f5491-d94e-4a08-86be-33f699768eca",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Do znalezienia wartości $a$ i $b$ można wykorzystać np. algorytm gradientu prostego, o którym wspomniano na poprzednich zajęciach. Ale na potrzeby tych zajęć nie będziemy się tym zajmować. Nas interesuje wynik, więc skorzystamy znowu z gotowych bibliotek języka Python, które pozwolą nam wyznaczyć odpowiednią funkcję regresji logistycznej. Dla konkretnego wiersza w naszych danych wyznaczamy wartość takiej funkcji regresji logistycznej, którą potraktujemy jako prawdopodobieństwo należenia do pewnej klasy. I tutaj należy podjąć decyzję, od jakiej wartości prawdopodobieństwa będziemy mówić, że dany obiekt (u nas: _uczeń_) należy do danej klasy lub nie należy (inaczej mówiąc należy do klasy przeciwnej). Na przykład: _jeśli prawdopodobieństwo jest większe niż 0.5, to danemu uczniowi przypisujemy klasę **zda** a w przeciwnym wypadku klasę **nie zda**_."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bfb8aa0a-7ab7-4e01-a3d7-134f9b1c3f32",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Zatem przejdźmy do kodu. Na początek importujemy potrzebne biblioteki:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "d43ede69-e85f-43c1-8bcb-dfa073585a2b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
" \n",
|
||||
"from sklearn.linear_model import LogisticRegression"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "98151afc-2d56-4055-a978-265f0c148cae",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Wczytajmy dane i podejrzyjmy nasz zbiór danych:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9e006cb5-50d5-4b9d-996c-cf77a93fe88a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
155
regresja logistyczna/regresja_logistyczna_NMI_2023.ipynb
Normal file
155
regresja logistyczna/regresja_logistyczna_NMI_2023.ipynb
Normal file
@ -0,0 +1,155 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c75106d7-67aa-4c6c-afd7-d4e135663c60",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Regresja logistyczna"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1d7d4df5-6af4-4ad8-b684-d2cdea71b65e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Na dzisiejszych zajęciach zajmiemy się problemem klasyfikacji danych. Wykorzystamy do tego regresję logistyczną."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9bce9f86-9a0c-49a8-b08b-15ddfe135256",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Wprowadzenie\n",
|
||||
"\n",
|
||||
"Kiedy chcemy zdecydować jak zaklasyfikować jakieś obiekty o konkretnych cechach możemy np. określić 2 lub więcej klas obiektów i obiekty przypisać do tych klas. Natomiast jeśli algorytmy mają to zrobić za nas, przypiszą obiekt do jakiejś klasy na podstawie wyliczonego prawdopodobieństwa należenia do klasy. To znaczy, że jeśli mamy dwie klasy: A i B, to algorytm może np. wyliczyć, że obiekt można zaklasyfikować jako A z prawdopodobieństwem 0.8 a jako B z prawdopodobieństwem 0.2 to oczywiście algorytm przypisze obiektowi klasę A, dlatego że prawdopodobieństwo jest wyższe, choć nie jest równe 1 - nie mamy pewności, że obiekt rzeczywiście należy do klasy A."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d21f295f-dee6-419e-b8f3-f00fd8941448",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Regresja logistyczna jako klasyfikator\n",
|
||||
"\n",
|
||||
"Wiemy już, że będzie nam potrzebne prawdopodobieństwo i wiemy jak ocenić poprawność działania naszego algorytmu. Ale skąd wziąć prawdopodobieństwo?\n",
|
||||
"\n",
|
||||
"Przypomnijmy sobie najpierw jak działała regresja liniowa, którą znamy z poprzednich zajęć. Na podstawie jakiejś cechy lub zestawu cech (zmiennych niezależnych) funkcja ta przybliżała nam wartość zmiennej zależnej od tych cech. Np. procentowy wynik na teście końcowym w kursie względem rozwiązanej liczby ćwiczeń, liczby wejść do kursu, czasu spędzonego w kursie, itp. Załóżmy, że zamiast konkretnego wyniku chcemy przypisać danemu uczniowi etykietę \"zda\" (wartość = 1) lub \"nie zda\" (wartość = 0). Co by było, gdybyśmy zastosowali tutaj regresję liniową? Mogłoby to na wykresie wyglądać mniej więcej tak:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7db5ff10-5a9a-4036-89cb-d3f3413347d5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7ab8d303-437d-4674-84a9-7856a7563688",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"No cóż, widzimy, że tym razem regresja liniowa nie pomoże nam przy estymowaniu wartości przewidywanej, bo w zbiorze uczącym nie będziemy mieli innych wartości zmiennej zależnej niż 0 i 1. Co teraz?\n",
|
||||
"\n",
|
||||
"Może spróbujmy przybliżyć zbiór wartości zmiennej zależnej inną funkcją, np.:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8121eab5-bf59-4994-bef8-08777c9a5728",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "900d42f6-1deb-4eac-a57a-65b0fffe0a8a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Ta funkcja już lepiej pasuje :)\n",
|
||||
"\n",
|
||||
"I o takiej funkcji mówimy, że jest funkcją **regresji logistycznej**. Jest to **funkcja sigmoidalna**. Dla funkcji logistycznej jednej zmiennej wzór w ogólności jest następujący:\n",
|
||||
"\n",
|
||||
"$$ f\\left ( x \\right )=\\frac{1}{1+e^{-x}}$$"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "60c4cb42-d15c-49ea-8d55-aabf17cb5cde",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Natomiast my musimy dopasować tę funkcję do naszego zbioru danych i w tym celu szukamy pewnej funkcji liniowej, która jest argumentem funkcji $e^{-x}$. Na przykład jeśli mamy regresję logistyczną dla jednej zmiennej to szukamy funkcji liniowej $g(x)=ax+b$:\n",
|
||||
"\n",
|
||||
"$$ h\\left ( x \\right )=\\frac{1}{1+e^{-\\left ( ax + b \\right )}}$$"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8e8f5491-d94e-4a08-86be-33f699768eca",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Do znalezienia wartości $a$ i $b$ można wykorzystać np. algorytm gradientu prostego, o którym wspomniano na poprzednich zajęciach. Ale na potrzeby tych zajęć nie będziemy się tym zajmować. Nas interesuje wynik, więc skorzystamy znowu z gotowych bibliotek języka Python, które pozwolą nam wyznaczyć odpowiednią funkcję regresji logistycznej. Dla konkretnego wiersza w naszych danych wyznaczamy wartość takiej funkcji regresji logistycznej, którą potraktujemy jako prawdopodobieństwo należenia do pewnej klasy. I tutaj należy podjąć decyzję, od jakiej wartości prawdopodobieństwa będziemy mówić, że dany obiekt (u nas: _uczeń_) należy do danej klasy lub nie należy (inaczej mówiąc należy do klasy przeciwnej). Na przykład: _jeśli prawdopodobieństwo jest większe niż 0.5, to danemu uczniowi przypisujemy klasę **zda** a w przeciwnym wypadku klasę **nie zda**_."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bfb8aa0a-7ab7-4e01-a3d7-134f9b1c3f32",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Zatem przejdźmy do kodu. Na początek importujemy potrzebne biblioteki:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "d43ede69-e85f-43c1-8bcb-dfa073585a2b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
" \n",
|
||||
"from sklearn.linear_model import LogisticRegression"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "98151afc-2d56-4055-a978-265f0c148cae",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Wczytajmy dane i podejrzyjmy nasz zbiór danych:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9e006cb5-50d5-4b9d-996c-cf77a93fe88a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
Loading…
Reference in New Issue
Block a user