Skip to content

Instantly share code, notes, and snippets.

@denismazzucato
Created January 12, 2019 12:56
Show Gist options
  • Save denismazzucato/2e65a4a6b882ab93b7d482558883b6d5 to your computer and use it in GitHub Desktop.
Save denismazzucato/2e65a4a6b882ab93b7d482558883b6d5 to your computer and use it in GitHub Desktop.
NaiveBayes.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "NaiveBayes.ipynb",
"version": "0.3.2",
"provenance": [],
"collapsed_sections": [],
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/denismazzu96/2e65a4a6b882ab93b7d482558883b6d5/naivebayes.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"metadata": {
"id": "rBgbBW_rDQZB",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Apprendimento con metodo Naive Bayes \n",
"\n",
"Denis Mazzucato,\n",
"Paolo Eccher\n",
"\n",
"Script per l'applicazione dell'algoritmo **Naive Bayes** per classificare un documento testuale preso dal dataset **20newsgroups** ottenuto da scikit-learn.\n",
"\n",
"### Per l'implementazione sono state usate queste funzionalità esterne:\n",
"* [Counter](https://docs.python.org/3/library/collections.html)\n",
"* [DictVectorized](https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.DictVectorizer.html#sklearn.feature_extraction.DictVectorizer)\n",
"\n",
"###Lo script lavora nel seguente modo:\n",
"1. Trasformiamo i testi in liste di stringhe rimuovendo caratteri non alfabetici e rendendo minuscole tutte le lettere\n",
"2. Uso le liste appena create per costruire il vocabolario, associando ad ogni parola un indice numerico\n",
"3. Conto le occorrenze in ogni documento\n",
"4. Creo le matrici sparse per training set e test set, dove X[a, b] = \"occorrenze della parola b nel documento a\"\n",
"5. Eseguo apprendimento e test\n",
"\n",
"Nello script ci sono commenti che puntano a questa lista per non perdersi nel workflow dello script.\n",
"\n"
]
},
{
"metadata": {
"id": "-DzkBjGDGHcK",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 201
},
"outputId": "c30c9fac-3e04-48dc-ed7e-448ecf54ed2f"
},
"cell_type": "code",
"source": [
"import numpy as np\n",
"from sklearn.datasets import fetch_20newsgroups\n",
"from re import sub\n",
"from collections import Counter\n",
"from sklearn.feature_extraction import DictVectorizer\n",
"from sklearn.naive_bayes import MultinomialNB\n",
"from sklearn.metrics import accuracy_score\n",
"\n",
"'''\n",
"Ottengo i dati da sklearn.\n",
"'''\n",
"print ('Scarico i dati...')\n",
"tr = fetch_20newsgroups(subset='train')\n",
"ts = fetch_20newsgroups(subset='test')\n",
"\n",
"X_tr, y_tr = (tr.data, tr.target)\n",
"X_ts, y_ts = (ts.data, ts.target)\n",
"targets = tr.target_names\n",
"\n",
"'''\n",
"Punto 1 - Trasformo i dati in liste di stringhe.\n",
"'''\n",
"for i in range(len(X_tr)):\n",
" X_tr[i] = sub(\"[^\\w]\", \" \", X_tr[i].lower()) # Elimino i caratteri non alfanumerici\n",
" X_tr[i] = str(X_tr[i]) # Converto in stringa (i dati scaricati sono di tipo 'unicode')\n",
" X_tr[i] = X_tr[i].split() # Trasformo in lista di stringhe\n",
"for i in range(len(X_ts)):\n",
" X_ts[i] = sub(\"[^\\w]\", \" \", X_ts[i].lower()) # Elimino i caratteri non alfanumerici\n",
" X_ts[i] = str(X_ts[i]) # Converto in stringa (i dati scaricati sono di tipo 'unicode')\n",
" X_ts[i] = X_ts[i].split() # Trasformo in lista di stringhe\n",
"\n",
"'''\n",
"Punto 2 - Costruisco il vocabolario come un dizionario che associa ad ogni parola possibile un indice\n",
"(mi baso solo sul training set).\n",
"'''\n",
"print ('Creo il vocabolario...')\n",
"v = []\n",
"for text in X_tr:\n",
" v.extend(text)\n",
"v = set(v)\n",
"v = list(v) # Metodo molto empirico per eliminare le ripetizioni e mantenere una lista\n",
"vocabulary = {}\n",
"i = 0\n",
"for word in v:\n",
" vocabulary[word] = i\n",
" i += 1\n",
"print ('Vocabulario creato (' + str(len(vocabulary)) + ' parole).')\n",
"\n",
"'''\n",
"Punto 3 - Effettuo i conteggi delle parole su ogni documento.\n",
"'''\n",
"print (\"Preparo i dati...\")\n",
"counters_tr = []\n",
"counters_ts = []\n",
"for text in X_tr:\n",
" counters_tr.append(Counter(text))\n",
"for text in X_ts:\n",
" counters_ts.append(Counter(text))\n",
"\n",
"'''\n",
"Punto 4 - Creo le strutture dati per l'algoritmo di apprendimento.\n",
"Le funzioni fit() e predict() di MultinomialNB lavorano su array bidimensionali:\n",
"creo due matrici sparse per training set e ts set, mappando le occorrenze delle parole\n",
"del vocabolario nei documenti.\n",
"'''\n",
"vectorizer = DictVectorizer(sort=False)\n",
"vectorizer.vocabulary_ = vocabulary\n",
"X_tr_sparse = vectorizer.fit_transform(counters_tr)\n",
"X_ts_sparse = vectorizer.transform(counters_ts) # Non devo fare fit_transform dato che il training set ha 'fissato' il vocabolario\n",
"\n",
"'''\n",
"Punto 5 - Apprendimento e predizione con Naive Bayes\n",
"'''\n",
"print ('Apprendimento...')\n",
"clf = MultinomialNB(alpha=0.1)\n",
"clf.fit(X_tr_sparse, y_tr)\n",
"print ('Predizioni sul ts set...')\n",
"y_pred = clf.predict(X_ts_sparse)\n",
"\n",
"print ()\n",
"print ('ACCURACY: ' + str(accuracy_score(y_ts, y_pred)))\n",
" "
],
"execution_count": 3,
"outputs": [
{
"output_type": "stream",
"text": [
"Downloading 20news dataset. This may take a few minutes.\n",
"Downloading dataset from https://ndownloader.figshare.com/files/5975967 (14 MB)\n"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"Scarico i dati...\n",
"Creo il vocabolario...\n",
"Vocabulario creato (130152 parole).\n",
"Preparo i dati...\n",
"Apprendimento...\n",
"Predizioni sul ts set...\n",
"\n",
"ACCURACY: 0.8023101433882103\n"
],
"name": "stdout"
}
]
},
{
"metadata": {
"id": "barNFTINF7fc",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Osservazioni finali\n",
"\n",
"L'accuracy delle predizioni risulta dell'80% circa. Osservazione, si potrebbe aumentare eliminando le parole non significative dal vocabolario, che rischiano di influire negativamente sul risultato. Oppure usando la funzione peso **TF-IDF** per associare una certa misura di importanza all'interno della raccolta di documenti."
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment