Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save josejesus30/5e956fb290eb43ec169fda7e41dd9897 to your computer and use it in GitHub Desktop.
Save josejesus30/5e956fb290eb43ec169fda7e41dd9897 to your computer and use it in GitHub Desktop.
Uso de el modelo de Support Vector Machine para la detección de URLs Fraudulentas
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Modelo: _Support Vector Machine (SVM)_"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_<h2 style=\"color:blue\"> Autor: José Alamo Palomino</h2>_"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Caso Práctico: Detección de URLs maliciosas"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Descripción\n",
"\n",
"La Web se ha convertido en una plataforma importante para actividades delictivas en línea. Las URL se utilizan como el vehículo principal en este dominio. Para contrarrestar estos problemas, la comunidad de seguridad centró sus esfuerzos en desarrollar técnicas para la mayoría de las listas negras de URL maliciosas.\n",
"\n",
"Si bien logra proteger a los usuarios de dominios maliciosos conocidos, este enfoque solo resuelve parte del problema. Las nuevas URL maliciosas que surgieron en toda la web en masa comúnmente obtienen una ventaja en esta carrera. Además de eso, según Alexa, los sitios web confiables pueden transmitir URL fraudulentas comprometidas llamadas URL de desfiguración.\n",
"\n",
"Exploramos un enfoque liviano para la detección y categorización de las URL maliciosas de acuerdo con su tipo de ataque y mostramos que el análisis léxico es efectivo y eficiente para la detección proactiva de estas URL. También estudiamos el efecto de las técnicas de ofuscación en URL maliciosas para descubrir el tipo de técnica de ofuscación dirigida a un tipo específico de URL maliciosa. Estudiamos principalmente cinco tipos diferentes de URL:\n",
"\n",
"* **URL benignas**: se recopilaron más de 35,300 URL benignas de los principales sitios web de Alexa. Los dominios se han pasado a través de un rastreador web Heritrix para extraer las URL. Inicialmente, se rastrean alrededor de medio millón de URL únicas y luego se pasan para eliminar las URL duplicadas y solo de dominio. Más tarde, las URL extraídas se han verificado a través de Virustotal para filtrar las URL benignas.\n",
"\n",
"* **URL de spam**: se recopilaron alrededor de 12,000 URL de spam del conjunto de datos de WEBSPAM-UK2007 disponible públicamente.\n",
"\n",
"* **URL de phishing**: se tomaron alrededor de 10,000 URL de phishing de OpenPhish, que es un repositorio de sitios de phishing activos.\n",
"\n",
"* **URL de malware**: Se obtuvieron más de 11,500 URL relacionadas con sitios web de malware de DNS-BH, que es un proyecto que mantiene una lista de sitios de malware.\n",
"\n",
"* **URL de desfiguración**: más de 45,450 URL pertenecen a la categoría de URL de desfiguración. Son sitios web de confianza clasificados por Alexa que alojan URL fraudulentas u ocultas que contienen páginas web maliciosas.\n",
"\n",
"La ofuscación se utiliza como un método común para enmascarar URL maliciosas. Un atacante que intenta evadir el análisis estático de las características de URL léxicas utiliza técnicas de ofuscación para que las URL maliciosas se vuelvan estadísticamente similares a las benignas. Las técnicas de ofuscación en las URL se analizan para detectar la intención de actividad maliciosa en esta investigación. Analizamos principalmente las URL de spam, phishing y malware para ver qué tipo de técnicas de ofuscación se aplican en las URL."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## OBSERVACIÓN\n",
"\n",
"<h2 style = color:red>Solo utilizarán URLs benignas y de phishing para el análisis de la máquina de soporte vectorial.</h2>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 style=\"color:blue\">1. Importando librerías necesarias</h2>"
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"import pandas as pd\n",
"from sklearn.model_selection import train_test_split\n",
"import numpy as np\n",
"from sklearn.metrics import f1_score\n",
"from sklearn.preprocessing import StandardScaler, RobustScaler\n",
"from sklearn.pipeline import Pipeline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 style=\"color:blue\">2. Funciones auxiliares</h2>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.1 Función para la partición del conjunto de datos"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def train_val_test_split(df, rstate=42, shuffle=True, stratify=None):\n",
" strat = df[stratify] if stratify else None\n",
" train_set, test_set = train_test_split(\n",
" df, test_size=0.4, random_state=rstate, shuffle=shuffle, stratify=strat)\n",
" strat = test_set[stratify] if stratify else None\n",
" val_set, test_set = train_test_split(\n",
" test_set, test_size=0.5, random_state=rstate, shuffle=shuffle, stratify=strat)\n",
" return (train_set, val_set, test_set)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.2 Representación gráfica del límite de decisión"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# Se utilizará esta función más adelante\n",
"def plot_svc_decision_boundary(svm_clf, xmin, xmax):\n",
" w = svm_clf.coef_[0]\n",
" b = svm_clf.intercept_[0]\n",
"\n",
" # At the decision boundary, w0*x0 + w1*x1 + b = 0\n",
" # => x1 = -w0/w1 * x0 - b/w1\n",
" x0 = np.linspace(xmin, xmax, 200)\n",
" decision_boundary = -w[0]/w[1] * x0 - b/w[1]\n",
"\n",
" margin = 1/w[1]\n",
" gutter_up = decision_boundary + margin\n",
" gutter_down = decision_boundary - margin\n",
"\n",
" svs = svm_clf.support_vectors_\n",
" plt.scatter(svs[:, 0], svs[:, 1], s=180, facecolors='#FFAAAA')\n",
" plt.plot(x0, decision_boundary, \"k-\", linewidth=2)\n",
" plt.plot(x0, gutter_up, \"k--\", linewidth=2)\n",
" plt.plot(x0, gutter_down, \"k--\", linewidth=2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 style=\"color:blue\">3. Lectura del conjunto de datos</h2>"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Querylength</th>\n",
" <th>domain_token_count</th>\n",
" <th>path_token_count</th>\n",
" <th>avgdomaintokenlen</th>\n",
" <th>longdomaintokenlen</th>\n",
" <th>avgpathtokenlen</th>\n",
" <th>tld</th>\n",
" <th>charcompvowels</th>\n",
" <th>charcompace</th>\n",
" <th>ldl_url</th>\n",
" <th>...</th>\n",
" <th>SymbolCount_FileName</th>\n",
" <th>SymbolCount_Extension</th>\n",
" <th>SymbolCount_Afterpath</th>\n",
" <th>Entropy_URL</th>\n",
" <th>Entropy_Domain</th>\n",
" <th>Entropy_DirectoryName</th>\n",
" <th>Entropy_Filename</th>\n",
" <th>Entropy_Extension</th>\n",
" <th>Entropy_Afterpath</th>\n",
" <th>URL_Type_obf_Type</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>12</td>\n",
" <td>5.5</td>\n",
" <td>8</td>\n",
" <td>4.083334</td>\n",
" <td>2</td>\n",
" <td>15</td>\n",
" <td>7</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>-1</td>\n",
" <td>-1</td>\n",
" <td>-1</td>\n",
" <td>0.676804</td>\n",
" <td>0.860529</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.00000</td>\n",
" <td>-1.000000</td>\n",
" <td>benign</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>0</td>\n",
" <td>3</td>\n",
" <td>12</td>\n",
" <td>5.0</td>\n",
" <td>10</td>\n",
" <td>3.583333</td>\n",
" <td>3</td>\n",
" <td>12</td>\n",
" <td>8</td>\n",
" <td>2</td>\n",
" <td>...</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>-1</td>\n",
" <td>0.715629</td>\n",
" <td>0.776796</td>\n",
" <td>0.693127</td>\n",
" <td>0.738315</td>\n",
" <td>1.00000</td>\n",
" <td>-1.000000</td>\n",
" <td>benign</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>11</td>\n",
" <td>4.0</td>\n",
" <td>5</td>\n",
" <td>4.750000</td>\n",
" <td>2</td>\n",
" <td>16</td>\n",
" <td>11</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0.677701</td>\n",
" <td>1.000000</td>\n",
" <td>0.677704</td>\n",
" <td>0.916667</td>\n",
" <td>0.00000</td>\n",
" <td>0.898227</td>\n",
" <td>benign</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>7</td>\n",
" <td>4.5</td>\n",
" <td>7</td>\n",
" <td>5.714286</td>\n",
" <td>2</td>\n",
" <td>15</td>\n",
" <td>10</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>-1</td>\n",
" <td>0.696067</td>\n",
" <td>0.879588</td>\n",
" <td>0.818007</td>\n",
" <td>0.753585</td>\n",
" <td>0.00000</td>\n",
" <td>-1.000000</td>\n",
" <td>benign</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>19</td>\n",
" <td>2</td>\n",
" <td>10</td>\n",
" <td>6.0</td>\n",
" <td>9</td>\n",
" <td>2.250000</td>\n",
" <td>2</td>\n",
" <td>9</td>\n",
" <td>5</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>5</td>\n",
" <td>4</td>\n",
" <td>3</td>\n",
" <td>0.747202</td>\n",
" <td>0.833700</td>\n",
" <td>0.655459</td>\n",
" <td>0.829535</td>\n",
" <td>0.83615</td>\n",
" <td>0.823008</td>\n",
" <td>benign</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>10</td>\n",
" <td>5.5</td>\n",
" <td>9</td>\n",
" <td>4.100000</td>\n",
" <td>2</td>\n",
" <td>15</td>\n",
" <td>11</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>-1</td>\n",
" <td>-1</td>\n",
" <td>-1</td>\n",
" <td>0.732981</td>\n",
" <td>0.860529</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.00000</td>\n",
" <td>-1.000000</td>\n",
" <td>benign</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>12</td>\n",
" <td>4.5</td>\n",
" <td>6</td>\n",
" <td>5.333334</td>\n",
" <td>2</td>\n",
" <td>24</td>\n",
" <td>9</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>-1</td>\n",
" <td>0.692383</td>\n",
" <td>0.939794</td>\n",
" <td>0.910795</td>\n",
" <td>0.673973</td>\n",
" <td>0.00000</td>\n",
" <td>-1.000000</td>\n",
" <td>benign</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>11</td>\n",
" <td>3.5</td>\n",
" <td>4</td>\n",
" <td>3.909091</td>\n",
" <td>2</td>\n",
" <td>15</td>\n",
" <td>6</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>-1</td>\n",
" <td>0.707365</td>\n",
" <td>0.916667</td>\n",
" <td>0.916667</td>\n",
" <td>0.690332</td>\n",
" <td>0.00000</td>\n",
" <td>-1.000000</td>\n",
" <td>benign</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>9</td>\n",
" <td>2.5</td>\n",
" <td>3</td>\n",
" <td>4.555555</td>\n",
" <td>2</td>\n",
" <td>6</td>\n",
" <td>3</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>-1</td>\n",
" <td>0.742606</td>\n",
" <td>1.000000</td>\n",
" <td>0.785719</td>\n",
" <td>0.808833</td>\n",
" <td>1.00000</td>\n",
" <td>-1.000000</td>\n",
" <td>benign</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>13</td>\n",
" <td>4.5</td>\n",
" <td>6</td>\n",
" <td>5.307692</td>\n",
" <td>2</td>\n",
" <td>16</td>\n",
" <td>9</td>\n",
" <td>1</td>\n",
" <td>...</td>\n",
" <td>-1</td>\n",
" <td>-1</td>\n",
" <td>-1</td>\n",
" <td>0.734633</td>\n",
" <td>0.939794</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.00000</td>\n",
" <td>-1.000000</td>\n",
" <td>benign</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>10 rows × 80 columns</p>\n",
"</div>"
],
"text/plain": [
" Querylength domain_token_count path_token_count avgdomaintokenlen \\\n",
"0 0 2 12 5.5 \n",
"1 0 3 12 5.0 \n",
"2 2 2 11 4.0 \n",
"3 0 2 7 4.5 \n",
"4 19 2 10 6.0 \n",
"5 0 2 10 5.5 \n",
"6 0 2 12 4.5 \n",
"7 0 2 11 3.5 \n",
"8 0 2 9 2.5 \n",
"9 0 2 13 4.5 \n",
"\n",
" longdomaintokenlen avgpathtokenlen tld charcompvowels charcompace \\\n",
"0 8 4.083334 2 15 7 \n",
"1 10 3.583333 3 12 8 \n",
"2 5 4.750000 2 16 11 \n",
"3 7 5.714286 2 15 10 \n",
"4 9 2.250000 2 9 5 \n",
"5 9 4.100000 2 15 11 \n",
"6 6 5.333334 2 24 9 \n",
"7 4 3.909091 2 15 6 \n",
"8 3 4.555555 2 6 3 \n",
"9 6 5.307692 2 16 9 \n",
"\n",
" ldl_url ... SymbolCount_FileName SymbolCount_Extension \\\n",
"0 0 ... -1 -1 \n",
"1 2 ... 1 0 \n",
"2 0 ... 2 0 \n",
"3 0 ... 0 0 \n",
"4 0 ... 5 4 \n",
"5 0 ... -1 -1 \n",
"6 0 ... 0 0 \n",
"7 0 ... 0 0 \n",
"8 0 ... 1 0 \n",
"9 1 ... -1 -1 \n",
"\n",
" SymbolCount_Afterpath Entropy_URL Entropy_Domain Entropy_DirectoryName \\\n",
"0 -1 0.676804 0.860529 -1.000000 \n",
"1 -1 0.715629 0.776796 0.693127 \n",
"2 1 0.677701 1.000000 0.677704 \n",
"3 -1 0.696067 0.879588 0.818007 \n",
"4 3 0.747202 0.833700 0.655459 \n",
"5 -1 0.732981 0.860529 -1.000000 \n",
"6 -1 0.692383 0.939794 0.910795 \n",
"7 -1 0.707365 0.916667 0.916667 \n",
"8 -1 0.742606 1.000000 0.785719 \n",
"9 -1 0.734633 0.939794 -1.000000 \n",
"\n",
" Entropy_Filename Entropy_Extension Entropy_Afterpath URL_Type_obf_Type \n",
"0 -1.000000 -1.00000 -1.000000 benign \n",
"1 0.738315 1.00000 -1.000000 benign \n",
"2 0.916667 0.00000 0.898227 benign \n",
"3 0.753585 0.00000 -1.000000 benign \n",
"4 0.829535 0.83615 0.823008 benign \n",
"5 -1.000000 -1.00000 -1.000000 benign \n",
"6 0.673973 0.00000 -1.000000 benign \n",
"7 0.690332 0.00000 -1.000000 benign \n",
"8 0.808833 1.00000 -1.000000 benign \n",
"9 -1.000000 -1.00000 -1.000000 benign \n",
"\n",
"[10 rows x 80 columns]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = pd.read_csv(\"FinalDataset/Phishing.csv\")\n",
"df.head(10)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Querylength</th>\n",
" <th>domain_token_count</th>\n",
" <th>path_token_count</th>\n",
" <th>avgdomaintokenlen</th>\n",
" <th>longdomaintokenlen</th>\n",
" <th>avgpathtokenlen</th>\n",
" <th>tld</th>\n",
" <th>charcompvowels</th>\n",
" <th>charcompace</th>\n",
" <th>ldl_url</th>\n",
" <th>...</th>\n",
" <th>SymbolCount_Directoryname</th>\n",
" <th>SymbolCount_FileName</th>\n",
" <th>SymbolCount_Extension</th>\n",
" <th>SymbolCount_Afterpath</th>\n",
" <th>Entropy_URL</th>\n",
" <th>Entropy_Domain</th>\n",
" <th>Entropy_DirectoryName</th>\n",
" <th>Entropy_Filename</th>\n",
" <th>Entropy_Extension</th>\n",
" <th>Entropy_Afterpath</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>15096.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>...</td>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>15367.000000</td>\n",
" <td>13541.000000</td>\n",
" <td>15177.000000</td>\n",
" <td>15364.000000</td>\n",
" <td>15364.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>3.446021</td>\n",
" <td>2.543698</td>\n",
" <td>8.477061</td>\n",
" <td>5.851956</td>\n",
" <td>10.027461</td>\n",
" <td>5.289936</td>\n",
" <td>2.543698</td>\n",
" <td>12.659986</td>\n",
" <td>8.398516</td>\n",
" <td>1.910913</td>\n",
" <td>...</td>\n",
" <td>2.120843</td>\n",
" <td>1.124618</td>\n",
" <td>0.500813</td>\n",
" <td>-0.158782</td>\n",
" <td>0.721684</td>\n",
" <td>0.854232</td>\n",
" <td>0.634859</td>\n",
" <td>0.682896</td>\n",
" <td>0.313617</td>\n",
" <td>-0.723793</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>14.151453</td>\n",
" <td>0.944938</td>\n",
" <td>4.660250</td>\n",
" <td>2.064581</td>\n",
" <td>5.281090</td>\n",
" <td>3.535097</td>\n",
" <td>0.944938</td>\n",
" <td>8.562206</td>\n",
" <td>6.329007</td>\n",
" <td>4.657731</td>\n",
" <td>...</td>\n",
" <td>2.777307</td>\n",
" <td>2.570246</td>\n",
" <td>2.261013</td>\n",
" <td>2.535939</td>\n",
" <td>0.049246</td>\n",
" <td>0.072641</td>\n",
" <td>0.510992</td>\n",
" <td>0.502288</td>\n",
" <td>0.576910</td>\n",
" <td>0.649785</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>0.000000</td>\n",
" <td>2.000000</td>\n",
" <td>0.000000</td>\n",
" <td>1.500000</td>\n",
" <td>2.000000</td>\n",
" <td>0.000000</td>\n",
" <td>2.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>...</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.000000</td>\n",
" <td>0.419560</td>\n",
" <td>0.561913</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.000000</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td>0.000000</td>\n",
" <td>2.000000</td>\n",
" <td>5.000000</td>\n",
" <td>4.500000</td>\n",
" <td>7.000000</td>\n",
" <td>3.800000</td>\n",
" <td>2.000000</td>\n",
" <td>6.000000</td>\n",
" <td>4.000000</td>\n",
" <td>0.000000</td>\n",
" <td>...</td>\n",
" <td>1.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>-1.000000</td>\n",
" <td>0.687215</td>\n",
" <td>0.798231</td>\n",
" <td>0.709532</td>\n",
" <td>0.707165</td>\n",
" <td>0.000000</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td>0.000000</td>\n",
" <td>2.000000</td>\n",
" <td>8.000000</td>\n",
" <td>5.500000</td>\n",
" <td>9.000000</td>\n",
" <td>4.500000</td>\n",
" <td>2.000000</td>\n",
" <td>11.000000</td>\n",
" <td>7.000000</td>\n",
" <td>0.000000</td>\n",
" <td>...</td>\n",
" <td>2.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>-1.000000</td>\n",
" <td>0.723217</td>\n",
" <td>0.859793</td>\n",
" <td>0.785949</td>\n",
" <td>0.814038</td>\n",
" <td>0.000000</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td>0.000000</td>\n",
" <td>3.000000</td>\n",
" <td>11.000000</td>\n",
" <td>6.666666</td>\n",
" <td>12.000000</td>\n",
" <td>5.571429</td>\n",
" <td>3.000000</td>\n",
" <td>17.000000</td>\n",
" <td>11.000000</td>\n",
" <td>1.000000</td>\n",
" <td>...</td>\n",
" <td>3.000000</td>\n",
" <td>1.000000</td>\n",
" <td>0.000000</td>\n",
" <td>-1.000000</td>\n",
" <td>0.757949</td>\n",
" <td>0.916667</td>\n",
" <td>0.859582</td>\n",
" <td>0.916667</td>\n",
" <td>1.000000</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>173.000000</td>\n",
" <td>19.000000</td>\n",
" <td>68.000000</td>\n",
" <td>29.500000</td>\n",
" <td>63.000000</td>\n",
" <td>105.000000</td>\n",
" <td>19.000000</td>\n",
" <td>94.000000</td>\n",
" <td>62.000000</td>\n",
" <td>58.000000</td>\n",
" <td>...</td>\n",
" <td>24.000000</td>\n",
" <td>31.000000</td>\n",
" <td>30.000000</td>\n",
" <td>29.000000</td>\n",
" <td>0.869701</td>\n",
" <td>1.000000</td>\n",
" <td>0.962479</td>\n",
" <td>1.000000</td>\n",
" <td>1.000000</td>\n",
" <td>1.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>8 rows × 79 columns</p>\n",
"</div>"
],
"text/plain": [
" Querylength domain_token_count path_token_count avgdomaintokenlen \\\n",
"count 15367.000000 15367.000000 15367.000000 15367.000000 \n",
"mean 3.446021 2.543698 8.477061 5.851956 \n",
"std 14.151453 0.944938 4.660250 2.064581 \n",
"min 0.000000 2.000000 0.000000 1.500000 \n",
"25% 0.000000 2.000000 5.000000 4.500000 \n",
"50% 0.000000 2.000000 8.000000 5.500000 \n",
"75% 0.000000 3.000000 11.000000 6.666666 \n",
"max 173.000000 19.000000 68.000000 29.500000 \n",
"\n",
" longdomaintokenlen avgpathtokenlen tld charcompvowels \\\n",
"count 15367.000000 15096.000000 15367.000000 15367.000000 \n",
"mean 10.027461 5.289936 2.543698 12.659986 \n",
"std 5.281090 3.535097 0.944938 8.562206 \n",
"min 2.000000 0.000000 2.000000 0.000000 \n",
"25% 7.000000 3.800000 2.000000 6.000000 \n",
"50% 9.000000 4.500000 2.000000 11.000000 \n",
"75% 12.000000 5.571429 3.000000 17.000000 \n",
"max 63.000000 105.000000 19.000000 94.000000 \n",
"\n",
" charcompace ldl_url ... SymbolCount_Directoryname \\\n",
"count 15367.000000 15367.000000 ... 15367.000000 \n",
"mean 8.398516 1.910913 ... 2.120843 \n",
"std 6.329007 4.657731 ... 2.777307 \n",
"min 0.000000 0.000000 ... -1.000000 \n",
"25% 4.000000 0.000000 ... 1.000000 \n",
"50% 7.000000 0.000000 ... 2.000000 \n",
"75% 11.000000 1.000000 ... 3.000000 \n",
"max 62.000000 58.000000 ... 24.000000 \n",
"\n",
" SymbolCount_FileName SymbolCount_Extension SymbolCount_Afterpath \\\n",
"count 15367.000000 15367.000000 15367.000000 \n",
"mean 1.124618 0.500813 -0.158782 \n",
"std 2.570246 2.261013 2.535939 \n",
"min -1.000000 -1.000000 -1.000000 \n",
"25% 0.000000 0.000000 -1.000000 \n",
"50% 0.000000 0.000000 -1.000000 \n",
"75% 1.000000 0.000000 -1.000000 \n",
"max 31.000000 30.000000 29.000000 \n",
"\n",
" Entropy_URL Entropy_Domain Entropy_DirectoryName Entropy_Filename \\\n",
"count 15367.000000 15367.000000 13541.000000 15177.000000 \n",
"mean 0.721684 0.854232 0.634859 0.682896 \n",
"std 0.049246 0.072641 0.510992 0.502288 \n",
"min 0.419560 0.561913 -1.000000 -1.000000 \n",
"25% 0.687215 0.798231 0.709532 0.707165 \n",
"50% 0.723217 0.859793 0.785949 0.814038 \n",
"75% 0.757949 0.916667 0.859582 0.916667 \n",
"max 0.869701 1.000000 0.962479 1.000000 \n",
"\n",
" Entropy_Extension Entropy_Afterpath \n",
"count 15364.000000 15364.000000 \n",
"mean 0.313617 -0.723793 \n",
"std 0.576910 0.649785 \n",
"min -1.000000 -1.000000 \n",
"25% 0.000000 -1.000000 \n",
"50% 0.000000 -1.000000 \n",
"75% 1.000000 -1.000000 \n",
"max 1.000000 1.000000 \n",
"\n",
"[8 rows x 79 columns]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.describe()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 15367 entries, 0 to 15366\n",
"Data columns (total 80 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 Querylength 15367 non-null int64 \n",
" 1 domain_token_count 15367 non-null int64 \n",
" 2 path_token_count 15367 non-null int64 \n",
" 3 avgdomaintokenlen 15367 non-null float64\n",
" 4 longdomaintokenlen 15367 non-null int64 \n",
" 5 avgpathtokenlen 15096 non-null float64\n",
" 6 tld 15367 non-null int64 \n",
" 7 charcompvowels 15367 non-null int64 \n",
" 8 charcompace 15367 non-null int64 \n",
" 9 ldl_url 15367 non-null int64 \n",
" 10 ldl_domain 15367 non-null int64 \n",
" 11 ldl_path 15367 non-null int64 \n",
" 12 ldl_filename 15367 non-null int64 \n",
" 13 ldl_getArg 15367 non-null int64 \n",
" 14 dld_url 15367 non-null int64 \n",
" 15 dld_domain 15367 non-null int64 \n",
" 16 dld_path 15367 non-null int64 \n",
" 17 dld_filename 15367 non-null int64 \n",
" 18 dld_getArg 15367 non-null int64 \n",
" 19 urlLen 15367 non-null int64 \n",
" 20 domainlength 15367 non-null int64 \n",
" 21 pathLength 15367 non-null int64 \n",
" 22 subDirLen 15367 non-null int64 \n",
" 23 fileNameLen 15367 non-null int64 \n",
" 24 this.fileExtLen 15367 non-null int64 \n",
" 25 ArgLen 15367 non-null int64 \n",
" 26 pathurlRatio 15367 non-null float64\n",
" 27 ArgUrlRatio 15367 non-null float64\n",
" 28 argDomanRatio 15367 non-null float64\n",
" 29 domainUrlRatio 15367 non-null float64\n",
" 30 pathDomainRatio 15367 non-null float64\n",
" 31 argPathRatio 15367 non-null float64\n",
" 32 executable 15367 non-null int64 \n",
" 33 isPortEighty 15367 non-null int64 \n",
" 34 NumberofDotsinURL 15367 non-null int64 \n",
" 35 ISIpAddressInDomainName 15367 non-null int64 \n",
" 36 CharacterContinuityRate 15367 non-null float64\n",
" 37 LongestVariableValue 15367 non-null int64 \n",
" 38 URL_DigitCount 15367 non-null int64 \n",
" 39 host_DigitCount 15367 non-null int64 \n",
" 40 Directory_DigitCount 15367 non-null int64 \n",
" 41 File_name_DigitCount 15367 non-null int64 \n",
" 42 Extension_DigitCount 15367 non-null int64 \n",
" 43 Query_DigitCount 15367 non-null int64 \n",
" 44 URL_Letter_Count 15367 non-null int64 \n",
" 45 host_letter_count 15367 non-null int64 \n",
" 46 Directory_LetterCount 15367 non-null int64 \n",
" 47 Filename_LetterCount 15367 non-null int64 \n",
" 48 Extension_LetterCount 15367 non-null int64 \n",
" 49 Query_LetterCount 15367 non-null int64 \n",
" 50 LongestPathTokenLength 15367 non-null int64 \n",
" 51 Domain_LongestWordLength 15367 non-null int64 \n",
" 52 Path_LongestWordLength 15367 non-null int64 \n",
" 53 sub-Directory_LongestWordLength 15367 non-null int64 \n",
" 54 Arguments_LongestWordLength 15367 non-null int64 \n",
" 55 URL_sensitiveWord 15367 non-null int64 \n",
" 56 URLQueries_variable 15367 non-null int64 \n",
" 57 spcharUrl 15367 non-null int64 \n",
" 58 delimeter_Domain 15367 non-null int64 \n",
" 59 delimeter_path 15367 non-null int64 \n",
" 60 delimeter_Count 15367 non-null int64 \n",
" 61 NumberRate_URL 15367 non-null float64\n",
" 62 NumberRate_Domain 15367 non-null float64\n",
" 63 NumberRate_DirectoryName 15358 non-null float64\n",
" 64 NumberRate_FileName 15358 non-null float64\n",
" 65 NumberRate_Extension 8012 non-null float64\n",
" 66 NumberRate_AfterPath 15364 non-null float64\n",
" 67 SymbolCount_URL 15367 non-null int64 \n",
" 68 SymbolCount_Domain 15367 non-null int64 \n",
" 69 SymbolCount_Directoryname 15367 non-null int64 \n",
" 70 SymbolCount_FileName 15367 non-null int64 \n",
" 71 SymbolCount_Extension 15367 non-null int64 \n",
" 72 SymbolCount_Afterpath 15367 non-null int64 \n",
" 73 Entropy_URL 15367 non-null float64\n",
" 74 Entropy_Domain 15367 non-null float64\n",
" 75 Entropy_DirectoryName 13541 non-null float64\n",
" 76 Entropy_Filename 15177 non-null float64\n",
" 77 Entropy_Extension 15364 non-null float64\n",
" 78 Entropy_Afterpath 15364 non-null float64\n",
" 79 URL_Type_obf_Type 15367 non-null object \n",
"dtypes: float64(21), int64(58), object(1)\n",
"memory usage: 9.4+ MB\n"
]
}
],
"source": [
"df.info()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"benign 7781\n",
"phishing 7586\n",
"Name: URL_Type_obf_Type, dtype: int64"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df[\"URL_Type_obf_Type\"].value_counts()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"avgpathtokenlen True\n",
"NumberRate_DirectoryName True\n",
"NumberRate_FileName True\n",
"NumberRate_Extension True\n",
"NumberRate_AfterPath True\n",
"Entropy_DirectoryName True\n",
"Entropy_Filename True\n",
"Entropy_Extension True\n",
"Entropy_Afterpath True\n",
"dtype: bool"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Comprobación de si existen valores nulos\n",
"is_null = df.isna().any()\n",
"is_null[is_null]"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"argPathRatio True\n",
"dtype: bool"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Comprobación de la existencia de valores infinitos\n",
"# Pueden haber valores que son las combinación de otros valores como por ejemplo una división\n",
"is_inf = df.isin([np.inf, -np.inf]).any()\n",
"is_inf[is_inf]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Representación gráfica de dos características de entrada"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 864x432 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Tenemos los valores de las 15367 URLs representadas gráfiamente para las siguientes variables:\n",
"# * domainUrlRatio = Ratio del dominio de la URL (Eje X)\n",
"# * domainlength = Longitud del dominio (Eje Y)\n",
"\n",
"# Luego representamos en diferentes colores a las categorías de la variable \"URL_Type_obf_Type\":\n",
"# benign (verde) 7781 URLs\n",
"# phishing (rojo) 7586 URLs\n",
"\n",
"plt.figure(figsize=(12, 6))\n",
"plt.scatter(df[\"domainUrlRatio\"][df['URL_Type_obf_Type'] == \"phishing\"], df[\"domainlength\"][df['URL_Type_obf_Type'] == \"phishing\"], c=\"r\", marker=\".\")\n",
"plt.scatter(df[\"domainUrlRatio\"][df['URL_Type_obf_Type'] == \"benign\"], df[\"domainlength\"][df['URL_Type_obf_Type'] == \"benign\"], c=\"g\", marker=\"x\")\n",
"plt.xlabel(\"domainUrlRatio\", fontsize=13)\n",
"plt.ylabel(\"domainlength\", fontsize=13)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 style=\"color:blue\">4. División del conjunto de datos</h2>"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"# División del conjunto de datos\n",
"train_set, val_set, test_set = train_val_test_split(df)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Longitud del Training Set: 9220\n",
"Longitud del Validation Set: 3073\n",
"Longitud del Test Set: 3074\n"
]
}
],
"source": [
"print(\"Longitud del Training Set:\", len(train_set))\n",
"print(\"Longitud del Validation Set:\", len(val_set))\n",
"print(\"Longitud del Test Set:\", len(test_set))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Para cada uno de los subconjuntos, separamos las etiquetas de las características de entrada"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 4.1 Conjunto de datos de entrenamiento"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"X_train = train_set.drop(\"URL_Type_obf_Type\", axis=1)\n",
"y_train = train_set[\"URL_Type_obf_Type\"].copy()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 4.2 Conjunto de datos de validación"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"X_val = val_set.drop(\"URL_Type_obf_Type\", axis=1)\n",
"y_val = val_set[\"URL_Type_obf_Type\"].copy()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 4.3 Conjunto de datos de pruebas"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
"X_test = test_set.drop(\"URL_Type_obf_Type\", axis=1)\n",
"y_test = test_set[\"URL_Type_obf_Type\"].copy()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 style=\"color:blue\">5. Preparación del conjunto de datos</h2>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 5.1 Eliminamos el atributo que tiene valores infinitos"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"argPathRatio True\n",
"dtype: bool"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Verificamos que la variable \"argPathRatio\" tiene valores infinitos\n",
"is_inf = df.isin([np.inf, -np.inf]).any()\n",
"is_inf[is_inf]"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"# La acción de eliminar la variable \"argPathRatio\" se tomó despues de evaluar opciones como eliminar las filas o\n",
"# reeemplazar esos valores por un valor, se concluyó que eliminar el atributo es la mejor decisión para este tipo\n",
"# de algoritmos.\n",
"X_train = X_train.drop(\"argPathRatio\", axis=1)\n",
"X_val = X_val.drop(\"argPathRatio\", axis=1)\n",
"X_test = X_test.drop(\"argPathRatio\", axis=1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 5.2 Rellenamos los valores nulos con la mediana"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [],
"source": [
"# Importamos de sklearn la clase SimpleImputer \n",
"from sklearn.impute import SimpleImputer\n",
"\n",
"# Instanciamos la clase \"SimpleImputer\" pasándole la estrategia \"median\" al objeto imputer \n",
"imputer = SimpleImputer(strategy=\"median\")\n",
"\n",
"# Luego pasaremos a nuestro conjunto de datos el objeto \"imputer\" para que de manera automática busque los valores\n",
"# nulos y los sutituya por la mediana sin necesidad de tenerle q proporcionar el nombre de las características o\n",
"# atributos de entrada.\n",
"\n",
"# La clase imputer no admite valores categoricos, en este caso no tenemos que eliminar los atributos categóricos ya que\n",
"# todas las características de entrada son númericos (enteros o floats)."
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"# Reemplazamos los valores nulos con la MEDIANA y obtenemos los subconjuntos preprocesados\n",
"# El inconveniente al usar \"imputer.fit_transform\" es que los subconjuntos se convierten en arrays de numpy\n",
"X_train_prep = imputer.fit_transform(X_train)\n",
"X_val_prep = imputer.fit_transform(X_val)\n",
"X_test_prep = imputer.fit_transform(X_test)"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"numpy.ndarray"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(X_train_prep)"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [],
"source": [
"# Para evitar este inconveniente, transformamos el resultado a un DataFrame de Pandas\n",
"X_train_prep = pd.DataFrame(X_train_prep, columns=X_train.columns, index=y_train.index)\n",
"X_val_prep = pd.DataFrame(X_val_prep, columns=X_val.columns, index=y_val.index)\n",
"X_test_prep = pd.DataFrame(X_test_prep, columns=X_test.columns, index=y_test.index)"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Querylength</th>\n",
" <th>domain_token_count</th>\n",
" <th>path_token_count</th>\n",
" <th>avgdomaintokenlen</th>\n",
" <th>longdomaintokenlen</th>\n",
" <th>avgpathtokenlen</th>\n",
" <th>tld</th>\n",
" <th>charcompvowels</th>\n",
" <th>charcompace</th>\n",
" <th>ldl_url</th>\n",
" <th>...</th>\n",
" <th>SymbolCount_Directoryname</th>\n",
" <th>SymbolCount_FileName</th>\n",
" <th>SymbolCount_Extension</th>\n",
" <th>SymbolCount_Afterpath</th>\n",
" <th>Entropy_URL</th>\n",
" <th>Entropy_Domain</th>\n",
" <th>Entropy_DirectoryName</th>\n",
" <th>Entropy_Filename</th>\n",
" <th>Entropy_Extension</th>\n",
" <th>Entropy_Afterpath</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2134</th>\n",
" <td>0.0</td>\n",
" <td>2.0</td>\n",
" <td>6.0</td>\n",
" <td>2.000000</td>\n",
" <td>2.0</td>\n",
" <td>8.666667</td>\n",
" <td>2.0</td>\n",
" <td>17.0</td>\n",
" <td>10.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>2.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>-1.0</td>\n",
" <td>0.681183</td>\n",
" <td>0.827729</td>\n",
" <td>0.702637</td>\n",
" <td>0.849605</td>\n",
" <td>0.000000</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9178</th>\n",
" <td>0.0</td>\n",
" <td>4.0</td>\n",
" <td>18.0</td>\n",
" <td>3.250000</td>\n",
" <td>5.0</td>\n",
" <td>1.000000</td>\n",
" <td>4.0</td>\n",
" <td>18.0</td>\n",
" <td>13.0</td>\n",
" <td>2.0</td>\n",
" <td>...</td>\n",
" <td>12.0</td>\n",
" <td>3.0</td>\n",
" <td>0.0</td>\n",
" <td>4.0</td>\n",
" <td>0.695232</td>\n",
" <td>0.820160</td>\n",
" <td>0.682849</td>\n",
" <td>0.875578</td>\n",
" <td>0.000000</td>\n",
" <td>0.778747</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13622</th>\n",
" <td>0.0</td>\n",
" <td>3.0</td>\n",
" <td>3.0</td>\n",
" <td>6.666666</td>\n",
" <td>14.0</td>\n",
" <td>4.000000</td>\n",
" <td>3.0</td>\n",
" <td>1.0</td>\n",
" <td>1.0</td>\n",
" <td>1.0</td>\n",
" <td>...</td>\n",
" <td>1.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>-1.0</td>\n",
" <td>0.836006</td>\n",
" <td>0.869991</td>\n",
" <td>0.879588</td>\n",
" <td>1.000000</td>\n",
" <td>0.000000</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15182</th>\n",
" <td>0.0</td>\n",
" <td>3.0</td>\n",
" <td>5.0</td>\n",
" <td>3.333333</td>\n",
" <td>4.0</td>\n",
" <td>3.000000</td>\n",
" <td>3.0</td>\n",
" <td>5.0</td>\n",
" <td>2.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>2.0</td>\n",
" <td>1.0</td>\n",
" <td>0.0</td>\n",
" <td>-1.0</td>\n",
" <td>0.731804</td>\n",
" <td>0.796490</td>\n",
" <td>0.796658</td>\n",
" <td>1.000000</td>\n",
" <td>1.000000</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8013</th>\n",
" <td>74.0</td>\n",
" <td>2.0</td>\n",
" <td>13.0</td>\n",
" <td>9.500000</td>\n",
" <td>17.0</td>\n",
" <td>7.875000</td>\n",
" <td>2.0</td>\n",
" <td>21.0</td>\n",
" <td>29.0</td>\n",
" <td>26.0</td>\n",
" <td>...</td>\n",
" <td>4.0</td>\n",
" <td>5.0</td>\n",
" <td>4.0</td>\n",
" <td>3.0</td>\n",
" <td>0.653371</td>\n",
" <td>0.820569</td>\n",
" <td>0.758055</td>\n",
" <td>0.714969</td>\n",
" <td>0.712215</td>\n",
" <td>0.708031</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12408</th>\n",
" <td>0.0</td>\n",
" <td>3.0</td>\n",
" <td>4.0</td>\n",
" <td>8.333333</td>\n",
" <td>19.0</td>\n",
" <td>3.750000</td>\n",
" <td>3.0</td>\n",
" <td>5.0</td>\n",
" <td>1.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>2.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>-1.0</td>\n",
" <td>0.726479</td>\n",
" <td>0.789538</td>\n",
" <td>0.800705</td>\n",
" <td>1.000000</td>\n",
" <td>0.000000</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>509</th>\n",
" <td>20.0</td>\n",
" <td>2.0</td>\n",
" <td>13.0</td>\n",
" <td>4.500000</td>\n",
" <td>6.0</td>\n",
" <td>3.000000</td>\n",
" <td>2.0</td>\n",
" <td>24.0</td>\n",
" <td>17.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>1.0</td>\n",
" <td>14.0</td>\n",
" <td>13.0</td>\n",
" <td>12.0</td>\n",
" <td>0.678515</td>\n",
" <td>0.796658</td>\n",
" <td>0.871049</td>\n",
" <td>0.695112</td>\n",
" <td>0.701662</td>\n",
" <td>0.698106</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10714</th>\n",
" <td>0.0</td>\n",
" <td>3.0</td>\n",
" <td>8.0</td>\n",
" <td>6.666666</td>\n",
" <td>14.0</td>\n",
" <td>4.250000</td>\n",
" <td>3.0</td>\n",
" <td>11.0</td>\n",
" <td>5.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>4.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>-1.0</td>\n",
" <td>0.745348</td>\n",
" <td>0.869991</td>\n",
" <td>0.788921</td>\n",
" <td>1.000000</td>\n",
" <td>0.000000</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3986</th>\n",
" <td>0.0</td>\n",
" <td>2.0</td>\n",
" <td>6.0</td>\n",
" <td>6.500000</td>\n",
" <td>10.0</td>\n",
" <td>4.500000</td>\n",
" <td>2.0</td>\n",
" <td>7.0</td>\n",
" <td>7.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>2.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>-1.0</td>\n",
" <td>0.760843</td>\n",
" <td>0.798231</td>\n",
" <td>0.822491</td>\n",
" <td>0.796670</td>\n",
" <td>0.000000</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>748</th>\n",
" <td>0.0</td>\n",
" <td>2.0</td>\n",
" <td>8.0</td>\n",
" <td>4.000000</td>\n",
" <td>5.0</td>\n",
" <td>5.750000</td>\n",
" <td>2.0</td>\n",
" <td>14.0</td>\n",
" <td>14.0</td>\n",
" <td>1.0</td>\n",
" <td>...</td>\n",
" <td>2.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>-1.0</td>\n",
" <td>0.709062</td>\n",
" <td>0.929897</td>\n",
" <td>0.884735</td>\n",
" <td>0.674994</td>\n",
" <td>0.000000</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>10 rows × 78 columns</p>\n",
"</div>"
],
"text/plain": [
" Querylength domain_token_count path_token_count avgdomaintokenlen \\\n",
"2134 0.0 2.0 6.0 2.000000 \n",
"9178 0.0 4.0 18.0 3.250000 \n",
"13622 0.0 3.0 3.0 6.666666 \n",
"15182 0.0 3.0 5.0 3.333333 \n",
"8013 74.0 2.0 13.0 9.500000 \n",
"12408 0.0 3.0 4.0 8.333333 \n",
"509 20.0 2.0 13.0 4.500000 \n",
"10714 0.0 3.0 8.0 6.666666 \n",
"3986 0.0 2.0 6.0 6.500000 \n",
"748 0.0 2.0 8.0 4.000000 \n",
"\n",
" longdomaintokenlen avgpathtokenlen tld charcompvowels charcompace \\\n",
"2134 2.0 8.666667 2.0 17.0 10.0 \n",
"9178 5.0 1.000000 4.0 18.0 13.0 \n",
"13622 14.0 4.000000 3.0 1.0 1.0 \n",
"15182 4.0 3.000000 3.0 5.0 2.0 \n",
"8013 17.0 7.875000 2.0 21.0 29.0 \n",
"12408 19.0 3.750000 3.0 5.0 1.0 \n",
"509 6.0 3.000000 2.0 24.0 17.0 \n",
"10714 14.0 4.250000 3.0 11.0 5.0 \n",
"3986 10.0 4.500000 2.0 7.0 7.0 \n",
"748 5.0 5.750000 2.0 14.0 14.0 \n",
"\n",
" ldl_url ... SymbolCount_Directoryname SymbolCount_FileName \\\n",
"2134 0.0 ... 2.0 0.0 \n",
"9178 2.0 ... 12.0 3.0 \n",
"13622 1.0 ... 1.0 0.0 \n",
"15182 0.0 ... 2.0 1.0 \n",
"8013 26.0 ... 4.0 5.0 \n",
"12408 0.0 ... 2.0 0.0 \n",
"509 0.0 ... 1.0 14.0 \n",
"10714 0.0 ... 4.0 0.0 \n",
"3986 0.0 ... 2.0 0.0 \n",
"748 1.0 ... 2.0 0.0 \n",
"\n",
" SymbolCount_Extension SymbolCount_Afterpath Entropy_URL \\\n",
"2134 0.0 -1.0 0.681183 \n",
"9178 0.0 4.0 0.695232 \n",
"13622 0.0 -1.0 0.836006 \n",
"15182 0.0 -1.0 0.731804 \n",
"8013 4.0 3.0 0.653371 \n",
"12408 0.0 -1.0 0.726479 \n",
"509 13.0 12.0 0.678515 \n",
"10714 0.0 -1.0 0.745348 \n",
"3986 0.0 -1.0 0.760843 \n",
"748 0.0 -1.0 0.709062 \n",
"\n",
" Entropy_Domain Entropy_DirectoryName Entropy_Filename \\\n",
"2134 0.827729 0.702637 0.849605 \n",
"9178 0.820160 0.682849 0.875578 \n",
"13622 0.869991 0.879588 1.000000 \n",
"15182 0.796490 0.796658 1.000000 \n",
"8013 0.820569 0.758055 0.714969 \n",
"12408 0.789538 0.800705 1.000000 \n",
"509 0.796658 0.871049 0.695112 \n",
"10714 0.869991 0.788921 1.000000 \n",
"3986 0.798231 0.822491 0.796670 \n",
"748 0.929897 0.884735 0.674994 \n",
"\n",
" Entropy_Extension Entropy_Afterpath \n",
"2134 0.000000 -1.000000 \n",
"9178 0.000000 0.778747 \n",
"13622 0.000000 -1.000000 \n",
"15182 1.000000 -1.000000 \n",
"8013 0.712215 0.708031 \n",
"12408 0.000000 -1.000000 \n",
"509 0.701662 0.698106 \n",
"10714 0.000000 -1.000000 \n",
"3986 0.000000 -1.000000 \n",
"748 0.000000 -1.000000 \n",
"\n",
"[10 rows x 78 columns]"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_train_prep.head(10)"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Series([], dtype: bool)"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Comprobamos si hay valores nulos en el conjunto de datos de entrenamiento\n",
"is_null = X_train_prep.isna().any()\n",
"is_null[is_null]"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Series([], dtype: bool)"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Comprobación de la existencia de valores infinitos en el conjunto de datos de entrenamiento\n",
"is_inf = X_train_prep.isin([np.inf, -np.inf]).any()\n",
"is_inf[is_inf]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 style=\"color:blue\">6. SMV: Kernel lineal</h2>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Entrenaremos nuestro algoritmo de **2 formas**:\n",
"\n",
"<h4>1era forma (CONJUNTO DE DATOS REDUCIDO):</h4>\n",
"Voy a entrenarlo extrayendo únicamente 2 características de entrada (domainUrlRatio y domainlength) para poder representar gráficamente el límite de decisión.\n",
"\n",
"<h4>2da forma: (CONJUNTO DE DATOS COMPLETO)</h4> \n",
"Voy a entrenarlo utilizando las 78 carcacterísticas de entrada."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 6.1 Conjunto de datos reducido"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Entrenamiento del algoritmo con un conjunto de datos reducido**"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [],
"source": [
"# Reducimos el conjunto de datos a 2 atributos ((domainUrlRatio y domainlength) )para representarlo gráficamente:\n",
"X_train_reduced = X_train_prep[[\"domainUrlRatio\", \"domainlength\"]].copy()\n",
"X_val_reduced = X_val_prep[[\"domainUrlRatio\", \"domainlength\"]].copy()"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>domainUrlRatio</th>\n",
" <th>domainlength</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2134</th>\n",
" <td>0.072464</td>\n",
" <td>5.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9178</th>\n",
" <td>0.166667</td>\n",
" <td>16.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13622</th>\n",
" <td>0.511628</td>\n",
" <td>22.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15182</th>\n",
" <td>0.315789</td>\n",
" <td>12.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8013</th>\n",
" <td>0.107527</td>\n",
" <td>20.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5191</th>\n",
" <td>0.116667</td>\n",
" <td>14.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13418</th>\n",
" <td>0.477273</td>\n",
" <td>21.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5390</th>\n",
" <td>0.157895</td>\n",
" <td>9.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>860</th>\n",
" <td>0.072917</td>\n",
" <td>7.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7270</th>\n",
" <td>0.207547</td>\n",
" <td>11.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>9220 rows × 2 columns</p>\n",
"</div>"
],
"text/plain": [
" domainUrlRatio domainlength\n",
"2134 0.072464 5.0\n",
"9178 0.166667 16.0\n",
"13622 0.511628 22.0\n",
"15182 0.315789 12.0\n",
"8013 0.107527 20.0\n",
"... ... ...\n",
"5191 0.116667 14.0\n",
"13418 0.477273 21.0\n",
"5390 0.157895 9.0\n",
"860 0.072917 7.0\n",
"7270 0.207547 11.0\n",
"\n",
"[9220 rows x 2 columns]"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Conjunto de datos de entrenamiento reducido de las características de entrada\n",
"X_train_reduced"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### SVM Large Margin Classification\n",
"Vamos a entrenar nuestro algoritmo SVM con un kernel lineal"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"SVC(C=50, break_ties=False, cache_size=200, class_weight=None, coef0=0.0,\n",
" decision_function_shape='ovr', degree=3, gamma='scale', kernel='linear',\n",
" max_iter=-1, probability=False, random_state=None, shrinking=True,\n",
" tol=0.001, verbose=False)"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Importamos la clase SVC de sklearn.svm\n",
"from sklearn.svm import SVC\n",
"\n",
"# Luego instanciamos la clase SVC en un objeto \"svm_clf\" asignándole el parámetro kernel = 'linear ' y otro parámetro\n",
"# c=50 que va a controlar la distania de los márgenes.\n",
"svm_clf = SVC(kernel=\"linear\", C=50)\n",
"\n",
"# Luego entrenamos nuestro algoritmo SVM\n",
"# invocamos el método fit y le proporcionamos el conjunto de datos de entrenamiento reducido y las etiquetas del conjunto\n",
"# de entrenamiento.\n",
"svm_clf.fit(X_train_reduced, y_train)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Representación del límite de decisión**"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
"def plot_svc_decision_boundary(svm_clf, xmin, xmax):\n",
" w = svm_clf.coef_[0]\n",
" b = svm_clf.intercept_[0]\n",
"\n",
" x0 = np.linspace(xmin, xmax, 200)\n",
" decision_boundary = -w[0]/w[1] * x0 - b/w[1]\n",
"\n",
" margin = 1/w[1]\n",
" gutter_up = decision_boundary + margin\n",
" gutter_down = decision_boundary - margin\n",
"\n",
" svs = svm_clf.support_vectors_\n",
" plt.scatter(svs[:, 0], svs[:, 1], s=180, facecolors='#FFAAAA')\n",
" plt.plot(x0, decision_boundary, \"k-\", linewidth=2)\n",
" plt.plot(x0, gutter_up, \"k--\", linewidth=2)\n",
" plt.plot(x0, gutter_down, \"k--\", linewidth=2)"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 864x432 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(12, 6))\n",
"plt.plot(X_train_reduced.values[:, 0][y_train==\"phishing\"], X_train_reduced.values[:, 1][y_train==\"phishing\"], \"g^\")\n",
"plt.plot(X_train_reduced.values[:, 0][y_train==\"benign\"], X_train_reduced.values[:, 1][y_train==\"benign\"], \"bs\")\n",
"plot_svc_decision_boundary(svm_clf, 0, 1)\n",
"plt.title(\"$C = {}$\".format(svm_clf.C), fontsize=16)\n",
"plt.axis([0, 1, -100, 250])\n",
"plt.xlabel(\"domainUrlRatio\", fontsize=13)\n",
"plt.ylabel(\"domainlength\", fontsize=13)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Vemos a los datos pertenecientes a la clase phishing en verde (triángulos) y los datos de la clase benign en azul \n",
"# (cuadrados).\n",
"\n",
"# Luego observamos el límete de decisión (la recta) que ha construido el algoritmo SVM. Este está separando los ejemplos\n",
"# legítimos de los de phishing de una forma correcta. Los ejemplos que están en rojo son los de la clase legítima que ha\n",
"# clasificado correctamente."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Predicción con un conjunto de datos reducido**"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [],
"source": [
"# Validación del modelo\n",
"# Hacemos predicción de la variable \"URL_Type_obf_Type\" utilizando la data de validación \"X_val_reduced\"\n",
"y_pred = svm_clf.predict(X_val_reduced)"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"F1 Score: 0.8142614601018675\n"
]
}
],
"source": [
"# Luego comparamos esa predicción con los valores reales\n",
"# Mi algoritmo ha sido capaz de predecir correctamente en un 81.43% para mi conjunto de datos de validación\n",
"# Es decir, para un 81.43 % de URLs que no ha visto nunca, ha sido capaz de clasificar correctamente en URLs legítimas\n",
"# y de phishing.\n",
"print(\"F1 Score:\", f1_score(y_pred, y_val, pos_label='phishing'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Como se verá más adelante, para determinados kernels es muy importante escalar el conjunto de datos. En ese caso, para el kernel lineal, no es tan relevante, aunque es posible que proporcione mejores resultados.**"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Pipeline(memory=None,\n",
" steps=[('scaler',\n",
" RobustScaler(copy=True, quantile_range=(25.0, 75.0),\n",
" with_centering=True, with_scaling=True)),\n",
" ('linear_svc',\n",
" SVC(C=50, break_ties=False, cache_size=200, class_weight=None,\n",
" coef0=0.0, decision_function_shape='ovr', degree=3,\n",
" gamma='scale', kernel='linear', max_iter=-1,\n",
" probability=False, random_state=None, shrinking=True,\n",
" tol=0.001, verbose=False))],\n",
" verbose=False)"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Aplicaremos escalado utilizando un pipeline, por un lado el transformador RobustScaler() para escalar datos y por otro\n",
"# lado el algoritmo SVM con el kernel lineal.\n",
"svm_clf_sc = Pipeline([\n",
" (\"scaler\", RobustScaler()),\n",
" (\"linear_svc\", SVC(kernel=\"linear\", C=50)),\n",
" ])\n",
"\n",
"svm_clf_sc.fit(X_train_reduced, y_train)"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [],
"source": [
"# Hacemos la predicción con el conjunto de datos de validación\n",
"y_pred = svm_clf_sc.predict(X_val_reduced)"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"F1 Score: 0.8142614601018675\n"
]
}
],
"source": [
"# Para un 81.43 % de URLs que no ha visto nunca, ha sido capaz de clasificar correctamente en URLs legítimas\n",
"# y de phishing.\n",
"# No hay mucha diferencia en aplicar o no escalado usando un kernel lineal.\n",
"# Cuando aplicamos kernels no lineales, escalar si proporciona mejores resultados.\n",
"print(\"F1 Score:\", f1_score(y_pred, y_val, pos_label='phishing'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 6.2 Conjunto de datos completo"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"SVC(C=1, break_ties=False, cache_size=200, class_weight=None, coef0=0.0,\n",
" decision_function_shape='ovr', degree=3, gamma='scale', kernel='linear',\n",
" max_iter=-1, probability=False, random_state=None, shrinking=True,\n",
" tol=0.001, verbose=False)"
]
},
"execution_count": 54,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Entrenamiento con todo el conjunto de datos\n",
"from sklearn.svm import SVC\n",
"\n",
"svm_clf = SVC(kernel=\"linear\", C=1)\n",
"svm_clf.fit(X_train_prep, y_train)"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array(['benign', 'benign', 'benign', ..., 'phishing', 'phishing',\n",
" 'phishing'], dtype=object)"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Realizamos las predicciones utilizando la data de validación\n",
"y_pred = svm_clf.predict(X_val_prep)\n",
"y_pred"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"F1 Score: 0.9611330698287219\n"
]
}
],
"source": [
"# Mi algoritmo ha sido capaz de clasificar correctamente en un 96.11% para mi conjunto de datos de validación\n",
"print(\"F1 Score:\", f1_score(y_pred, y_val, pos_label='phishing'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 style=\"color:blue\">7. SMV: Kernel no lineal</h2>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.1. Polynomial Kernel (I)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Entrenamiento del algoritmo con un conjunto de datos reducido"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [],
"source": [
"# Para representar el límite de decisión tenemos que pasar la variable objetivo a numérica en las bases de datos\n",
"# y_train & y_val\n",
"\n",
"# Luego convertimos las categorias 'benign' y 'phishing' a 0 y 1 respectivamente, esto para representar la longitud\n",
"# del límite de decisión.\n",
"\n",
"y_train_num = y_train.factorize()[0]\n",
"y_val_num = y_val.factorize()[0]"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Pipeline(memory=None,\n",
" steps=[('poly_features',\n",
" PolynomialFeatures(degree=3, include_bias=True,\n",
" interaction_only=False, order='C')),\n",
" ('scaler',\n",
" StandardScaler(copy=True, with_mean=True, with_std=True)),\n",
" ('svm_clf',\n",
" LinearSVC(C=20, class_weight=None, dual=True,\n",
" fit_intercept=True, intercept_scaling=1,\n",
" loss='hinge', max_iter=100000, multi_class='ovr',\n",
" penalty='l2', random_state=42, tol=0.0001,\n",
" verbose=0))],\n",
" verbose=False)"
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Utilizando un pipeline, vamos a realizar algunas transformaciones sobre nuestro kernel lineal.\n",
"\n",
"# \"poly_features\", PolynomialFeatures(degree=3) -> Convierte varias de las características de entrada a características\n",
"# polinómicas. Es decir, coge los atributos de entrada (X1, X2, X3,...X79) y las transforma en características polinómicas\n",
"# donde concretamente llega a un límite de polinomio de un grado igual a 3. \n",
"\n",
"# \"scaler\", StandardScaler() -> Escalo mis características.\n",
"\n",
"# (\"svm_clf\", LinearSVC(C=20, loss=\"hinge\", random_state=42, max_iter=100000) -> entrenamos un algoritmo SVM lineal. Con\n",
"# la diferencia que ahora estoy introduciendo características polinómicas y el resultado será un límite de desición no\n",
"# lineal\n",
"\n",
"from sklearn.datasets import make_moons\n",
"from sklearn.svm import LinearSVC\n",
"from sklearn.preprocessing import PolynomialFeatures\n",
"\n",
"polynomial_svm_clf = Pipeline([\n",
" (\"poly_features\", PolynomialFeatures(degree=3)),\n",
" (\"scaler\", StandardScaler()),\n",
" (\"svm_clf\", LinearSVC(C=20, loss=\"hinge\", random_state=42, max_iter=100000))\n",
" ])\n",
"\n",
"polynomial_svm_clf.fit(X_train_reduced, y_train_num)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Representación del límite de decisión**"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [],
"source": [
"def plot_dataset(X, y):\n",
" plt.plot(X[:, 0][y==1], X[:, 1][y==1], \"g.\")\n",
" plt.plot(X[:, 0][y==0], X[:, 1][y==0], \"b.\")"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1080x360 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"def plot_predictions(clf, axes):\n",
" x0s = np.linspace(axes[0], axes[1], 100)\n",
" x1s = np.linspace(axes[2], axes[3], 100)\n",
" x0, x1 = np.meshgrid(x0s, x1s)\n",
" X = np.c_[x0.ravel(), x1.ravel()]\n",
" y_pred = clf.predict(X).reshape(x0.shape)\n",
" y_decision = clf.decision_function(X).reshape(x0.shape)\n",
" plt.contourf(x0, x1, y_pred, cmap=plt.cm.brg, alpha=0.2)\n",
" plt.contourf(x0, x1, y_decision, cmap=plt.cm.brg, alpha=0.1)\n",
"\n",
"fig, axes = plt.subplots(ncols=2, figsize=(15,5), sharey=True)\n",
"plt.sca(axes[0])\n",
"plot_dataset(X_train_reduced.values, y_train_num)\n",
"plot_predictions(polynomial_svm_clf, [0, 1, -100, 250])\n",
"plt.xlabel(\"domainUrlRatio\", fontsize=11)\n",
"plt.ylabel(\"domainlength\", fontsize=11)\n",
"plt.sca(axes[1])\n",
"plot_predictions(polynomial_svm_clf, [0, 1, -100, 250])\n",
"plt.xlabel(\"domainUrlRatio\", fontsize=11)\n",
"plt.ylabel(\"domainlength\", fontsize=11)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Observamos en azul a las URLs benigas y en verde observamos las URLs de phishing.\n",
"# Al generar características polinómicas, el resultado es un límite de decisión no lineal (color rosado). Aparentemente\n",
"# representa bastante bien la separación entre ambas clases."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Predicción con el conjunto de datos reducido**"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [],
"source": [
"# Hacemos la predicción con el conjunto de datos de validación reducido\n",
"y_pred = polynomial_svm_clf.predict(X_val_reduced)"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"F1 Score: 0.8574514038876889\n"
]
}
],
"source": [
"# Mi algoritmo ha sido capaz de predecir correctamente en un 85.74% para mi conjunto de datos de validación\n",
"print(\"F1 Score:\", f1_score(y_pred, y_val_num))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.2. Polynomial Kernel (II)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Existe una forma más sencilla de entrenar un algoritmo SVM que utilize polynomial kernel utilizando el parámetro **kernel** de la propia función implementada en **sklearn**"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Entrenamiento del algoritmo con un conjunto de datos reducido**"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"SVC(C=20, break_ties=False, cache_size=200, class_weight=None, coef0=10,\n",
" decision_function_shape='ovr', degree=3, gamma='scale', kernel='poly',\n",
" max_iter=-1, probability=False, random_state=None, shrinking=True,\n",
" tol=0.001, verbose=False)"
]
},
"execution_count": 82,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Instanciamos la clase SVC en un objeto \"svm_clf\" asignándole el parámetro kernel = 'poly', c=50 que va a controlar la \n",
"# distania de los márgenes y degree=3 para que genere característias polinómicas de grado 3.\n",
"svm_clf = SVC(kernel=\"poly\", degree=3, coef0=10, C=20)\n",
"svm_clf.fit(X_train_reduced, y_train_num)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Representación del límite de decisión**"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1080x360 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"fig, axes = plt.subplots(ncols=2, figsize=(15,5), sharey=True)\n",
"plt.sca(axes[0])\n",
"plot_dataset(X_train_reduced.values, y_train_num)\n",
"plot_predictions(svm_clf, [0, 1, -100, 250])\n",
"plt.xlabel(\"domainUrlRatio\", fontsize=11)\n",
"plt.ylabel(\"domainlength\", fontsize=11)\n",
"plt.sca(axes[1])\n",
"plot_predictions(svm_clf, [0, 1, -100, 250])\n",
"plt.xlabel(\"domainUrlRatio\", fontsize=11)\n",
"plt.ylabel(\"domainlength\", fontsize=11)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Predicción con un conjunto de datos reducido**"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [],
"source": [
"# Hacemos la predicción con el conjunto de datos de validación reducido\n",
"y_pred = svm_clf.predict(X_val_reduced)"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"F1 Score: 0.8249238062986793\n"
]
}
],
"source": [
"# Mi algoritmo ha sido capaz de predecir correctamente en un 82.49% para mi conjunto de datos de validación\n",
"print(\"F1 Score:\", f1_score(y_pred, y_val_num))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Predicción con el conjunto de datos completo**"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"SVC(C=40, break_ties=False, cache_size=200, class_weight=None, coef0=10,\n",
" decision_function_shape='ovr', degree=3, gamma='scale', kernel='poly',\n",
" max_iter=-1, probability=False, random_state=None, shrinking=True,\n",
" tol=0.001, verbose=False)"
]
},
"execution_count": 87,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"svm_clf = SVC(kernel=\"poly\", degree=3, coef0=10, C=40)\n",
"svm_clf.fit(X_train_prep, y_train_num)"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [],
"source": [
"# Hacemos la predicción con el conjunto de datos de validación\n",
"y_pred = svm_clf.predict(X_val_prep)"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"F1 Score: 0.9715984147952443\n"
]
}
],
"source": [
"# Mi algoritmo ha sido capaz de predecir correctamente en un 97.16% para mi conjunto de datos de validación\n",
"print(\"F1 Score:\", f1_score(y_pred, y_val_num))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7.3. Gaussian Kernel"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Entrenamiento del algoritmo con un conjunto de datos reducido**"
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Pipeline(memory=None,\n",
" steps=[('scaler',\n",
" RobustScaler(copy=True, quantile_range=(25.0, 75.0),\n",
" with_centering=True, with_scaling=True)),\n",
" ('svm_clf',\n",
" SVC(C=1000, break_ties=False, cache_size=200,\n",
" class_weight=None, coef0=0.0,\n",
" decision_function_shape='ovr', degree=3, gamma=0.5,\n",
" kernel='rbf', max_iter=-1, probability=False,\n",
" random_state=None, shrinking=True, tol=0.001,\n",
" verbose=False))],\n",
" verbose=False)"
]
},
"execution_count": 88,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Utilizando un pipeline, vamos a realizar algunas transformaciones sobre nuestro kernel.\n",
"\n",
"# \"scaler\", RobustScaler() -> Escalo mis características.\n",
"\n",
"# \"svm_clf\", SVC(kernel=\"rbf\", gamma=0.5, C=1000) -> donde: kernel=\"rbf\" es el kernel gaussiano \n",
"\n",
"rbf_kernel_svm_clf = Pipeline([\n",
" (\"scaler\", RobustScaler()),\n",
" (\"svm_clf\", SVC(kernel=\"rbf\", gamma=0.5, C=1000))\n",
" ])\n",
"\n",
"rbf_kernel_svm_clf.fit(X_train_reduced, y_train_num)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Representación del límite de decisión**"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA4sAAAFBCAYAAADe/zqYAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOzde3zcZZ33/9c1k0l6PkHouRR6gtaU0oZykloOpVJBWNl1VUTURUBR7M3qrave9/Lbe7kXFVkWRRARRami3rJAK6XU0lJEaElLmjQtPQRKm7ZJ06bnQzKZuX5/zMy3c55JMue8nzz6SOY7M9+5ZhLmk/dcJ2OtRURERERERCScK98NEBERERERkcKjsCgiIiIiIiIxFBZFREREREQkhsKiiIiIiIiIxFBYFBERERERkRgKiyIiIiIiIhIjb2HRGDPWGLPSGLPZGNNgjPl68Ph9xpjdxpja4L8FYff5F2PMdmPMFmPM/Hy1XUREREREpNSZfO2zaIwZCYy01q43xgwE1gE3AZ8EjllrH4y6/VTgd8BsYBTwF2CytdaX25aLiIiIiIiUvrz1LFpr91pr1we/PwpsBkYnucuNwLPW2nZr7fvAdgLBUURERERERDKsIOYsGmPGAxcCa4KHvmqMqTPGPGWMGRo8NhrYFXa3JpKHSxEREREREemmsnw3wBgzAPgTsNBae8QY8xjwfwAb/Poj4IuAiXP3mDG0xpg7gDsA+vbrM2v8ueOy1XQRESkgmzdu3W+trcx3OwqZaqSISO/Tk/qY17BojPEQCIqLrLXPAVhrW8Ku/zmwJHixCRgbdvcxwJ7oc1prnwCeAJhaNcU+88IT2Wm8iIgUlFkT5n6Q7zYUOtVIEZHepyf1MZ+roRrgF8Bma+1DYcdHht3s74CNwe9fBD5ljKkwxpwDTALW5qq9IiIiIiIivUk+exYvB24F6o0xtcFj3wE+bYyZQWCI6Q7gTgBrbYMx5g/AJqATuFsroYqIiIiIiGRH3sKitfavxJ+H+FKS+9wP3J+1RomIiIiIiAhQIKuhioiIiIiISGFRWBQREREREZEYCosiIiIiIiISQ2FRREREREREYigsioiIiIiISAyFRREREREREYmhsCgiIiIiIiIxFBZFREREREQkhsKiiIiIiIiIxFBYFBERERERkRgKiyIiIiIiIhJDYVFERLKirrWBp+oXUdfakO+miIiISDeU5bsBIiJSeupaG7jjlYV0+jspc5XxxLUPM71yWr6bJSIiIl2gnkUREcm4JY3L8Pq9WCxev5cljcvy3SQRERHpIoVFERERERERiaGwKCIiGXf9hPmUuzwYDOUuD9dPmJ/vJomIiEgXac6iiIhk3PTKafzs2oepaa6lesQMzVcUEREpQgqLIiKSFdMrpykkioiIFDENQxUREREREZEYCosiIiIiIiISQ2FRREREREREYigsioiIiIiISAyFRREREREREYmhsCgiIiIiIiIxFBZFREREREQkhsKiiIiIiIiIxFBYFBERERERkRgKiyIiIiIiIhJDYVFERERERERiKCyKiIiIiIhIjLyFRWPMWGPMSmPMZmNMgzHm68Hjw4wxy40x24JfhwaPG2PMI8aY7caYOmPMzHy1XUREREREpNTls2exE/hna+35wCXA3caYqcC3gRXW2knAiuBlgOuAScF/dwCP5b7JIiIiIiIivUPewqK1dq+1dn3w+6PAZmA0cCPwdPBmTwM3Bb+/Efi1DXgLGGKMGZnjZouIiIiIiPQKBTFn0RgzHrgQWAMMt9buhUCgBM4K3mw0sCvsbk3BYyIiIiIiIpJheQ+LxpgBwJ+AhdbaI8luGueYjXO+O4wxNcaYmoNthzPVTBERkaKnGikiIl2R17BojPEQCIqLrLXPBQ+3hIaXBr/uCx5vAsaG3X0MsCf6nNbaJ6y11dba6qHDBmev8SIiIkVGNVJERLoin6uhGuAXwGZr7UNhV70I3Bb8/jbghbDjnwuuinoJcDg0XFVEREREREQyqyyPj305cCtQb4ypDR77DvAA8AdjzD8BO4F/CF73ErAA2A6cAL6Q2+aKiIiIiIj0HnkLi9bavxJ/HiLA1XFub4G7s9ooERERERERAQpggRsREREREREpPAqLIiIiIiIiEkNhUURERERERGIoLIqIiIiIiEgMhUURERERERGJobAoIiIiIiIiMRQWRUREREREJIbCooiIiIiIiMRQWBQREREREZEYCosiIiIiIiISQ2FRREREREREYigsioiIiIiISAyFRREREREREYmhsCgiIiIiIiIxFBZFRApcXWsDT9Uvoq61Id9NERERkV6kLN8NEBGRxOpaG7hr+b14fV48bg+Pz3uI6ZXT8t0sERER6QXUsygiUsBqmmvx+rz48dPp91LTXJvvJomIiEgvobAoIlLAqkfMwOP24DYuylweqkfMyHeTREREpJfQMFQRkQI2vXIaj897iJrmWqpHzNAQVBEREckZhUURkQI3vXKaQqKIiIjknIahioiIiIiISAyFRREREREREYmhsCgiIiIiIiIxFBZFREREREQkhsKiiIiIiIiIxFBYFBERERERkRgKiyIiIiIiIhJDYVFERERERERiKCyKiIiIiIhIDIVFERERERERiZHXsGiMecoYs88YszHs2H3GmN3GmNrgvwVh1/2LMWa7MWaLMWZ+flotIiIiIiJS+vLds/gr4KNxjv+ntXZG8N9LAMaYqcCngGnB+/zUGOPOWUtFRERERER6kbyGRWvtaqAtzZvfCDxrrW231r4PbAdmZ61xIiIiIiIivVi+exYT+aoxpi44THVo8NhoYFfYbZqCx0RERERERCTDCjEsPgZMAGYAe4EfBY+bOLe10QeMMXcYY2qMMTUH2w5nr5UiIiJFRjVSRES6ouDCorW2xVrrs9b6gZ9zeqhpEzA27KZjgD1x7v+EtbbaWls9dNjg7DdYRESkSKhGiohIVxRcWDTGjAy7+HdAaKXUF4FPGWMqjDHnAJOAtblun4iIiIiISG9Qls8HN8b8DpgLnGmMaQL+FZhrjJlBYIjpDuBOAGttgzHmD8AmoBO421rry0e7RURERERESl1ew6K19tNxDv8iye3vB+7PXotEREREREQECnAYqoiIiIiIiOSfwqKIiIiIiIjEUFgUEZGcqmtt4Kn6RdS1NuS7KSIiIpJEXucsiohI71LX2sBdy+/F6/PicXt4fN5DTK+clu9miYiISBzqWRQRkZypaa7F6/Pix0+n30tNc22+myQiIiIJKCyKiEjOVI+YgcftwW1clLk8VI+Yke8miYiISAIahioiIjkzvXIaj897iJrmWqpHzNAQVBERkQKmsCgiIjk1vXKaQqKIiEgR0DBUERERERERiaGwKCIiIiIiIjEUFkVEipD2KhQREZFs05xFEZEio70KRUREJBfUsygivUap9MZpr0IRERHJBfUsikivUEq9caG9Cjv9Xu1VKCIiIlmjsCgivUK83rhiDYvaq1BERERyQWFRRHqFUuuN016FIiIikm0KiyLSK6g3TkRERKRr0gqLxpgpwPeACeH3sdbOzlK7REQy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\n",
"text/plain": [
"<Figure size 1080x360 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"fig, axes = plt.subplots(ncols=2, figsize=(15,5), sharey=True)\n",
"plt.sca(axes[0])\n",
"plot_dataset(X_train_reduced.values, y_train_num)\n",
"plot_predictions(rbf_kernel_svm_clf, [0, 1, -100, 250])\n",
"plt.xlabel(\"domainUrlRatio\", fontsize=11)\n",
"plt.ylabel(\"domainlength\", fontsize=11)\n",
"plt.sca(axes[1])\n",
"plot_predictions(rbf_kernel_svm_clf, [0, 1, -100, 250])\n",
"plt.xlabel(\"domainUrlRatio\", fontsize=11)\n",
"plt.ylabel(\"domainlength\", fontsize=11)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Predicción con un conjunto de datos reducido**"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [],
"source": [
"# Hacemos la predicción con el conjunto de datos de validación\n",
"y_pred = rbf_kernel_svm_clf.predict(X_val_reduced)"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"F1 Score: 0.8617363344051447\n"
]
}
],
"source": [
"# Mi algoritmo ha sido capaz de predecir correctamente en un 86.17% para mi conjunto de datos de validación\n",
"print(\"F1 Score:\", f1_score(y_pred, y_val_num))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Predicción con un conjunto de datos completo**"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Pipeline(memory=None,\n",
" steps=[('scaler',\n",
" RobustScaler(copy=True, quantile_range=(25.0, 75.0),\n",
" with_centering=True, with_scaling=True)),\n",
" ('svm_clf',\n",
" SVC(C=1000, break_ties=False, cache_size=200,\n",
" class_weight=None, coef0=0.0,\n",
" decision_function_shape='ovr', degree=3, gamma=0.05,\n",
" kernel='rbf', max_iter=-1, probability=False,\n",
" random_state=None, shrinking=True, tol=0.001,\n",
" verbose=False))],\n",
" verbose=False)"
]
},
"execution_count": 90,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rbf_kernel_svm_clf = Pipeline([\n",
" (\"scaler\", RobustScaler()),\n",
" (\"svm_clf\", SVC(kernel=\"rbf\", gamma=0.05, C=1000))\n",
" ])\n",
"\n",
"rbf_kernel_svm_clf.fit(X_train_prep, y_train_num)"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [],
"source": [
"# Hacemos la predicción con el conjunto de datos de validación\n",
"y_pred = rbf_kernel_svm_clf.predict(X_val_prep)"
]
},
{
"cell_type": "code",
"execution_count": 92,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"F1 Score: 0.9640522875816993\n"
]
}
],
"source": [
"# Mi algoritmo ha sido capaz de predecir correctamente en un 96.4% para mi conjunto de datos de validación\n",
"print(\"F1 Score:\", f1_score(y_pred, y_val_num))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
@fenix820077
Copy link

Excelente

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment