Un aspecto muy importante en series de datos (como los datos usados en la entrada sobre correlación) son las tendencias. Las tendencias indican cambios graduales el comportamiento temporal el promedio en un período prolongado. Aunque medidas consecutivas puedan indicar valores que crecen o decrecen en sentidos opuestos a la tendencia general, el comportamiento promedio persiste en el tiempo.
Un ejemplo de esto sería el clima; en el hemisferio norte, las temperaturas pueden disminuir varios grados de un día a otro, pero el comportamiento general será el del calentamiento hasta el verano. Entender las tendencias también nos permite realizar análisis predictivos; como los que nos advierten del calentamiento global. Pero las tendencias no son importantes sólo en ciencias naturales; también lo son, y mucho, en los mercados y los negocios.
En esta entrada, veremos cómo detectar la tendencia de una serie temporal, usando nuevamente los datos de la célula de flotación que usamos en la entrada anterior.
En primer lugar, cargamos los datos:
>>> import pandas as pd >>> import matplotlib.pyplot as plt >>> fcdata = pd.read_csv('flotation-cell.csv', index_col=0) >>> print(fcdata.head()) Feed rate Upstream pH CuSO4 added Pulp level \ Date and time 15/12/2004 19:57:01 341.049347 10.820513 7.995605 24.443470 15/12/2004 19:57:31 274.270782 10.827351 7.786569 27.819294 15/12/2004 19:58:01 334.836761 10.854701 7.655922 30.335533 15/12/2004 19:58:32 323.605927 10.885470 7.838828 30.663738 15/12/2004 19:59:03 322.341309 10.851282 7.995605 30.288647 Air flow rate Date and time 15/12/2004 19:57:01 2.802198 15/12/2004 19:57:31 2.798535 15/12/2004 19:58:01 2.805861 15/12/2004 19:58:32 2.802198 15/12/2004 19:59:03 2.805861
A continuación, seleccionamos los datos que queremos analizar:
>>> selected = fcdata.loc[('16/12/2004 20:16:00' < fcdata.index) & (fcdata.index < '16/12/2004 20:25:00'),'Feed rate'] >>> selected.plot() >>> plt.show()
Bien, ¿cómo podemos usar Pandas para encontrar la tendencia en esta serie temporal? Hay muchas formas, pero usaremos una librería adicional (usada internamente por Pandas): NumPy. NumPy tiene muchas funciones matemáticas interesantes y es muy recomendable conocerla bien. En este caso, usaremos la función polyfit(), que ajusta un polinomio a los datos que le pasemos y nos devuelve además el error de ajuste. En nuestro caso, usaremos un polinomio de primer grado para encontrar la línea de regresión óptima. Un polinomio de primer grado tendrá dos parámetros: la pendiente y la ordenada en el origen. Si la pendiente devuelta por polyfit() es distinta a cero, entonces se puede considerar que hay una tendencia. polyfit() devolverá varios valores, pero sólo necesitamos dos: los coeficientes (dados como una lista con la pendiente y la ordenada en el origen) y el residuo (que nos da una medida del error de ajuste, y que convertiremos en el Error Cuadrático Medio Normalizado, o NRMSE, que nos da una medida del error entre 0 y 1).
>>> import numpy as np >>> coefficients, residuals, _, _, _ = np.polyfit(range(len(selected.index)),selected,1,full=True) >>> mse = residuals[0]/(len(selected.index)) >>> nrmse = np.sqrt(mse)/(selected.max() - selected.min()) >>> print('Slope ' + str(coefficients[0])) >>> print('NRMSE: ' + str(nrmse)) Slope -1.72979024566 NMRSE: 0.274160734073
Podemos ver que hay una tendencia negativa, de -1.73 unidades para la variable Feed rate por cada intervalo de tiempo (en estos datos, cada intervalo son 30 segundos), con un error de ajuste del 27.4%. Con esto podemos dibujar la línea de regresión, recordando que es un polinomio del tipo Ax+B.
>>> plt.plot(selected) >>> plt.plot([coefficients[0]*x + coefficients[1] for x in range(len(selected))]) >>> plt.show()
Podemos ver que la línea de regresión se aproxima claramente a la tendencia de los datos, aunque el ruido (las pequeñas variaciones de una muestra a la siguiente) añade algo de error.
En esta entrada hemos visto una aplicación más de Pandas a un problema real. En el futuro veremos aplicaciones más específicas.