miércoles, 27 de junio de 2012

Regresión polinomial (extremely easy)

Usando a librería numpy podemos axustar unha curva de predicción a datos empíricos en catro liñas. Supoñamos que temos un programa que analiza texto. Funciona moi ben nos textos de proba, pero intuimos que textos de máis de 40 millóns de caracteres pode bloquear ou eternizar o script. ¿Cómo facer unha estima a priori de cánto tardará o script? Facemos unhas probas con textos controlados:
Millóns           Tempo
de caracteres  |  en segundos
---------------+--------------------
1              | 0.65
2              | 1.76
3              | 3.34
4              | 5.4
4.5            | 6.8
5              | 7.9
7.5            | 16.15
10             | 27.2
20             | 101.5
---------------+--------------------
(Estes datos foron medidos realmente). Rápidamente podemos decidir un punto de corte, por exemplo textos de máis de 10 millóns de caracteres non se van procesar porque levan moito tempo. Pero mellor predecimos cánto vai tardar o script axustando un polinomio ós datos que temos. Ploteando os puntos anteriores, podemos intuir que necesitamos "máis" que unha recta, pero "chega" con unha parábola:


tempo = a + bx + cx²

import numpy as np
from numpy.polynomial.polynomial import polyfit

#Millions of chars
n_char = np.array([1, 2, 3, 4, 4.5, 5, 7.5, 10, 20])

#Seconds meassured
times = np.array([0.65, 1.76, 3.34, 5.4,
                  6.8, 7.9, 16.15, 27.2, 101.5])

#polyfit(X, Y, grado polinomio)
print polyfit(n_char, times, 2)


Salida:

[0.11502188  0.37922652  0.23444005]

Then, solution. Contamos o número de palabras, metémolo en x, e calculamos:


tempo estimado = 0.115 + 0.379x + 0.234x²


Para un texto de 15 millóns de palabras, estimamos 0.115 + 0.379 * 15 + 0.234 * 15²,  ~58 seg.