La simplicidad es clave.
Objetivo
En este tutorial, usaremos este conjunto de datos de precio de Bitcoin vs USD .
El conjunto de datos anterior contiene un resumen diario de precios donde el CAMBIO columna es el cambio porcentual del último precio del día ( PRECIO ) con respecto al primero (O PEN ).
Meta: Para simplificar las cosas nos centraremos en predecir si el precio aumentará ( cambiará> 0 ) o caerá ( cambio ≤ 0 ) al día siguiente. (Por lo tanto, podríamos usar las predicciones “en la vida real”).
Requisitos previos
- Tener instalado Python 2.6+ o 3.1+
- Instalar pandas, sklearn y openblender (con pip)
$ pip install pandas OpenBlender scikit-learn
Paso 1. Obtenga los datos de precio de Bitcoin
Importemos las bibliotecas que usaremos:
import OpenBlender
import pandas as pd
import json
Ahora saquemos las datos a través de la API OpenBlender .
Primero, definiremos los parámetros (en este caso es solo la identificación del conjunto de datos de precio de Bitcoin ):
# It only contains the id, we'll add more parameters
later.parameters = {
'id_dataset':'5d4c3af79516290b01c83f51'
}
agregaremos más parámetros más tarde.
parameters = {
'token':'your_token',
'id_user':'your_id_user',
'id_dataset':'5d4c3af79516290b01c83f51'
}
Ahora extraigamos los datos en un Marco de datos ‘df’:
# This function pulls the data and orders by timestamp
def pullObservationsToDF(parameters):
action = 'API_getObservationsFromDataset'
df = pd.read_json(json.dumps(OpenBlender.call(action,parameters)['sample']), convert_dates=False,convert_axes=False) .sort_values('timestamp', ascending=False)
df.reset_index(drop=True, inplace=True)
return df
df = pullObservationsToDF(parameters)
Echemos un vistazo
df.head ()
Nota: Los valores pueden variar ya que este conjunto de datos se actualiza diariamente .
Precio de Bitcoin: Paso 2. Prepara los datos
Primero, necesitamos crear nuestro p objetivo de prohibición que es si el “cambio” aumentará o disminuirá. Para hacer esto, agregue un umbral objetivo para el éxito sobre cero a nuestros parámetros:
parameters = {
'token':'your_token',
'id_user':'your_id_user',
'id_dataset':'5d4c3af79516290b01c83f51',
'target_threshold':{'feature':'change', 'success_thr_over': 0}
}
Si extraemos datos de la API nuevamente:
df = pullObservationsToDF(parameters)
df.head()
La característica ‘cambiar’ fue reemplazada por una nueva característica: ‘ change_over_0 ‘ que es 1 si ‘cambio’ fue positivo y 0 si más. Este será nuestro objetivo para el aprendizaje automático.
Si queremos predecir observaciones para ‘mañana’ no podemos usar información del mismo día, así que agreguemos un un período de retraso en el destino.
parameters = {
'token':'your_token',
'id_user':'your_id_user',
'id_dataset':'5d4c3af79516290b01c83f51',
'target_threshold':{'feature':'change','success_thr_over' : 0},
'lag_target_feature':{'feature':'change_over_0', 'periods' : 1}
}
df = pullObservationsToDF(parameters)
df.head()
Esto simplemente alineó ‘change_over_0’ con los datos del período anterior (día) y cambió su nombre a ‘ TARGET_change_over_0 ‘.
Echemos un vistazo a las correlaciones:
target_variable = 'TARGET_change_over_0'
df = df.dropna()
df.corr()[target_variable].sort_values()
No están correlacionados linealmente y es muy poco probable que sean útiles.
Paso 3. Obtener datos de Business News
Después de buscar correlaciones en OpenBlender encontré un conjunto de datos de Fox Business News que ayuda a generar buenas predicciones sobre nuestro objetivo específico.
Lo que queremos es una forma de convertir el ‘título’ en características numéricas contando repeticiones de palabras y grupos de palabras por elemento de noticias y combínalos en el tiempo a nuestro conjunto de datos de precio de Bitcoin. Esto es más simple de lo que parece.
Primero, necesitamos crear un TextVectorizer para la función ‘título’ de la noticia:
action = 'API_createTextVectorizer'vectorizer_parameters = {
'token' : 'your_token',
'id_user' : 'your_id_user',
'name' : 'Fox Business TextVectorizer',
'anchor':{'id_dataset' : '5d571f9e9516293a12ad4f6d', 'include_features' : ['title']},
'ngram_range' : {'min' : 1, 'max' : 2},
'language' : 'en',
'remove_stop_words' : 'on',
'min_count_limit' : 2
}
Crearemos un vectorizador para que podamos obtener todas las funciones como recuentos numéricos de token de palabras. Arriba, especificamos lo siguiente:
- name: Lo llamaremos ‘Fox Business TextVectorizer’
- anchor : El id del conjunto de datos y el nombre de las características para incluir como fuente (en este caso, solo ‘título’)
- ngram_range : La longitud mínima y máxima del conjunto de palabras que se tokenizarán
- language: inglés
- remove_stop_words : Por lo tanto, elimina las palabras de detención de la fuente
- min_count_limit : El mínimo de repeticiones para ser considerado un token (los eventos únicos rara vez ayudan)
Vamos a ejecutarlo :
res = OpenBlender.call(action, vectorizer_parameters)
res
Response:
{
'message' : 'TextVectorizer created successfully.'
'id_textVectorizer' : '5dc1a404951629331f6359dd',
'num_ngrams': 4270
}
El TextVectorizer fue creado y generó 4270 n-gramos con nuestra configuración. Usaremos la identificación generada más tarde: 5dc1a404951629331f6359dd
Paso 4. Mezcle las noticias con el conjunto de datos de precio de Bitcoin
Ahora, queremos mezclar las características en el tiempo Datos de precio de Bitcoin .
Esto básicamente significa unir los dos conjuntos de datos utilizando la marca de tiempo como clave . Agreguemos la mezcla a nuestros parámetros originales para obtener datos:
parameters = {
'token':'your_token',
'id_user':'your_id_user',
'id_dataset':'5d4c3af79516290b01c83f51',
'target_threshold' : {'feature':'change','success_thr_over':0},
'lag_target_feature' : {'feature':'change_over_0', 'periods':1},
'blends':[{'id_blend':'5dc1a404951629331f6359dd',
'blend_type' : 'text_ts',
'restriction' : 'predictive',
'blend_class' : 'closest_observation',
'specifications":{'time_interval_size' : 3600*12 }}]
}
Lo que estamos especificando arriba es lo siguiente:
- id_blend : La identificación de nuestro TextVectorizer
- blend_type : ‘text_ts’ para que sepa que es una mezcla de texto y marca de tiempo
- restriction : ‘predictivo’, para que no mezcle noticias del futuro con cada observación, solo noticias que ocurrieron antes de
- blend_class : ‘la observación más cercana’ para que combine las observaciones más cercanas en el tiempo
- specificacions : el tiempo máximo al pasado desde el cual traerá observaciones en segundos, que en este caso es de 12 horas (3600 * 12). Esto solo significa que cada observación del precio de Bitcoin se pronosticará con noticias del últimas 12 horas
Finalmente, solo agregaremos un filtro de fecha que comienza el 20 de agosto porque es cuando se inició el conjunto de datos de Fox News y ‘drop_non_numeric’, por lo que solo obtenemos números:
parameters = {
'token':'your_token',
'id_user':'your_id_user',
'id_dataset':'5d4c3af79516290b01c83f51',
'target_threshold' : {'feature':'change','success_thr_over':0},
'lag_target_feature' : {'feature':'change_over_0', 'periods':1},
'blends':[{'id_blend':'5dc1a404951629331f6359dd',
'blend_type' : 'text_ts',
'restriction' : 'predictive',
'blend_class' : 'closest_observation',
'specifications':{'time_interval_size' : 3600*12 }}],
'date_filter':{'start_date':'2019-08-20T16:59:35.825Z',
'end_date':'2019-11-04T17:59:35.825Z'},
'drop_non_numeric' : 1
}
Nota: Especifiqué el 4 de noviembre como ‘ end_date ‘ porque ese es el día en que lo escribí, pero puede cambiar el fecha en que lo está leyendo.
Vuelva a extraer los datos:
df = pullObservationsToDF(parameters)
print(df.shape)
df.head()
( 57, 2115)
Ahora tenemos más de 2K características con todos los tokens, y tenemos 57 observaciones.
Paso 5. Aplicar ML para predecir el objetivo
Ahora finalmente tenemos el conjunto de datos limpios exactamente como lo necesitamos con el objetivo rezagado y los datos numéricos combinados .
Echemos un vistazo a las correlaciones principales con ‘Target_change_over_0’:
Hay varias características correlacionadas ahora. Separemos o entrenar y prueba establece cronológicamente, por lo que podemos entrenar con observaciones anteriores y prueba en futuras .
X = df.loc[:, df.columns != target_variable].values
y = df.loc[:,[target_variable]].values
div = int(round(len(X) * 0.29))
# We take the first observations as test and the last as train because the dataset is ordered by timestamp descending.
X_test = X[:div]
y_test = y[:div]print(X_test.shape)
print(y_test.shape)X_train = X[div:]
y_train = y[div:]
print(X_train.shape)
print(y_train.shape)
Tenemos 40 observaciones para entrenar y 17 para probar.
Ahora, importaremos las bibliotecas necesarias:
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error
from sklearn.metrics import accuracy_score
from sklearn.metrics import roc_auc_score
from sklearn import metrics
Ahora, ajustemos RandomForest y hagamos las predicciones:
rf = RandomForestRegressor(n_estimators = 1000)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)
Para que sea más fácil de entender, pongamos las predicciones y el y_test en un Dataframe:
df_res = pd.DataFrame({'y_test':y_test[:,0], 'y_pred':y_pred})
df_res.head()
df_res.head ()
Nuestro verdadero ‘y_test’ es binario pero nuestras predicciones son flotantes, así que redondeémoslas suponiendo que si son mayores que 0.5 predeciríamos un aumento de precio y menor que 0.5 una disminución.
threshold = 0.5
preds = [1 if val > threshold else 0 for val in df_res['y_pred']]
Ahora, para mejor comprensión de nuestros resultados, obtengamos el AUC, la matriz de confusión y el puntaje de precisión:
print(roc_auc_score(preds, df_res['y_test']))
print(metrics.confusion_matrix(preds, df_res['y_test']))
print(accuracy_score(preds, df_res['y_test']))
Obtuvimos 64.7 % de las predicciones correctas con 0.65 AUC para respaldarlo.
- 9 veces predijimos una disminución y disminuyó ( correcto )
- 5 veces pronosticamos una disminución y aumentó ( incorrecto )
- 1 vez predijimos un aumento y disminuyó ( incorrecto )
- 2 veces predijimos un aumento y aumentó ( correcto )