<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Caso de estudio - Supervivencia en el Titanic
Extracción de características
Ahora trataremos parte muy importante del aprendizaje automático
Step1:  Las características son
Step2:  Características derivadas
Otro tipo bastante común de características son las características derivadas, que son características obtenidas a partir de algún paso previo de preprocesamiento y que se supone que son más informativas que las originales. Este tipo de características pueden estar basadas en extracción de características y en reducción de la dimensionalidad (tales como PCA o aprendizaje de variedades) y pueden ser combinaciones lineales o no lineales de las características originales (como en regresión polinómica) o transformaciones más sofisticadas de las características.
Combinando características numéricas y categóricas
Como un ejemplo de la forma en que se trabaja con datos numéricos y categóricos, vamos a realizar un ejercicio en el que predeciremos la supervivencia de los pasajeros del HMS Titanic.
Utilizaremos una versión del dataset Titatic que puede descargarse de titanic3.xls. Previamente, ya hemos convertido el .xls a .csv para que sea más fácil su manipulación (como texto), de manera que los datos no fueron modificados.
Necesitamos leer todas las líneas del fichero titanic3.csv, ignorar la cabecera y encontrar las etiquetas (sobrevivió o murió) y los datos de entrada (características de la persona). Vamos a ver la cabecera y algunas líneas de ejemplo
Step3:  Aquí tenemos una descripción de lo que significan cada una de las variables
Step4:  Podemos descartar directamente las columnas "boat" y "body" ya que está directamente relacionadas con que el pasajero sobreviviese. El nombre es (probablemente) único para cada persona y por tanto no es informativo. Vamos a intentar en primer lugar usar "pclass", "sibsp", "parch", "fare" y "embarked" como características
Step5:  En principio, los datos ahora solo contienen características útiles, pero no están en un formato que los algoritmos de aprendizaje automático puedan entender. Necesitamos transformar las cadenas "male" y "female" en variables binarias que indiquen el género y lo mismo para embarked.Podemos hacer esto usando la función get_dummies de pandas
Step6:  Esta transformación ha codificado bien las columnas de cadenas. Sin embargo, parece que la variable pclass también es una variable categórica. Podemos listar de forma explícita las variables que queremos codificar utilizando el parámetro columns para incluir pclass
Step7:  Una vez hemos hecho el trabajo de duro de cargar los datos, evaluar un clasificador con estos datos es directo. Vamos a ver que rendimiento obtenemos con el clasificador más simple, DummyClassifier('most_frequent'), que es equivalente al ZeroR.
<ASSISTANT_TASK:>
Python Code:
from sklearn.datasets import load_iris
iris = load_iris()
print(iris.data.shape)
Explanation: Caso de estudio - Supervivencia en el Titanic
Extracción de características
Ahora trataremos parte muy importante del aprendizaje automático: la extracción de características cuantitativas a partir de los datos. Con este fin:
- Aprenderemos como las características pueden extraerse a partir de datos del mundo real.
- Veremos como extraer características numéricas a partir de datos textuales.
Además, repasaremos algunas herramientas básicas en scikit-learn que pueden utilizarse para realizar estas tareas.
¿Qué son características?
Características numéricas
Recuerda que los datos en scikit-learn vienen en arrays de dos dimensiones con tamaño n_samples $\times$ n_features.
Anteriormente, vimos el dataset iris, que tienen 150 ejemplos y 4 características.
End of explanation
measurements = [
    {'city': 'Dubai', 'temperature': 33.},
    {'city': 'London', 'temperature': 12.},
    {'city': 'San Francisco', 'temperature': 18.}
]
from sklearn.feature_extraction import DictVectorizer
vec = DictVectorizer()
vec
vec.fit_transform(measurements).toarray()
vec.get_feature_names()
Explanation: Las características son:
- Longitud de sépalo en cm
- Ancho de sépalo en cm
- Longitud de pétalo en cm
- Ancho de pétalo en cm
Las características numéricas como estas son directas: cada ejemplo contiene una lista de números con precisión real que se corresponden con las características.
Características categóricas
¿Qué pasa si tenemos características categóricas?. Por ejemplo, imagina que disponemos del color de cada flor de iris: $color \in {red, blue, purple}$
Podrías estar tentado de usar algo así como i.e. red=1, blue=2, purple=3, pero, en general, esto es una mala idea. Los estimadores tienden a trabajar con la suposición de que las características numéricas se sitúan en una escala continua por lo que, en este ejemplo, 1 y 2 serían más parecidos que 1 y 3 y esto no tiene porque ser generalmente verdad.
De hecho, el ejemplo anterior es una subcategoría de las variables categóricas, en concreto, una variable nominal. Las variables nominales no tienen asociado un orden, mientras que las variables ordinales si que implican un orden. Por ejemplo, las tallas de las camisetas formarían una variable ordinal "XL > L > M > S". 
Una forma de transformar variables nominales en un formato que prevenga al estimador de asumir un orden es la llamada representación $1$-$de$-$J$ (one-hot encoding). Cada categoría genera su propia variable por separado.
El conjunto de características aumentado sería:
- Longitud de sépalo en cm
- Ancho de sépalo en cm
- Longitud de pétalo en cm
- Ancho de pétalo en cm
- color=purple (1.0 o 0.0)
- color=blue (1.0 o 0.0)
- color=red (1.0 o 0.0)
Observa que al usar este conjunto de características puede que los datos se representen mejor usando matrices dispersas, como veremos en el ejemplo de clasificación de texto que analizaremos después.
Utilizando DictVectorizer para codificar variables categóricas
Cuando los datos de entrada están codificados con un diccionario de tal forma que los valores son o cadenas o valores numéricos, se puede usar la clase DictVectorizer para obtener la expansión booleana sin tocar las características numéricas:
End of explanation
import os
import pandas as pd
titanic = pd.read_csv(os.path.join('datasets', 'titanic3.csv'))
print(titanic.columns)
Explanation: Características derivadas
Otro tipo bastante común de características son las características derivadas, que son características obtenidas a partir de algún paso previo de preprocesamiento y que se supone que son más informativas que las originales. Este tipo de características pueden estar basadas en extracción de características y en reducción de la dimensionalidad (tales como PCA o aprendizaje de variedades) y pueden ser combinaciones lineales o no lineales de las características originales (como en regresión polinómica) o transformaciones más sofisticadas de las características.
Combinando características numéricas y categóricas
Como un ejemplo de la forma en que se trabaja con datos numéricos y categóricos, vamos a realizar un ejercicio en el que predeciremos la supervivencia de los pasajeros del HMS Titanic.
Utilizaremos una versión del dataset Titatic que puede descargarse de titanic3.xls. Previamente, ya hemos convertido el .xls a .csv para que sea más fácil su manipulación (como texto), de manera que los datos no fueron modificados.
Necesitamos leer todas las líneas del fichero titanic3.csv, ignorar la cabecera y encontrar las etiquetas (sobrevivió o murió) y los datos de entrada (características de la persona). Vamos a ver la cabecera y algunas líneas de ejemplo:
End of explanation
titanic.head()
Explanation: Aquí tenemos una descripción de lo que significan cada una de las variables:
pclass          Passenger Class
                (1 = 1st; 2 = 2nd; 3 = 3rd)
