Inicio de la diabetes en los indígenas Pima¶

Información sobre las columnas del dataset¶

  • Número de embarazos
  • Concentración de glucosa
  • Presión arterial
  • Grosor del pliegue de la piel del tríceps
  • Insulina sérica
  • Índice de masa corporal
  • Función del pedigrí de diabetes
  • Edad
  • Clase, aparición de diabetes en un plazo de 5 años

Comenzamos realizando las importaciones necesarias

In [1]:
from keras.models import Sequential
from keras.layers import Dense
import numpy as np
np.random.seed(123)

Cargaremos los datos, donde las columnas de la 0 a la 7 serán las características y la columna 8 será el objetivo.

In [2]:
# Cargamos los datos
db = np.loadtxt('https://cursopypagina.github.io/CursoPy/pima-indians-diabetes.csv', delimiter=',')

# Definimos las variables 
X = db[:, 0:8]
y = db[:, 8] 

Procedemos a definir el modelo de la red neuronal.

In [19]:
model = Sequential()
# Capa de entrada y primera capa oculta 1
model.add(Dense(64, activation='relu', input_shape=(8,)))
# Capa oculta 2
model.add(Dense(32, activation='relu'))
# Capa oculta 3
model.add(Dense(8, activation='relu'))
# Capa de salida
model.add(Dense(1, activation='sigmoid'))

Dado que es un problema de clasificación utilizaremos la función de pérdida logarítmica la cual definimos en keras mediante binary_crossentropy.

In [20]:
# Copilacion del modelo
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

# Ajustamos el modelo
# batch_size: numero de instancias que se evaluan
# antes de que se realice una actualizacion en los
# pesos
model.fit(X,y, epochs=500, verbose=0)
Out[20]:
<keras.callbacks.History at 0x2c8acd03b50>

Evaluamos nuestro modelo

In [21]:
scores = model.evaluate(X, y)
print('%s: %.4f%%' % (model.metrics_names[1], scores[1] * 100))
24/24 [==============================] - 0s 999us/step - loss: 0.2212 - accuracy: 0.9193
accuracy: 91.9271%

Finalizamos realizando predicciones

In [22]:
predicciones = model.predict(X).round()
24/24 [==============================] - 0s 880us/step

donde 0 hace alusión a que el usuario no tiene diabetes y 1 si el usuario tiene diabetes.


Modelo dividiendo los datos¶

In [35]:
%%time
from sklearn.model_selection import train_test_split

# División de los datos
X_train, X_test, y_train, y_test = train_test_split(
                                        X,
                                        y,
                                        train_size   = 0.25,
                                        random_state = 123)
# Definicion del modelo
model2 = Sequential()
# Capa de entrada y primera capa oculta 1
model2.add(Dense(64, activation='relu', input_shape=(8,)))
# Capa oculta 2
model2.add(Dense(32, activation='relu'))
# Capa oculta 3
model2.add(Dense(8, activation='relu'))
# Capa de salida
model2.add(Dense(1, activation='sigmoid'))
# Copilacion del modelo
model2.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

# Ajustamos el modelo con los datos de 
# entrenamiento
model2.fit(X_train,y_train, epochs=5000, verbose=0)
CPU times: total: 54.2 s
Wall time: 34.5 s
Out[35]:
<keras.callbacks.History at 0x2c8b3707fa0>

Vemos la evaluación de nuestro modelo

In [36]:
scores = model2.evaluate(X_test, y_test)
print('%s: %.4f%%' % (model2.metrics_names[1], scores[1] * 100))
18/18 [==============================] - 0s 1ms/step - loss: 3.3432 - accuracy: 0.6753
accuracy: 67.5347%

Hacemos predicciones con los datos de testeo

In [81]:
predicciones = model2.predict(X_test).round()
predicciones.shape
18/18 [==============================] - 0s 921us/step
Out[81]:
(576, 1)

Después crearemos un dataframe para comparar las predicciones hechas con los datos de X_test y los valores reales en y_test

In [52]:
y_test.shape
Out[52]:
(576,)
In [82]:
import pandas as pd
# Creamos un dataframe vacio
dict1 = {'Predicción': [0 for i in range(576)], 'Valor real': [0 for i in range(576)]}
df = pd.DataFrame(dict1)
df
Out[82]:
Predicción Valor real
0 0 0
1 0 0
2 0 0
3 0 0
4 0 0
... ... ...
571 0 0
572 0 0
573 0 0
574 0 0
575 0 0

576 rows × 2 columns

In [83]:
# Llenamos el dataframe
for i in range(575):
    df.iloc[i][0] = predicciones[i][0]
    df.iloc[i][1] = y_test[i]
# Comparamos
df
Out[83]:
Predicción Valor real
0 1 1
1 0 0
2 1 0
3 0 0
4 0 0
... ... ...
571 0 1
572 0 0
573 1 1
574 0 0
575 0 0

576 rows × 2 columns

In [69]:
df['Predicción'][6]
Out[69]:
1

lo cual, en teoría, nuestro modelo acertará más del 70% de las veces, pero eso sólo en el caso de los datos de entrenamiento.

In [84]:
# Vemos que, en realidad, nuestro modelo no es tan bueno
print(df['Predicción'].sum())
print(df['Valor real'].sum())
181
202