Arboles y Bosques... de decision...

Avatar de Usuario
Dalamar
Site Admin
Mensajes: 8963
Registrado: 09 May 2012 01:38

Arboles y Bosques... de decision...

Mensajepor Dalamar » 04 Mar 2017 12:14

Vamos a empezar con unos experimentos en python usando scikit-learn.

Primero usaremos el dia de la semana unicamente, despues pasaremos a usar el mes, el dia del mes, medias moviles etc...

Y vamos a comparar los resultados usando arboles de decision (Decision Trees) con los que obtendremos con las diferentes metodologias de bosques aleatorios (Random Forest).

Vamos a descargar de Yahoo los datos de IBM y a hacer unos calculos con ello:

Código: Seleccionar todo

import os
import io
import subprocess
import pandas as pd
import numpy as np
from sklearn import tree
from sklearn import preprocessing
from sklearn.cross_validation import train_test_split
from sklearn.tree import export_graphviz
from sklearn.ensemble import RandomForestClassifier, ExtraTreesClassifier
import pandas_datareader as pdr
from datetime import datetime
import analyze_dt as adt
from sklearn import metrics
import pydot

df = pdr.get_data_yahoo(symbols='IBM', start=datetime(2000, 1, 1), end=datetime(2012, 1, 1))
# Day of the week
df["DayWeek"] = df.index.weekday
# Day of the month
df["DayMonth"] = df.index.day
# Days to end of the month
df["DayToEndMonth"] = df.index.daysinmonth - df.index.day
# Month
df["Month"] = df.index.month
# Today is up or down
df["Today"] = pd.Series((df.Open - df.Close) > 0, df.index)
# Yesterday was up or down
df["Yesterday"] = pd.Series((df.shift(1).Open - df.shift(1).Close)/df.shift(1).Close, df.index)
df["Yesterday"].fillna(0, inplace=True)
# Before yesterday was up or down
df["Before"] = pd.Series((df.shift(2).Open - df.shift(2).Close)/df.shift(2).Close, df.index)
df["Before"].fillna(0, inplace=True)
# 50 Days moving average
df["50d"] = np.round(df["Close"].rolling(window = 50, center = False).mean(), 2)
df["50d"].fillna(df["Close"], inplace=True)
# 200 Days moving average
df["200d"] = np.round(df["Close"].rolling(window = 200, center = False).mean(), 2)
df["200d"].fillna(df["Close"], inplace=True)
# 50 Days - 200 Days moving average
df['50d-200d'] = df['50d'] - df['200d']
# Regime
df["Regime"] = np.where(df['50d-200d'] > 0, 1, 0)
df["Regime"] = np.where(df['50d-200d'] < 0, -1, df["Regime"])


Para empezar solo usaremos el dia de la semana, de forma numerica ya que scikit-learn tiene ciertos problemas con las variables categoricas, veremos que con otros paquetes en R tenemos mas facilidades:

Código: Seleccionar todo

features = ["DayWeek"]
y = all["Today"]
X = all[features]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)
# Ver: http://stackoverflow.com/questions/34246336/python-randomforest-unknown-label-error
y_train = np.asarray(y_train.values, dtype="|S6")

model = tree.DecisionTreeClassifier(max_depth=3, min_samples_split=10, criterion='gini')
model.fit(X_train, y_train)
model.score(X_train, y_train)

dotfile = open("dtree.dot", 'w')
tree.export_graphviz(model, out_file = dotfile, feature_names = X.columns)
dotfile.close()


Obtenemos un 53,67% de aciertos, ver que he limitado la profundidad del arbol a 3, veremos lo que ocurre con otros parametros, jugando con el numero mino de samples y usando entropia en vez de gini.

Veremos como usar los encoders y como podemos obtener un 100% de aciertos con un overfitting total al no limitar la profuncidad del arbol.

Alguien se anima a experimentar conmigo?
Adjuntos
DecisionTree1.JPG
DecisionTree2.JPG
DecisionTree2.JPG (22.05 KiB) Visto 582 veces
DecisionTree3.JPG
¿Te ha gustado este hilo? Compartelo en las redes sociales para que se sume mas gente a la conversacion!

Avatar de Usuario
Dalamar
Site Admin
Mensajes: 8963
Registrado: 09 May 2012 01:38

Re: Arboles y Bosques... de decision...

Mensajepor Dalamar » 04 Mar 2017 12:19

Si queremos que el dia de la semana sea el dia en si, no el numero, podemos hacer esto:

Código: Seleccionar todo

df["DayWeek"] = df.index.weekday_name


Y si necesitamos evaluarlo de forma numerica podemos crear una columna para cada dia usando get_dummies:

Código: Seleccionar todo

pd.get_dummies(df["DayWeek"])
all = pd.concat([df, pd.get_dummies(df["DayWeek"])], axis=1)
Adjuntos
DecisionTree4.JPG
¿Te ha gustado este hilo? Compartelo en las redes sociales para que se sume mas gente a la conversacion!

Avatar de Usuario
Dalamar
Site Admin
Mensajes: 8963
Registrado: 09 May 2012 01:38

Re: Arboles y Bosques... de decision...

Mensajepor Dalamar » 04 Mar 2017 12:30

Ahora le agregamos al calculo, la cariacion del precio de ayer y de antes de ayer, tengo en cuenta que esto hay que mejorarlo con el porcentaje... pero poco a poco...

