diff --git a/zajecia3/logistic.png b/zajecia3/logistic.png new file mode 100644 index 0000000..8a1e860 Binary files /dev/null and b/zajecia3/logistic.png differ diff --git a/zajecia3/sklearn cz. 2-ODPOWIEDZI.ipynb b/zajecia3/sklearn cz. 2-ODPOWIEDZI.ipynb index 3205240..99fdca1 100644 --- a/zajecia3/sklearn cz. 2-ODPOWIEDZI.ipynb +++ b/zajecia3/sklearn cz. 2-ODPOWIEDZI.ipynb @@ -683,7 +683,9 @@ { "cell_type": "code", "execution_count": 68, - "metadata": {}, + "metadata": { + "scrolled": true + }, "outputs": [ { "data": { @@ -707,6 +709,219 @@ "plt.ylabel('Procent błędów')\n", "plt.show()" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## TF IDF Vectorizer\n", + "\n", + "Czasami, żeby wytrenować model nie da się zastosować bezpośrednio danego typu danych, ponieważ najczęściej wejściem do algorytmu ML jest wektor, macierz lub tensor.\n", + "Dane tekstowe musimy również przekształcić do wektorów. Przydatny w tym przypadku jest TF IDF Vectorizer.\n", + "Oto przyład z dokumentacji jak można z niego skorzystać (https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(4, 9)\n" + ] + } + ], + "source": [ + "from sklearn.feature_extraction.text import TfidfVectorizer\n", + "corpus = [\n", + " 'This is the first document.',\n", + " 'This document is the second document.',\n", + " 'And this is the third one.',\n", + " 'Is this the first document?',\n", + "]\n", + "vectorizer = TfidfVectorizer()\n", + "X = vectorizer.fit_transform(corpus)\n", + "vectorizer.get_feature_names_out()\n", + "print(X.shape)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third',\n", + " 'this'], dtype=object)" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vectorizer.get_feature_names_out()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<4x9 sparse matrix of type ''\n", + "\twith 21 stored elements in Compressed Sparse Row format>" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "matrix([[0. , 0.46979139, 0.58028582, 0.38408524, 0. ,\n", + " 0. , 0.38408524, 0. , 0.38408524],\n", + " [0. , 0.6876236 , 0. , 0.28108867, 0. ,\n", + " 0.53864762, 0.28108867, 0. , 0.28108867],\n", + " [0.51184851, 0. , 0. , 0.26710379, 0.51184851,\n", + " 0. , 0.26710379, 0.51184851, 0.26710379],\n", + " [0. , 0.46979139, 0.58028582, 0.38408524, 0. ,\n", + " 0. , 0.38408524, 0. , 0.38408524]])" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X.todense()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Na podstawie tych danych możemy wytrenowąc model regresji logistycznej. Jest to model regresji liniowej z dodatkową nałożoną funkcją logistyczną:\n", + " ( https://en.wikipedia.org/wiki/Logistic_function )\n", + " \n", + " \n", + "![Przykład 1](./logistic.png)\n", + "\n", + "\n", + "Dzięki wyjściu modelu zawsze pomiędzy 0, a 1 można traktować wynik jako prawdopodobieństwo\n" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.linear_model import LogisticRegression" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0, 0, 1, 0])" + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y = [0,0,1,1]\n", + "model = LogisticRegression()\n", + "model.fit(X, y)\n", + "model.predict(X)" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0.51514316, 0.48485684],\n", + " [0.56428483, 0.43571517],\n", + " [0.40543928, 0.59456072],\n", + " [0.51514316, 0.48485684]])" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.predict_proba(X)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sieci neuronowe\n", + "\n", + "Warto zauważyć, że sieci neuronowe w najprostszym wariancie to tak naprawdę złożenie wielu funkcji regresji logistycznej ze sobą, gdzie wejściem jednego modelu regresji logistycznej jest wyjście poprzedniej. W przypadku danych tekstowych zazwyczaj jest wybierana wtedy inna reprezentacja danych niż TF IDF, ponieważ TF IDF nie uwzględnia kolejności słów" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Standard Scaler\n", + "\n", + "**Zadanie 7**\n", + "\n", + "\n", + "Sprawdź dokumentację https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html\n", + "\n", + "KNN jest wrażliwy na liniowe skalowanie danych (w przeciwieństwie do modeli bazujących na regresji, gdyż współczynniki liniowe rekompensują skalowanie liniowe).\n", + "\n", + "Wytrenuj dowolny model KNN na cechach pozyskanych ze StandardScaler. Pamiętaj, żeby wyskalować zarówno dane ze zbioru test jak i train.\n", + "\n", + "\n", + "\n", + "Zauważ, że scaler ma podobne API (fit, transform) jak TF IDF Vectorier" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/zajecia3/sklearn cz. 2.ipynb b/zajecia3/sklearn cz. 2.ipynb index 61d8c03..022140b 100644 --- a/zajecia3/sklearn cz. 2.ipynb +++ b/zajecia3/sklearn cz. 2.ipynb @@ -330,6 +330,212 @@ "plt.show()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## TF IDF Vectorizer\n", + "\n", + "Czasami, żeby wytrenować model nie da się zastosować bezpośrednio danego typu danych, ponieważ najczęściej wejściem do algorytmu ML jest wektor, macierz lub tensor.\n", + "Dane tekstowe musimy również przekształcić do wektorów. Przydatny w tym przypadku jest TF IDF Vectorizer.\n", + "Oto przyład z dokumentacji jak można z niego skorzystać (https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(4, 9)\n" + ] + } + ], + "source": [ + "from sklearn.feature_extraction.text import TfidfVectorizer\n", + "corpus = [\n", + " 'This is the first document.',\n", + " 'This document is the second document.',\n", + " 'And this is the third one.',\n", + " 'Is this the first document?',\n", + "]\n", + "vectorizer = TfidfVectorizer()\n", + "X = vectorizer.fit_transform(corpus)\n", + "vectorizer.get_feature_names_out()\n", + "print(X.shape)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third',\n", + " 'this'], dtype=object)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vectorizer.get_feature_names_out()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<4x9 sparse matrix of type ''\n", + "\twith 21 stored elements in Compressed Sparse Row format>" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "matrix([[0. , 0.46979139, 0.58028582, 0.38408524, 0. ,\n", + " 0. , 0.38408524, 0. , 0.38408524],\n", + " [0. , 0.6876236 , 0. , 0.28108867, 0. ,\n", + " 0.53864762, 0.28108867, 0. , 0.28108867],\n", + " [0.51184851, 0. , 0. , 0.26710379, 0.51184851,\n", + " 0. , 0.26710379, 0.51184851, 0.26710379],\n", + " [0. , 0.46979139, 0.58028582, 0.38408524, 0. ,\n", + " 0. , 0.38408524, 0. , 0.38408524]])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X.todense()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Na podstawie tych danych możemy wytrenowąc model regresji logistycznej. Jest to model regresji liniowej z dodatkową nałożoną funkcją logistyczną:\n", + " ( https://en.wikipedia.org/wiki/Logistic_function )\n", + " \n", + " \n", + "![Przykład 1](./logistic.png)\n", + "\n", + "\n", + "Dzięki wyjściu modelu zawsze pomiędzy 0, a 1 można traktować wynik jako prawdopodobieństwo\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.linear_model import LogisticRegression" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0, 0, 1, 0])" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y = [0,0,1,1]\n", + "model = LogisticRegression()\n", + "model.fit(X, y)\n", + "model.predict(X)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0.51514316, 0.48485684],\n", + " [0.56428483, 0.43571517],\n", + " [0.40543928, 0.59456072],\n", + " [0.51514316, 0.48485684]])" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.predict_proba(X)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sieci neuronowe\n", + "\n", + "Warto zauważyć, że sieci neuronowe w najprostszym wariancie to tak naprawdę złożenie wielu funkcji regresji logistycznej ze sobą, gdzie wejściem jednego modelu regresji logistycznej jest wyjście poprzedniej. W przypadku danych tekstowych zazwyczaj jest wybierana wtedy inna reprezentacja danych niż TF IDF, ponieważ TF IDF nie uwzględnia kolejności słów" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Standard Scaler\n", + "\n", + "**Zadanie 7**\n", + "\n", + "\n", + "Sprawdź dokumentację https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html\n", + "\n", + "KNN jest wrażliwy na liniowe skalowanie danych (w przeciwieństwie do modeli bazujących na regresji, gdyż współczynniki liniowe rekompensują skalowanie liniowe).\n", + "\n", + "Wytrenuj dowolny model KNN na cechach pozyskanych ze StandardScaler. Pamiętaj, żeby wyskalować zarówno dane ze zbioru test jak i train.\n", + "\n", + "\n", + "\n", + "Zauważ, że scaler ma podobne API (fit, transform) jak TF IDF Vectorier" + ] + }, { "cell_type": "code", "execution_count": null,