# Importaciones necesarias
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
# Cargamos los datos
banknotes = pd.read_csv('https://cursopypagina.github.io/CursoPy/banknotes.csv')
# Exporamos la informacion sobre nuestros datos
banknotes.head()
variace | skewness | curtosis | entropy | class | |
---|---|---|---|---|---|
0 | 3.62160 | 8.6661 | -2.8073 | -0.44699 | 0 |
1 | 4.54590 | 8.1674 | -2.4586 | -1.46210 | 0 |
2 | 3.86600 | -2.6383 | 1.9242 | 0.10645 | 0 |
3 | 3.45660 | 9.5228 | -4.0112 | -3.59440 | 0 |
4 | 0.32924 | -4.4552 | 4.5718 | -0.98880 | 0 |
banknotes.shape
(1372, 5)
banknotes
es una base de datos sobre la autentificación de billetes de dólares mediante 4 características, las cuales fueron calculadas realizando operaciones matemáticas sobre imágenes de los billetes de dólares. La clasificación de si el billete es verdadero o no está en la columna class
que solo tiene ceros y unos
Indaguemos graficamente sobre nuestros datos
sns.pairplot(banknotes, hue='class')
plt.show()
banknotes['class'].value_counts()
0 762 1 610 Name: class, dtype: int64
de donde hay características para las que las clases se extienden notablemente, esto nos da una intuición de que nuestras clases son fácilmente separables.
Ahora bien, dado que tenemos 4 características, entonces nuestra capa de entrada tendrá 4 neuronas, no tendremos capas ocultas y la capa de salida tendrá sólo una neurona en la cual implementaremos la función de activación sigmoide, donde para valores $<0.5$ asignaremos la etiqueta 0 y para valores $\geq5$ le asignaremos la etiqueta 1. Dichos valores lo interpretaremos como probabilidades, donde 1 nos dirá que el billete es falso.
Procedemos a crear nuestro modelo
# Realizamos las importaciones necesarias
from keras.models import Sequential
from keras.layers import Dense
import numpy as np
# Fijamos una semilla
np.random.seed(123)
# Instanciamos el modelo
model = Sequential()
# Capa de entrada de 4 neuronas y capa de salida de una neurona
model.add(Dense(1, input_shape=(4,), activation='sigmoid'))
# Copilacion del modelo.
# El optimizador sera: descenso del gradiente estocastico
model.compile(optimizer='sgd', loss='binary_crossentropy', metrics=['accuracy'])
# Vemos un resumen sobre nuestro modelo
model.summary()
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense (Dense) (None, 1) 5 ================================================================= Total params: 5 Trainable params: 5 Non-trainable params: 0 _________________________________________________________________
Convertimos nuestros datos a un NumPy array:
banknotes = np.array(banknotes)
Realizamos la división de los datos
from sklearn.model_selection import train_test_split
# Puntos
X = banknotes[:, 0:4]
# Etiquetas
y = banknotes[:, 4]
# Division de los datos
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
train_size = 0.25,
random_state = 123)
después, ajustamos el modelo y vemos la evaluación del mismo
# Ajustamos el modelo
model.fit(X_train, y_train, epochs=20, verbose=0)
# Evaluacion del modelo
scores = model.evaluate(X_train, y_train)
print('%s: %.4f%%' % (model.metrics_names[1], scores[1] * 100))
11/11 [==============================] - 0s 1ms/step - loss: 0.2066 - accuracy: 0.9446 accuracy: 94.4606%
Procedemos a realizar la predicción y comparamos dichas predicciones con los valores reales
# Realizamos las predicciones
predicciones = model.predict(X_test).round()
# Creamos un dataframe vacio
dict1 = {'Predicción': [0 for i in range(X_test.shape[0])],
'Valor real': [0 for i in range(X_test.shape[0])]}
df = pd.DataFrame(dict1)
# Llenamos el dataframe
for i in range(X_test.shape[0]):
df.iloc[i][0] = predicciones[i][0]
df.iloc[i][1] = y_test[i]
# Comparamos
df
33/33 [==============================] - 0s 968us/step
Predicción | Valor real | |
---|---|---|
0 | 0 | 0 |
1 | 0 | 0 |
2 | 0 | 0 |
3 | 0 | 0 |
4 | 1 | 1 |
... | ... | ... |
1024 | 0 | 0 |
1025 | 1 | 1 |
1026 | 0 | 0 |
1027 | 1 | 1 |
1028 | 0 | 0 |
1029 rows × 2 columns
count = 0
for i in range(1029):
if df.iloc[i][0] != df.iloc[i][1]:
count += 1
count
52
nuestro modelo se equivocó 61 veces.
Veamos algunos gráficos:
# Datos de prueba:
plt.figure(figsize=(4,4))
import matplotlib.pyplot as plt
# Graficamos
for i in range(X_test.shape[0]):
plt.plot(X_test[i][0], X_test[i][1], marker="o", color="#02FFEF")
plt.title('Varianza vs Asimetría')
plt.show()
Veamos el mismo gráfico con la separación hecha por nuestra red neuronal
plt.figure(figsize=(4,4))
# Graficamos
for i in range(X_test.shape[0]):
# si la etiqueta es 1 (billetes falsos), el color es morado
if predicciones[i][0] == 1:
plt.plot(X_test[i][0], X_test[i][1], marker="o", color="#9D02FF")
# si la etiqueta es 0 (billetes verdaderos), el color es maguenta
else:
plt.plot(X_test[i][0], X_test[i][1], marker="o", color="#FF02A3")
plt.title('Varianza vs Asimetría')
plt.show()
Veamos ahora el gráfico original
banknotes = pd.read_csv('https://cursopypagina.github.io/CursoPy/banknotes.csv')
banknotes.columns
Index(['variace', 'skewness', 'curtosis', 'entropy', 'class'], dtype='object')
plt.figure(figsize=(4,4))
sns.scatterplot(data=banknotes, x="variace", y="skewness", hue='class')
plt.show()