Código: Seleccionar todo

features = ["Yesterday", "Before", "DayWeek"]


Obtenemos un 56% de aciertos en este caso.

Como lo interpretamos? Pues el lunes es el 0, el Viernes es el 4...

Si estamos a menos de Viernes y antes de ayer la caida fue menor o igual de 0.0185, y ademas ayer la caida fue menor o igual de 0.006 tenemos 18 casos en los que subio el valor y 40 en los que bajo... etc...
Adjuntos
DecisionTree5.JPG
DecisionTree6.JPG
¿Te ha gustado este hilo? Compartelo en las redes sociales para que se sume mas gente a la conversacion!

Avatar de Usuario
Dalamar
Site Admin
Mensajes: 8963
Registrado: 09 May 2012 01:38

Re: Arboles y Bosques... de decision...

Mensajepor Dalamar » 04 Mar 2017 12:33

Ahora vamos a hacer el mismo estudio pero en este caso vamos a usar un RandomForest, obtenemos un 56.7%, vamos mejorando...
Adjuntos
RandomForest1.JPG
¿Te ha gustado este hilo? Compartelo en las redes sociales para que se sume mas gente a la conversacion!

Avatar de Usuario
Dalamar
Site Admin
Mensajes: 8963
Registrado: 09 May 2012 01:38

Re: Arboles y Bosques... de decision...

Mensajepor Dalamar » 04 Mar 2017 17:28

Vemos en el grafico que con un arbol de decision separamos en cajitas cada area, por lo que si queremos separar rojo (bajista) de azul (alcista), vamos a calcular que cajitas son las mas adecuadas...

Si separamos el grafico en demasiadas cajitas, podremos tener una para cada punto, por lo cual tendremos un 100% de exito en los datos de training, pero obviamente tendremos poco exito con datos que vengan de fuera de la muestra, es lo que llamamos overfitting.

Con RandomTrees lo que hacemos es crear varios arboles con componentes al azar, para que sean diferentes.

Por ejemplo podemos usar diferentes muestras de los datos.

La ventaja de utilizar multiples arboles es reducir la varianza (variance) o la desviacion (bias), es un trade-off.

La mayor desventaja es que los RandomTrees son mas dificiles de interpretar.

Otra gran ventaja es que son faciles de parametrizar.
Adjuntos
RandomforestExplanation3.JPG
RandomforestExplanation2.JPG
DecisionTreeExplanation1.JPG
RandomforestExplanation1.JPG
¿Te ha gustado este hilo? Compartelo en las redes sociales para que se sume mas gente a la conversacion!

Avatar de Usuario
Dalamar
Site Admin
Mensajes: 8963
Registrado: 09 May 2012 01:38

Re: Arboles y Bosques... de decision...

Mensajepor Dalamar » 04 Mar 2017 17:54

Si nos vamos un paso mas alla para obtener mejores resultados, hablamos de Boosting, el mayor problema es que es complicado de parametrizar, sobre todo el learning rate.
Adjuntos
BoostingExplanation1.JPG
BoostingExplanation2.JPG
¿Te ha gustado este hilo? Compartelo en las redes sociales para que se sume mas gente a la conversacion!

Avatar de Usuario
Dalamar
Site Admin
Mensajes: 8963
Registrado: 09 May 2012 01:38

Re: Arboles y Bosques... de decision...

Mensajepor Dalamar » 11 Mar 2017 07:19

Continuemos con nuestros arboles y bosques:

Hasta ahora hemos obtenido una tasa de aciertos basada en nuestros datos de entrenamiento, lo cual significa bastante poco, ahora tenemos que aplicarlo a los datos de test.

Por otro lado estamos dividiendo un 20% en datos de test y un 80% en datos de entrenamiento, pero que pasa si hacemos divisiones diversas y corremos el proceso multiples veces? Obtenemos los mismos resultados?

Por otro lado no hemos escalado los datos para que esten en una medida uniforme, por lo tanto estos van a ser los proximos pasos que aplicaremos en nuestro modelo.

De momento estamos aplicando el modelo a predecir si subira o bajara el stock al dia siguiente basandonos en el dia de la semana, podemos hacer otros estudios como relacionar el VIX con lo que le ocurrira al mercado en una semana, en un mes o en 3 o 6 meses, donde decimos VIX podemos decir ratio Put/Call o como suelen decir la media de 200 actua de soporte y resistencia y el precio rebota contra ella, podemos ver la distancia a la media movil (en porcentaje) y que pasa en un dia en una semana etc....

Una vez que comprobemos todo esto, iremos a por algo mas avanzado como Boosting: http://machinelearningmastery.com/gentl ... -learning/

Y ya no miraremos solo training y test, tendremos que optimizar hiperparametros y hacer otra division...

Otra cosa a tener en cuenta es que a mas factores para la prediccion, mas necesidad de datos de training, y los que tenemos son limitados, por lo que tendremos que identificar los mas relevantes, esto se automatiza con PCA (Principal Component Analysis).

Por aqui llegaremos a Boosting y creare otros hilos para optimizar hiperparametros, para PCA etc...
¿Te ha gustado este hilo? Compartelo en las redes sociales para que se sume mas gente a la conversacion!


Volver a “Inteligencia Artificial”

cron

Ingresar