survival        Survival
                (0 = No; 1 = Yes)
name            Name
sex             Sex
age             Age
sibsp           Number of Siblings/Spouses Aboard
parch           Number of Parents/Children Aboard
ticket          Ticket Number
fare            Passenger Fare
cabin           Cabin
embarked        Port of Embarkation
                (C = Cherbourg; Q = Queenstown; S = Southampton)
boat            Lifeboat
body            Body Identification Number
home.dest       Home/Destination
Parece que las variables name, sex, cabin, embarked, boat, body y homedest son candidatas a ser variables categóricas, mientras que el resto parecen variables numéricas. Vamos a ver las primeras filas para tener un mejor conocimiento de la base de datos:
End of explanation
labels = titanic.survived.values
features = titanic[['pclass', 'sex', 'age', 'sibsp', 'parch', 'fare', 'embarked']]
features.head()
Explanation: Podemos descartar directamente las columnas "boat" y "body" ya que está directamente relacionadas con que el pasajero sobreviviese. El nombre es (probablemente) único para cada persona y por tanto no es informativo. Vamos a intentar en primer lugar usar "pclass", "sibsp", "parch", "fare" y "embarked" como características:
End of explanation
pd.get_dummies(features).head()
Explanation: En principio, los datos ahora solo contienen características útiles, pero no están en un formato que los algoritmos de aprendizaje automático puedan entender. Necesitamos transformar las cadenas "male" y "female" en variables binarias que indiquen el género y lo mismo para embarked.Podemos hacer esto usando la función get_dummies de pandas:
End of explanation
features_dummies = pd.get_dummies(features, columns=['pclass', 'sex', 'embarked'])
features_dummies.head(n=16)
#También podríamos hacerlo con DictVectorizer
from sklearn.feature_extraction import DictVectorizer
diccionario = features.to_dict('records')
vec = DictVectorizer()
dataset = vec.fit_transform(diccionario)
print(dataset.todense())
data = features_dummies.values
# Comprobamos que hay valores perdidos, tendremos que aplicar un Imputer
import numpy as np
np.isnan(data).any()
Explanation: Esta transformación ha codificado bien las columnas de cadenas. Sin embargo, parece que la variable pclass también es una variable categórica. Podemos listar de forma explícita las variables que queremos codificar utilizando el parámetro columns para incluir pclass:
End of explanation
from sklearn.model_selection import train_test_split
from sklearn.impute import SimpleImputer
train_data, test_data, train_labels, test_labels = train_test_split(
    data, labels, random_state=0)
imp = SimpleImputer()
imp.fit(train_data)
train_data_finite = imp.transform(train_data)
test_data_finite = imp.transform(test_data)
np.isnan(train_data_finite).any()
from sklearn.dummy import DummyClassifier
clf = DummyClassifier(strategy='most_frequent')
clf.fit(train_data_finite, train_labels)
print("Accuracy: %f"
      % clf.score(test_data_finite, test_labels))
Explanation: Una vez hemos hecho el trabajo de duro de cargar los datos, evaluar un clasificador con estos datos es directo. Vamos a ver que rendimiento obtenemos con el clasificador más simple, DummyClassifier('most_frequent'), que es equivalente al ZeroR.
End of explanation
<END_TASK>