# librerias
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.model_selection import LeaveOneOut
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
Descripcion de datos https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.names
Enlace con datos https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.csv
El archivo "sonar.mines" contiene 111 patrones obtenidos al hacer rebotar señales de sonar en un cilindro de metal en varios ángulos y bajo diversas condiciones. El archivo "sonar.rocks" contiene 97 patrones obtenidos de rocas en condiciones similares. La señal del sonar transmitida es un chirrido de frecuencia modulada, aumentando en frecuencia. El conjunto de datos contiene señales obtenidas desde una variedad de ángulos de aspecto diferentes, que abarcan 90 grados para el cilindro y 180 grados para la roca.
Cada patrón es un conjunto de 60 números en el rango de 0,0 a 1,0. Cada número representa la energía dentro de una banda de frecuencia particular, integrada durante un cierto período de tiempo. La apertura de integración para frecuencias más altas ocurre más tarde, ya que estas frecuencias se transmiten más tarde durante el chirrido.
La etiqueta asociada a cada registro contiene la letra "R" si el objeto es una roca y "M" si es una mina (cilindro de metal). Los números en las etiquetas están en orden creciente de ángulo de aspecto, pero no codifican el ángulo directamente.
# datos
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.csv'
dataframe = read_csv(url, header=None)
data = dataframe.values
dataframe.head()
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.0200 | 0.0371 | 0.0428 | 0.0207 | 0.0954 | 0.0986 | 0.1539 | 0.1601 | 0.3109 | 0.2111 | ... | 0.0027 | 0.0065 | 0.0159 | 0.0072 | 0.0167 | 0.0180 | 0.0084 | 0.0090 | 0.0032 | R |
1 | 0.0453 | 0.0523 | 0.0843 | 0.0689 | 0.1183 | 0.2583 | 0.2156 | 0.3481 | 0.3337 | 0.2872 | ... | 0.0084 | 0.0089 | 0.0048 | 0.0094 | 0.0191 | 0.0140 | 0.0049 | 0.0052 | 0.0044 | R |
2 | 0.0262 | 0.0582 | 0.1099 | 0.1083 | 0.0974 | 0.2280 | 0.2431 | 0.3771 | 0.5598 | 0.6194 | ... | 0.0232 | 0.0166 | 0.0095 | 0.0180 | 0.0244 | 0.0316 | 0.0164 | 0.0095 | 0.0078 | R |
3 | 0.0100 | 0.0171 | 0.0623 | 0.0205 | 0.0205 | 0.0368 | 0.1098 | 0.1276 | 0.0598 | 0.1264 | ... | 0.0121 | 0.0036 | 0.0150 | 0.0085 | 0.0073 | 0.0050 | 0.0044 | 0.0040 | 0.0117 | R |
4 | 0.0762 | 0.0666 | 0.0481 | 0.0394 | 0.0590 | 0.0649 | 0.1209 | 0.2467 | 0.3564 | 0.4459 | ... | 0.0031 | 0.0054 | 0.0105 | 0.0110 | 0.0015 | 0.0072 | 0.0048 | 0.0107 | 0.0094 | R |
5 rows × 61 columns
dataframe.shape
(208, 61)
dataframe.isnull().sum()
0 0 1 0 2 0 3 0 4 0 .. 56 0 57 0 58 0 59 0 60 0 Length: 61, dtype: int64
sum(dataframe.isna().sum())
# no hay nulos
0
# Separar en X y y
X, y = data[:, :-1], data[:, -1]
print(X.shape, y.shape)
(208, 60) (208,)
# crear el procedimiento loocv
skf = StratifiedKFold(n_splits=5, random_state=42, shuffle=True)
skf.get_n_splits(X, y)
5
train, test = list(skf.split(X, y))[0]
train
array([ 0, 1, 2, 4, 5, 6, 7, 10, 11, 12, 13, 14, 16, 18, 19, 20, 21, 22, 24, 25, 27, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40, 42, 43, 45, 46, 47, 49, 52, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 83, 84, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 99, 100, 101, 102, 103, 105, 106, 107, 109, 110, 111, 112, 114, 115, 116, 117, 118, 119, 120, 121, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 146, 148, 149, 150, 151, 153, 154, 155, 156, 158, 160, 161, 162, 164, 165, 166, 167, 168, 170, 171, 172, 173, 175, 177, 179, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 196, 197, 199, 200, 201, 203, 204, 205, 207])
test
array([ 3, 8, 9, 15, 17, 23, 26, 28, 34, 38, 41, 44, 48, 50, 51, 53, 55, 82, 85, 94, 97, 98, 104, 108, 113, 122, 145, 147, 152, 157, 159, 163, 169, 174, 176, 178, 180, 181, 195, 198, 202, 206])
X[test]
(42, 60)
from sklearn.metrics import accuracy_score
# Modelo vacio
model = RandomForestClassifier(random_state=1,n_estimators=30, criterion="gini",max_depth=4)
# Lista para guardar accuracy
list_ac=[]
for i in range(0,skf.get_n_splits(X, y)):
# Calculo de indices
train, test = list(skf.split(X, y))[i]
# Separar train y test
X_train_n, y_train_n, X_test_n, y_test_n= X[train], y[train], X[test],y[test]
# Ajustar el modelo
model.fit(X_train_n, y_train_n)
# Predicciones
pred= model.predict(X_test_n)
# Calculo del error
accuracy= accuracy_score(y_true=y_test_n, y_pred= pred)
print('Iteracion: ',i+1, ' Accuracy:', accuracy)
list_ac.append(accuracy)
# Promedio de accuracy
import numpy as np
print('Accuracy promedio:', np.mean(list_ac))
Iteracion: 1 Accuracy: 0.7619047619047619 Iteracion: 2 Accuracy: 0.8095238095238095 Iteracion: 3 Accuracy: 0.8095238095238095 Iteracion: 4 Accuracy: 0.8292682926829268 Iteracion: 5 Accuracy: 0.8048780487804879 Accuracy promedio: 0.8030197444831592