Cual es la mejor estrategia para adivinar?

Por Miguel Escalona


In [ ]:
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
matplotlib.rcParams['figure.figsize'] = (15.0, 6.0)
import numpy as np
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning) 
from IPython.display import Image

¡Adivina Quién es!

El juego de adivina quién es, consiste en adivinar el personaje que tu oponente ha seleccionado antes de que él/ella adivine el tuyo. La dinámica del juego es:

  • Cada jugador elige un personaje al azar
  • Por turnos, cada jugador realiza preguntas de sí o no, e intenta adivinar el personaje del oponente.
  • Las preguntas válidas están basadas en la apariencia de los personajes y deberían ser fáciles de responder.
  • Ejemplo de pregunta válida: ¿Tiene el cabello negro?
  • Ejemplo de pregunta no válida: ¿Luce como un ex-presidiario?

A continuación, cargamos el tablero con los personajes.


In [ ]:
Image('data/guess_who_board.jpg', width=700)

1. Cargando los datos

Para la carga de datos usaremos la función read_csv de pandas. Pandas cuenta con un amplio listado de funciones para la carga de datos. Mas informacion en la documentación de la API.


In [ ]:
# Carga el modulo pandas

In [ ]:
# Escribe aqui tu codigo para cargar los datos (utiliza read_csv), llama a los datos df

df = 
df.head()

2. ¿Cuántos personajes tenemos con cada característica?


In [ ]:
#Separamos los tipos de variables
categorical_var = 'color de cabello'
binary_vars = list(set(df.keys()) - set([categorical_var, 'NOMBRE']))

In [ ]:
#  *** Escribe tu codigo aquí ***
# Para las variables booleanas calculamos la suma

In [ ]:
#  *** Escribe tu codigo aquí ***
# Para las variables categoricas, observamos la frecuencia de cada categoría

Pregunta, ¿cuántas personas tienen la boca grande?


In [ ]:
#  *** Escribe tu codigo aquí ***

y cuántos de estos son hombres?


In [ ]:
#  *** Escribe tu codigo aquí ***

3. Separamos el target de los features


In [ ]:
labels = df['NOMBRE']
del df['NOMBRE'] 
df.head()

In [ ]:
# inspección del target

4. Codificación de variables categóricas


In [ ]:
from sklearn.feature_extraction import DictVectorizer
vectorizer = DictVectorizer(sparse=False)
ab=vectorizer.fit_transform(df.to_dict('records'))
dft = pd.DataFrame(ab, columns=vectorizer.get_feature_names())
dft.head().T

5. Entrenando un arbol de decisión


In [ ]:
from sklearn.tree import DecisionTreeClassifier

clasificador = DecisionTreeClassifier(criterion='entropy', random_state=42)
clasificador.fit(dft, labels)

5.1 Obtención de los pesos de cada feature


In [ ]:
feat = pd.DataFrame(index=dft.keys(), data=clasificador.feature_importances_, columns=['score'])
feat = feat.sort_values(by='score', ascending=False)

In [ ]:
# grafica feat, para ver las variables mas relevantes

6. Visualizando el arbol (requiere graphviz)

Si no lo tienes instalado, puedes ejecutar

conda install graphviz

en una terminal


In [ ]:
from sklearn.tree import export_graphviz
dotfile = open('quien_es_quien_tree.dot', 'w')
export_graphviz(
    clasificador, 
    out_file = dotfile, 
    filled=True, 
    feature_names = dft.columns, 
    class_names=list(labels), 
    rotate=True, 
    max_depth=None, 
    rounded=True,
)
dotfile.close()
!dot -Tpng quien_es_quien_tree.dot -o quien_es_quien_tree.png
Image('quien_es_quien_tree.png', width=1000)

7. Es la hora de jugar!


In [ ]:
# Elige un personaje por su numero de observacion
observacion_numero = 17
mi_personaje = dft.iloc[observacion_numero]
mi_personaje

In [ ]:
personaje = clasificador.predict(mi_personaje)[0]
print('El personaje elegido es: ' + personaje + ' y en realidad es: ' + labels[observacion_numero+1])

8. Esto se pone mejor!!!

probemos otro clasificador del sklearn


In [ ]:
from sklearn.ensemble import RandomForestClassifier
rfc = RandomForestClassifier(criterion='entropy', random_state=42)
rfc.fit(dft, labels)

Ahora creamos un nuevo personaje, con las caracteristicas que queramos...


In [ ]:
new_per = np.zeros(len(dft.keys()))
nuevo_personaje = pd.DataFrame(index=dft.keys(), data=new_per, columns=['features']).T
nuevo_personaje.T

In [ ]:
def modifica_feature_de_personaje(data, feature, nuevo_valor=1.0):
    data[feature] = nuevo_valor
    return data

In [ ]:
Image('data/guess_who_board.jpg', width=700)

podemos modificar los features de nuestro personaje, llamando a la funcion modifica_feature_de_personaje


In [ ]:
nuevo_personaje = modifica_feature_de_personaje(nuevo_personaje, 'bigote', 1.0)
nuevo_personaje.T

Comparemos que dice cada clasificador


In [ ]:
print('El arbol de decision dice que es: ' + clasificador.predict(nuevo_personaje)[0])

In [ ]:
print('El random forest cree que es: ' + rfc.predict(nuevo_personaje)[0])

Veamos las probailidades del random forest


In [ ]:
ind = range(24)
plt.bar(ind,rfc.predict_proba(nuevo_personaje)[0])
plt.xticks(ind, labels.values, rotation='vertical')
plt.show()

Fin del notebook!