Los datos estructurados son aquellos datos que están bien organizados bajo criterios específicos, a los cuales es fácil de acceder, así como son sencillos de procesor. Algunos tipos de datos estructurados típicos son:
El manejo de datos estructurados es sencillo pues su misma natrualeza permite que se pueda acceder a ellos de manera simple. En python, una librería de gran utilidad para manejar datos estructurados es Pandas.
Pandas permite exportar datos desde una hoja de cálculo en formato csv como:
pd.read_csv(file_name)
De forma similar, también permite leer datos en formato de hoja de cálculo de Excel:
pd.read_excel(file_name)
import pandas as pd
import matplotlib.pyplot as plt
#Carga el archivo csv
dataset = pd.read_csv('dataset.csv', index_col=0)
dataset
mean radius | mean texture | mean perimeter | mean area | mean smoothness | mean compactness | mean concavity | mean concave points | mean symmetry | mean fractal dimension | ... | worst texture | worst perimeter | worst area | worst smoothness | worst compactness | worst concavity | worst concave points | worst symmetry | worst fractal dimension | Y | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 17.99 | 10.38 | 122.80 | 1001.0 | 0.11840 | 0.27760 | 0.30010 | 0.14710 | 0.2419 | 0.07871 | ... | 17.33 | 184.60 | 2019.0 | 0.16220 | 0.66560 | 0.7119 | 0.2654 | 0.4601 | 0.11890 | 0 |
1 | 20.57 | 17.77 | 132.90 | 1326.0 | 0.08474 | 0.07864 | 0.08690 | 0.07017 | 0.1812 | 0.05667 | ... | 23.41 | 158.80 | 1956.0 | 0.12380 | 0.18660 | 0.2416 | 0.1860 | 0.2750 | 0.08902 | 0 |
2 | 19.69 | 21.25 | 130.00 | 1203.0 | 0.10960 | 0.15990 | 0.19740 | 0.12790 | 0.2069 | 0.05999 | ... | 25.53 | 152.50 | 1709.0 | 0.14440 | 0.42450 | 0.4504 | 0.2430 | 0.3613 | 0.08758 | 0 |
3 | 11.42 | 20.38 | 77.58 | 386.1 | 0.14250 | 0.28390 | 0.24140 | 0.10520 | 0.2597 | 0.09744 | ... | 26.50 | 98.87 | 567.7 | 0.20980 | 0.86630 | 0.6869 | 0.2575 | 0.6638 | 0.17300 | 0 |
4 | 20.29 | 14.34 | 135.10 | 1297.0 | 0.10030 | 0.13280 | 0.19800 | 0.10430 | 0.1809 | 0.05883 | ... | 16.67 | 152.20 | 1575.0 | 0.13740 | 0.20500 | 0.4000 | 0.1625 | 0.2364 | 0.07678 | 0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
564 | 21.56 | 22.39 | 142.00 | 1479.0 | 0.11100 | 0.11590 | 0.24390 | 0.13890 | 0.1726 | 0.05623 | ... | 26.40 | 166.10 | 2027.0 | 0.14100 | 0.21130 | 0.4107 | 0.2216 | 0.2060 | 0.07115 | 0 |
565 | 20.13 | 28.25 | 131.20 | 1261.0 | 0.09780 | 0.10340 | 0.14400 | 0.09791 | 0.1752 | 0.05533 | ... | 38.25 | 155.00 | 1731.0 | 0.11660 | 0.19220 | 0.3215 | 0.1628 | 0.2572 | 0.06637 | 0 |
566 | 16.60 | 28.08 | 108.30 | 858.1 | 0.08455 | 0.10230 | 0.09251 | 0.05302 | 0.1590 | 0.05648 | ... | 34.12 | 126.70 | 1124.0 | 0.11390 | 0.30940 | 0.3403 | 0.1418 | 0.2218 | 0.07820 | 0 |
567 | 20.60 | 29.33 | 140.10 | 1265.0 | 0.11780 | 0.27700 | 0.35140 | 0.15200 | 0.2397 | 0.07016 | ... | 39.42 | 184.60 | 1821.0 | 0.16500 | 0.86810 | 0.9387 | 0.2650 | 0.4087 | 0.12400 | 0 |
568 | 7.76 | 24.54 | 47.92 | 181.0 | 0.05263 | 0.04362 | 0.00000 | 0.00000 | 0.1587 | 0.05884 | ... | 30.37 | 59.16 | 268.6 | 0.08996 | 0.06444 | 0.0000 | 0.0000 | 0.2871 | 0.07039 | 1 |
569 rows × 31 columns
Pandas también puede manejar datos que vengan de una base de datos SQL. Se pueden generar bases de datos por medio de to_sql también permite hacer consultas de la base de datos con read_sql.
from sqlite3 import connect
#Crea una base de datos
conn = connect(':memory:')
dataset.to_sql('dataset_db', conn)
#Realiza consulta
pd.read_sql('SELECT Y FROM dataset_db', conn)
Y | |
---|---|
0 | 0 |
1 | 0 |
2 | 0 |
3 | 0 |
4 | 0 |
... | ... |
564 | 0 |
565 | 0 |
566 | 0 |
567 | 0 |
568 | 1 |
569 rows × 1 columns
Es importante describir estadísticamente los datos. Para esto, Pandas permite realizar la descripción de datos, proporcinando estadísticas descriptivas básicas.
#Estadísticas del dataset
dataset.describe()
mean radius | mean texture | mean perimeter | mean area | mean smoothness | mean compactness | mean concavity | mean concave points | mean symmetry | mean fractal dimension | ... | worst texture | worst perimeter | worst area | worst smoothness | worst compactness | worst concavity | worst concave points | worst symmetry | worst fractal dimension | Y | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | ... | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 |
mean | 14.127292 | 19.289649 | 91.969033 | 654.889104 | 0.096360 | 0.104341 | 0.088799 | 0.048919 | 0.181162 | 0.062798 | ... | 25.677223 | 107.261213 | 880.583128 | 0.132369 | 0.254265 | 0.272188 | 0.114606 | 0.290076 | 0.083946 | 0.627417 |
std | 3.524049 | 4.301036 | 24.298981 | 351.914129 | 0.014064 | 0.052813 | 0.079720 | 0.038803 | 0.027414 | 0.007060 | ... | 6.146258 | 33.602542 | 569.356993 | 0.022832 | 0.157336 | 0.208624 | 0.065732 | 0.061867 | 0.018061 | 0.483918 |
min | 6.981000 | 9.710000 | 43.790000 | 143.500000 | 0.052630 | 0.019380 | 0.000000 | 0.000000 | 0.106000 | 0.049960 | ... | 12.020000 | 50.410000 | 185.200000 | 0.071170 | 0.027290 | 0.000000 | 0.000000 | 0.156500 | 0.055040 | 0.000000 |
25% | 11.700000 | 16.170000 | 75.170000 | 420.300000 | 0.086370 | 0.064920 | 0.029560 | 0.020310 | 0.161900 | 0.057700 | ... | 21.080000 | 84.110000 | 515.300000 | 0.116600 | 0.147200 | 0.114500 | 0.064930 | 0.250400 | 0.071460 | 0.000000 |
50% | 13.370000 | 18.840000 | 86.240000 | 551.100000 | 0.095870 | 0.092630 | 0.061540 | 0.033500 | 0.179200 | 0.061540 | ... | 25.410000 | 97.660000 | 686.500000 | 0.131300 | 0.211900 | 0.226700 | 0.099930 | 0.282200 | 0.080040 | 1.000000 |
75% | 15.780000 | 21.800000 | 104.100000 | 782.700000 | 0.105300 | 0.130400 | 0.130700 | 0.074000 | 0.195700 | 0.066120 | ... | 29.720000 | 125.400000 | 1084.000000 | 0.146000 | 0.339100 | 0.382900 | 0.161400 | 0.317900 | 0.092080 | 1.000000 |
max | 28.110000 | 39.280000 | 188.500000 | 2501.000000 | 0.163400 | 0.345400 | 0.426800 | 0.201200 | 0.304000 | 0.097440 | ... | 49.540000 | 251.200000 | 4254.000000 | 0.222600 | 1.058000 | 1.252000 | 0.291000 | 0.663800 | 0.207500 | 1.000000 |
8 rows × 31 columns
Asimismo, se pueden hacer diferentes visualizaciones de las variables de los datos. Esto tiene relevancia cuándo se quiere comparar el comportamiento de datos, pues permite ver gráficamente como se comportan.
Pandas tiene diferentes formas de visualizar los datos, aquí presentamos algunas de ellas:
data_vis = dataset[['mean radius', 'mean texture', 'mean area' , 'worst radius', 'worst texture', 'worst area','Y']]
#Graficación
data_vis[['mean radius','mean texture']].plot()
plt.show()
#Gráfica de barras
data_vis.groupby('Y').mean().plot.bar()
plt.show()
#Histograma
data_vis[['mean radius','mean texture']].plot.hist()
plt.show()
#Gráfica de cajas
data_vis[['mean radius','mean texture','Y']].plot.box()
plt.show()
#Gráfica de pastel
dataset.groupby('Y').mean()['worst radius'].plot.pie()
plt.show()
También podemos obtener la correlación de las variables entre sí. En particular se pueden obtener las correlaciones de Pearson y de Spearman. La correlación nos permite determinar qué tanta dependencia existe entre dos variables. Si el valor es positivo, implica que hay una dependencia. la cual más cercana a 1 será más fuerte. Si es negativo la dependencia es negativa. El valor 0 indica la ausencia de dependencias.
data_vis.corr('pearson')
mean radius | mean texture | mean area | worst radius | worst texture | worst area | Y | |
---|---|---|---|---|---|---|---|
mean radius | 1.000000 | 0.323782 | 0.987357 | 0.969539 | 0.297008 | 0.941082 | -0.730029 |
mean texture | 0.323782 | 1.000000 | 0.321086 | 0.352573 | 0.912045 | 0.343546 | -0.415185 |
mean area | 0.987357 | 0.321086 | 1.000000 | 0.962746 | 0.287489 | 0.959213 | -0.708984 |
worst radius | 0.969539 | 0.352573 | 0.962746 | 1.000000 | 0.359921 | 0.984015 | -0.776454 |
worst texture | 0.297008 | 0.912045 | 0.287489 | 0.359921 | 1.000000 | 0.345842 | -0.456903 |
worst area | 0.941082 | 0.343546 | 0.959213 | 0.984015 | 0.345842 | 1.000000 | -0.733825 |
Y | -0.730029 | -0.415185 | -0.708984 | -0.776454 | -0.456903 | -0.733825 | 1.000000 |
Dentro de la exploración de datos, es muy común que los datos de grandes dimensiones se reduzcan a dimensiones menores para poder visualizarse y poder explorar y explicar ciertos comportamientos en los datos. Para esto, se utilizan diferentes estrategias, entre una de las más populares se encuentra el método de PCA (Principal Component Analysis), el cuál básicamente se enfoca en encontrar una transformación lineal $U^*$ que sea invertible y ortogonal. Es decir, se busca una función que cumpla:
$$U^* = \arg\min_U \frac{1}{2}|| x - U^T U x||$$De tal forma que se satisfaga $U^T U \approx Id$$. Realizar esto lleva a un problema de valores y vectores propios. Para simplificar, usamos aquí la librería sklearn que ya cuenta con una implementación de PCA.
from sklearn.decomposition import PCA
#Datos
X = dataset.to_numpy()[:,:-1]
#Clases de los datos
Y = dataset['Y'].to_numpy()
#Reducción con PCA
X_red = PCA(2).fit_transform(X)
#Visualización
plt.scatter(X_red[:,0], X_red[:,1], c=Y)
plt.show()
El método de PCA es equivalente a una red neuronal con varias restricciones. Ponemos a continuación un código que determina una función lineal (definida por una matriz $U$) que es equivalente al procesamiento que hace PCA, pero con un entrenamiento de red neuronal. Los resultados, si bien no los mismos, son similares.
import torch
import torch.nn as nn
#Datos a formato torch
X = torch.tensor(X, dtype=torch.float)
#Primera capa equivalente a U
red = nn.Linear(30, 2, bias=False)
#Segunda capa equivalente a U^T
decode = nn.Linear(2, 30, bias=False)
#Entrenamiento
risk = nn.MSELoss()
optimizer = torch.optim.Adam(list(red.parameters()) + list(decode.parameters()), lr=0.1)
for t in range(0,1000):
reconst = decode(red(X))
optimizer.zero_grad()
loss = risk(reconst, X)
loss.backward()
optimizer.step()
#Visualización
visualization = red(X).detach().numpy()
plt.scatter(visualization[:,0], visualization[:,1], c=Y)
plt.show()