• Introducción
  • Librerías
  • Datos
  • Modelos de forecasting
    • ForecasterRecursive
  • Importancia de predictores específica de los modelos
  • Valores SHAP (SHapley Additive exPlanations)
    • Shap: importancia global de los predictores
      • SHAP Summary Plot
      • Gráfico de dependencia SHAP
    • SHAP: explicación de predicciones individuales
  • Scikit-learn gráficos de dependencia parcial
  • Información de sesión
  • Instrucciones para citar


Más sobre forecasting en: cienciadedatos.net


Introducción

La interpretabilidad de los modelos predictivos, también conocida como explicabilidad, se refiere a la capacidad de entender, interpretar y explicar las decisiones o predicciones tomadas por los modelos de una forma comprensible para el ser humano. Su objetivo es comprender cómo un modelo llega a un determinado resultado o decisión.

Debido a la naturaleza compleja de muchos modelos modernos de machine learning, como los métodos ensemble, que a menudo funcionan como cajas negras, es dificil comprender por qué se ha hecho una predicción concreta. Las técnicas de explicabilidad pretenden desmitificar estos modelos, proporcionando información sobre su funcionamiento interno y ayudando a generar confianza, a mejorar la transparencia y a cumplir los requisitos normativos en diversos ámbitos. Mejorar la explicabilidad de los modelos no solo ayuda a comprender su comportamiento, sino también a identificar sesgos, a mejorar el rendimiento de los modelos y a permitir que las partes interesadas tomen decisiones más informadas basadas en los conocimientos del aprendizaje automático.

La librería skforecast es compatible con algunos de los métodos de interpretabilidad más utilizados: Shap values, Partial Dependency Plots y métodos específicos de los modelos.

Librerías

Librerías utilizadas en este documento.

# Manipulación de datos
# ==============================================================================
import pandas as pd
import numpy as np
from skforecast.datasets import fetch_dataset

# Gráficos
# ==============================================================================
import matplotlib.pyplot as plt
import shap
from skforecast.plot import set_dark_theme

# Modelado y forecasting
# ==============================================================================
import sklearn
import lightgbm
import skforecast
from sklearn.inspection import PartialDependenceDisplay
from lightgbm import LGBMRegressor
from skforecast.recursive import ForecasterRecursive
from skforecast.preprocessing import RollingFeatures
from skforecast.model_selection import backtesting_forecaster, TimeSeriesFold

color = '\033[1m\033[38;5;208m'
print(f"{color}Versión skforecast: {skforecast.__version__}")
print(f"{color}Versión scikit-learn: {sklearn.__version__}")
print(f"{color}Versión lightgbm: {lightgbm.__version__}")
print(f"{color}Versión shap: {shap.__version__}")
Versión skforecast: 0.16.0
Versión scikit-learn: 1.6.1
Versión lightgbm: 4.6.0
Versión shap: 0.47.2

Datos

# Descarga de los datos
# ==============================================================================
data = fetch_dataset(name="vic_electricity")
data.head(3)
vic_electricity
---------------
Half-hourly electricity demand for Victoria, Australia
O'Hara-Wild M, Hyndman R, Wang E, Godahewa R (2022).tsibbledata: Diverse
Datasets for 'tsibble'. https://tsibbledata.tidyverts.org/,
https://github.com/tidyverts/tsibbledata/.
https://tsibbledata.tidyverts.org/reference/vic_elec.html
Shape of the dataset: (52608, 4)
Demand Temperature Date Holiday
Time
2011-12-31 13:00:00 4382.825174 21.40 2012-01-01 True
2011-12-31 13:30:00 4263.365526 21.05 2012-01-01 True
2011-12-31 14:00:00 4048.966046 20.70 2012-01-01 True
# Agregación a frecuencia diaria
# ==============================================================================
data = data.resample('D').agg({'Demand': 'sum', 'Temperature': 'mean'})
data.head(3)
Demand Temperature
Time
2011-12-31 82531.745918 21.047727
2012-01-01 227778.257304 26.578125
2012-01-02 275490.988882 31.751042
# Crear variables de calendario
# ==============================================================================
data['day_of_week'] = data.index.dayofweek
data['month'] = data.index.month
data.head(3)
Demand Temperature day_of_week month
Time
2011-12-31 82531.745918 21.047727 5 12
2012-01-01 227778.257304 26.578125 6 1
2012-01-02 275490.988882 31.751042 0 1
# División train-test
# ==============================================================================
end_train = '2014-12-01 23:59:00'
data_train = data.loc[: end_train, :]
data_test  = data.loc[end_train:, :]
print(f"Fechas train : {data_train.index.min()} --- {data_train.index.max()}  (n={len(data_train)})")
print(f"Fechas test  : {data_test.index.min()} --- {data_test.index.max()}  (n={len(data_test)})")
Fechas train : 2011-12-31 00:00:00 --- 2014-12-01 00:00:00  (n=1067)
Fechas test  : 2014-12-02 00:00:00 --- 2014-12-31 00:00:00  (n=30)

Modelos de forecasting

Se creará un modelo de forecasting para predecir la demanda de energía utilizando los últimos 7 valores (última semana) y la temperatura como variable exógena.

# Crear un forecaster recursivo de múltiples pasos (ForecasterRecursive)
# ==============================================================================
window_features = RollingFeatures(stats=['mean'], window_sizes=24)
exog_features = ['Temperature', 'day_of_week', 'month']
forecaster = ForecasterRecursive(
                 regressor       = LGBMRegressor(random_state=123, verbose=-1),
                 lags            = 7,
                 window_features = window_features
             )

forecaster.fit(
    y    = data_train['Demand'],
    exog = data_train[exog_features],
)
forecaster

ForecasterRecursive

General Information
  • Regressor: LGBMRegressor
  • Lags: [1 2 3 4 5 6 7]
  • Window features: ['roll_mean_24']
  • Window size: 24
  • Series name: Demand
  • Exogenous included: True
  • Weight function included: False
  • Differentiation order: None
  • Creation date: 2025-05-14 22:16:59
  • Last fit date: 2025-05-14 22:16:59
  • Skforecast version: 0.16.0
  • Python version: 3.12.9
  • Forecaster id: None
Exogenous Variables
    Temperature, day_of_week, month
Data Transformations
  • Transformer for y: None
  • Transformer for exog: None
Training Information
  • Training range: [Timestamp('2011-12-31 00:00:00'), Timestamp('2014-12-01 00:00:00')]
  • Training index type: DatetimeIndex
  • Training index frequency: D
Regressor Parameters
    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0, 'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1, 'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0, 'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None, 'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0, 'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1}
Fit Kwargs
    {}

🛈 API Reference    🗎 User Guide

Importancia de predictores específica de los modelos

La importancia de los predictores en modelos de machine learning determina la relevancia de cada predictor (o variable) en la predicción de un modelo. En otras palabras, mide cuánto contribuye cada predictor al resultado del modelo.

La importancia de los predictores puede utilizarse para varios fines, como identificar aquellos más relevantes para una predicción determinada, comprender el comportamiento de un modelo y seleccionar el mejor conjunto de predictores para una tarea determinada. También puede ayudar a identificar posibles sesgos o errores en los datos utilizados para entrenar el modelo. Es importante señalar que la importancia de un predictor no es una medida definitiva de causalidad. El hecho de que una característica se identifique como importante no significa necesariamente que haya causado el resultado. También pueden intervenir otros factores, como las variables de confusión.

El método utilizado para calcular la importancia de los predictores puede variar en función del tipo de modelo de machine learning que se utilice. Los distintos modelos pueden tener distintos supuestos y características que afecten al cálculo de la importancia. Por ejemplo, los modelos basados en árboles de decisión, como Random Forest y Gradient Boosting, suelen utilizar métodos que miden la disminución de impurezas o el impacto de las permutaciones. Los modelos de regresión lineal suelen utilizar los coeficientes. La magnitud del coeficiente refleja la magnitud y la dirección de la relación entre el predictor y la variable objetivo.

La importancia de los predictores incluidos en un forecaster se puede obtener utilizando el método get_feature_importances(). Este método accede a los atributos coef_ y feature_importances_ del regresor interno.

Warning

El método `get_feature_importances()` solo devolverá valores si el regresor del forecaster tiene el atributo `coef_` o `feature_importances_`, que es el nombre por defecto en scikit-learn.
# Extraer importancia de los predictores
# ==============================================================================
importance = forecaster.get_feature_importances()
importance
feature importance
8 Temperature 568
0 lag_1 426
1 lag_2 291
6 lag_7 248
4 lag_5 243
2 lag_3 236
7 roll_mean_24 227
10 month 224
5 lag_6 200
3 lag_4 177
9 day_of_week 160

Valores SHAP (SHapley Additive exPlanations)

SHAP (SHapley Additive exPlanations) es un método ampliamente adoptado para explicar modelos de machine learning. Proporciona tanto información visual como cuantitativa sobre cómo las variables predictoras influyen en el modelo. Los valores SHAP cumplen dos propósitos principales:

  • Interpretabilidad global: Los valores SHAP permiten cuantificar cómo influye cada variable en el modelo durante su entrenamiento. Al promediar los valores SHAP en todo el conjunto de datos, se pueden ordenar las variables según su importancia general y obtener una visión del proceso de toma de decisiones del modelo.

  • Interpretabilidad local: Los valores SHAP también explican predicciones individuales indicando cuánto contribuye cada variable a una salida específica. Esto permite desglosar predicciones individuales para entender el papel que desempeñó cada variable en el resultado.

Se pueden generar explicaciones con valores SHAP para modelos de skforecast utilizando dos componentes:

  • El regresor interno del forecaster, accesible mediante forecaster.regressor.

  • Las matrices internas utilizadas para el ajuste, backtesting y predicción del modelo. Estas matrices son accesibles a través del método create_predict_X() y estableciendo el argumento return_predictors=True en el método backtesting_forecaster().

Al aprovechar estos elementos, los usuarios pueden generar explicaciones claras e interpretables para sus modelos de forecasting. Estas explicaciones pueden utilizarse para evaluar la fiabilidad del modelo, identificar las variables más influyentes y comprender su impacto en las predicciones.

Shap: importancia global de los predictores

Al promediar los valores SHAP en el conjunto de datos utilizado para entrenar el modelo, es posible obtener una estimación de la contribución (tanto en magnitud como en dirección) de cada predictor en el modelo. Cuanto mayor sea el valor absoluto del valor SHAP, mayor será su importancia. El signo del valor SHAP indica si la característica tiene un impacto positivo o negativo en la predicción.

Primero, se crean las matrices de entrenamiento utilizadas para ajustar el modelo con el método create_train_X_y().

# Matrices de entrenamiento usadas por el forecaster para ajustar el regresor interno
# ==============================================================================
X_train, y_train = forecaster.create_train_X_y(
                       y    = data_train['Demand'],
                       exog = data_train[exog_features],
                   )

display(X_train.head(3))
lag_1 lag_2 lag_3 lag_4 lag_5 lag_6 lag_7 roll_mean_24 Temperature day_of_week month
Time
2012-01-24 280188.298774 239810.374218 207949.859910 225035.325476 240187.677944 247722.494256 292458.685446 222658.202570 26.611458 1.0 1.0
2012-01-25 287474.816646 280188.298774 239810.374218 207949.859910 225035.325476 240187.677944 247722.494256 231197.497184 19.759375 2.0 1.0
2012-01-26 239083.684380 287474.816646 280188.298774 239810.374218 207949.859910 225035.325476 240187.677944 231668.556646 20.038542 3.0 1.0

El método shap_values() se la librería shap se utiliza para calcular los valores SHAP del conjunto de datos de entrenamiento. Si el conjunto de datos es grande, se recomienda utilizar solo una muestra aleatoria.

# Crear un objeto explainer de SHAP (para modelos basados en árboles)
# ==============================================================================
explainer = shap.TreeExplainer(forecaster.regressor)

# Muestreo del 50% de los datos para acelerar el cálculo
rng = np.random.default_rng(seed=785412)
sample = rng.choice(X_train.index, size=int(len(X_train)*0.5), replace=False)
X_train_sample = X_train.loc[sample, :]
shap_values = explainer.shap_values(X_train_sample)

✎ Note

La librería Shap tiene varios explainers, cada uno diseñado para un tipo de modelo diferente. El explainer shap.TreeExplainer se utiliza para modelos basados en árboles, como el LGBMRegressor utilizado en este ejemplo. Para obtener más información, consulte la documentación de SHAP.

Una vez calculados los valores SHAP, se pueden generar varios gráficos para visualizar los resultados.

SHAP Summary Plot

El SHAP summary plot muestra la contribución de cada variable a la predicción del modelo en para varias observaciones. Muestra cuánto contribuye cada variable a alejar la predicción del modelo de un valor base (a menudo la predicción media del modelo). Al examinar un SHAP summary plot, se pueden obtener información sobre qué variables tienen un impacto más significativo en las predicciones, si influyen positiva o negativamente en el resultado y cómo contribuyen los diferentes valores de las variables a predicciones específicas.

# Shap summary plot (top 10)
# ==============================================================================
shap.initjs()
shap.summary_plot(shap_values, X_train_sample, max_display=10, show=False)
fig, ax = plt.gcf(), plt.gca()
ax.set_title("SHAP Summary plot")
ax.tick_params(labelsize=8)
fig.set_size_inches(6, 3)
shap.summary_plot(shap_values, X_train, plot_type="bar", plot_size=(6, 3))

Gráfico de dependencia SHAP

Los gráficos de dependencia SHAP son visualizaciones utilizadas para entender la relación entre una variable y la salida del modelo. Para ello muestran cómo, el valor de una única variable, afecta a las predicciones realizadas por el modelo teniendo en cuenta las interacciones con otras variables. Estos gráficos son especialmente útiles para examinar cómo una determinada variable afecta a las predicciones del modelo en todo su rango de valores.

# Gráfico de dependencia para la variable Temperature
# ==============================================================================
fig, ax = plt.subplots(figsize=(6, 3))
shap.dependence_plot("Temperature", shap_values, X_train_sample, ax=ax)

SHAP: explicación de predicciones individuales

Los valores SHAP no solo permiten interpretar el comportamiento general del modelo (Interpretabilidad Global), sino que también sirven para analizar predicciones individuales (Interpretabilidad Local). Esto resulta especialmente útil cuando se desea entender por qué el modelo realizó una predicción específica para un caso concreto.

Para llevar a cabo este análisis, es necesario acceder a los valores de los predictores — lags y variables exógenas — en el momento de la predicción. Esto se puede lograr utilizando el método create_predict_X o activando el argumento return_predictors=True en la función backtesting_forecaster.

SHAP values para los resultados de predict()

Supongamos que el modelo de pronóstico se utiliza para predecir los próximos 30 valores de la serie, y se desea explicar una predicción específica correspondiente a la fecha '2014-12-28'.

# Forecasting de los próximos 30 días
# ==============================================================================
set_dark_theme()
predictions = forecaster.predict(steps=30, exog=data_test[exog_features])
fig, ax = plt.subplots(figsize=(6, 2.5))
data_test['Demand'].plot(ax=ax, label='Test')
predictions.plot(ax=ax, label='Predictions', linestyle='--')
ax.set_xlabel(None)
ax.legend();

El método create_predict_X se utiliza para crear la matriz de entrada que el método predict usa internamente. Esta matriz se emplea posteriormente para generar los valores SHAP correspondientes a los valores predichos.

# Crear la matrixx de entrada utilizada para predecir los próximos 30 días
# ==============================================================================
X_predict = forecaster.create_predict_X(steps=30, exog=data_test[exog_features])
X_predict.head(3)
lag_1 lag_2 lag_3 lag_4 lag_5 lag_6 lag_7 roll_mean_24 Temperature day_of_week month
2014-12-02 237812.592388 234970.336660 189653.758108 202017.012448 214602.854760 218321.456402 214318.765210 211369.709659 19.833333 1.0 12.0
2014-12-03 230878.900870 237812.592388 234970.336660 189653.758108 202017.012448 214602.854760 218321.456402 212777.981610 19.616667 2.0 12.0
2014-12-04 230782.656189 230878.900870 237812.592388 234970.336660 189653.758108 202017.012448 214602.854760 214485.198829 21.702083 3.0 12.0
# SHAP values for the predictions
# ==============================================================================
shap_values = explainer.shap_values(X_predict)
# Waterfall plot for a single prediction
# ==============================================================================
predicted_date = '2014-12-28'
iloc_predicted_date = X_predict.index.get_loc(predicted_date)
shap_values_single = explainer(X_predict)
shap.plots.waterfall(shap_values_single[iloc_predicted_date], show=False)
fig, ax = plt.gcf(), plt.gca()
fig.set_size_inches(6, 3.5)
ax_list = fig.axes
ax = ax_list[0]
ax.tick_params(labelsize=10)
ax.set
plt.show()

El gráfico waterfall (cascada) muestra cómo los diferentes predictores influenciaron la predicción del modelo hacia arriba (en rojo) o hacia abajo (en azul), en relación con la predicción promedio del modelo.

  • lag_1 tuvo el mayor impacto negativo, reduciendo la predicción en más de 22,000 unidades.

  • Temperature contribuyó de forma positiva, aumentando la predicción en aproximadamente 7,685 unidades.

  • Otras predictores como day_of_week, month y varios valores de lag también influyeron en la predicción, aunque en menor medida.

La predicción del modelo (f(x)) fue de 200,849.86, mientras que el valor promedio esperado (E[f(x)]) en todas las predicciones del modelo es de 224,358.59. Esto significa que los valores específicos de entrada para esta predicción llevaron al modelo a prever un valor inferior al promedio, debido principalmente al fuerte impacto negativo de lag_1.

Las mismas conclusiones se pueden obtener utilizando el método shap.force_plot.

# Forceplot for a single prediction 
# ==============================================================================
shap.force_plot(
    base_value  = explainer.expected_value,
    shap_values = shap_values_single.values[iloc_predicted_date],
    features    = X_predict.iloc[iloc_predicted_date, :]
)
1.844e+51.944e+52.044e+52.144e+52.244e+52.344e+52.444e+52.544e+52.644e+5lag_2 = 2.039e+5Temperature = 24.54lag_1 = 1.817e+5day_of_week = 6lag_7 = 2.063e+5month = 12lag_4 = 2.184e+5base value200,849.86200,849.86higherf(x)lower
# Force plot for the 30 predictions
# ==============================================================================
shap.force_plot(
    base_value  = explainer.expected_value,
    shap_values = shap_values,
    features    = X_predict
)
02468101214161820222426281.744e+51.844e+51.944e+52.044e+52.144e+52.244e+52.344e+52.444e+52.544e+52.644e+52.744e+5

SHAP values para los resultados de backtesting_forecaster()

El análisis de predicciones individuales usando valores SHAP también puede aplicarse a las predicciones realizadas durante un proceso de backtesting. Para ello, se debe establecer el argumento return_predictors=True en el método backtesting_forecaster. Esto deveulve un DataFrame con el valor predicho (pred), la partición a la que pertenece (fold),y los valores de los lags y las variables exógenas utilizados para cada predicción.

En este escenario, se emplea un proceso de backtesting para entrenar el modelo utilizando datos hasta '2014-12-01 23:59:00'. Luego, el modelo genera predicciones en folds de 24 días. Posteriormente, se calculan los valores SHAP para la predicción correspondiente a la fecha '2014-12-16'.

# Backtesting devolviendo los predictores
# ==============================================================================
cv = TimeSeriesFold(steps= 24, initial_train_size = len(data.loc[:'2014-12-01 23:59:00']))
_, predictions = backtesting_forecaster(
                        forecaster        = forecaster,
                        y                 = data['Demand'],
                        exog              = data[exog_features],
                        cv                = cv,
                        metric            = 'mean_absolute_error',
                        return_predictors = True,
                )
predictions.head(3)
  0%|          | 0/2 [00:00<?, ?it/s]
pred fold lag_1 lag_2 lag_3 lag_4 lag_5 lag_6 lag_7 roll_mean_24 Temperature day_of_week month
2014-12-02 230878.900870 0 237812.592388 234970.336660 189653.758108 202017.012448 214602.854760 218321.456402 214318.765210 211369.709659 19.833333 1.0 12.0
2014-12-03 230782.656189 0 230878.900870 237812.592388 234970.336660 189653.758108 202017.012448 214602.854760 218321.456402 212777.981610 19.616667 2.0 12.0
2014-12-04 237992.220195 0 230782.656189 230878.900870 237812.592388 234970.336660 189653.758108 202017.012448 214602.854760 214485.198829 21.702083 3.0 12.0
# Waterfall para una predicción concreta generada en el backtesting
# ==============================================================================
predictions = predictions.astype(data[exog_features].dtypes) # Asegurar que los tipos son iguales
iloc_predicted_date = predictions.index.get_loc('2014-12-16')
shap_values_single = explainer(predictions.iloc[:, 2:])
shap.plots.waterfall(shap_values_single[iloc_predicted_date], show=False)
fig, ax = plt.gcf(), plt.gca()
fig.set_size_inches(6, 3.5)
ax_list = fig.axes
ax = ax_list[0]
ax.tick_params(labelsize=8)
ax.set
plt.show()

Scikit-learn gráficos de dependencia parcial

Scikit-learn permite crear gráficos de dependencia parcial utilizando la función plot_partial_dependence. Esta función visualiza el efecto de una o dos variables en el resultado predicho, marginalizando el efecto de todas las demás características. Estos gráficos proporcionan información sobre cómo influyen las variables seleccionadas en las predicciones del modelo y pueden ayudar a identificar relaciones no lineales o interacciones entre variables.

Una descripción más detallada sobre gráficos de dependencia parcial se puede encontrar en la Guía de Usuario de Scikitlearn.

# Scikit-learn gráfico de dependencia parcial
# ==============================================================================
fig, ax = plt.subplots(figsize=(8, 3))
pd.plots = PartialDependenceDisplay.from_estimator(
    estimator = forecaster.regressor,
    X         = X_train,
    features  = ["Temperature", "lag_1"],
    kind      = 'both',
    ax        = ax,
)
ax.set_title("Partial Dependence Plot")
fig.tight_layout()
plt.show()

Información de sesión

import session_info
session_info.show(html=False)
-----
lightgbm            4.6.0
matplotlib          3.10.1
numpy               2.2.5
pandas              2.2.3
session_info        v1.0.1
shap                0.47.2
skforecast          0.16.0
sklearn             1.6.1
-----
IPython             9.1.0
jupyter_client      8.6.3
jupyter_core        5.7.2
notebook            6.5.7
-----
Python 3.12.9 | packaged by Anaconda, Inc. | (main, Feb  6 2025, 18:56:27) [GCC 11.2.0]
Linux-6.11.0-25-generic-x86_64-with-glibc2.39
-----
Session information updated at 2025-05-14 22:17

Instrucciones para citar

¿Cómo citar este documento?

Si utilizas este documento o alguna parte de él, te agradecemos que lo cites. ¡Muchas gracias!

Modelos de forecasting interpretables por Joaquín Amat Rodrigo y Javier Escobar Ortiz, disponible bajo una licencia Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 DEED) en https://www.cienciadedatos.net/documentos/py57-modelos-forecasting-interpretables.html

¿Cómo citar skforecast?

Si utilizas skforecast, te agradeceríamos mucho que lo cites. ¡Muchas gracias!

Zenodo:

Amat Rodrigo, Joaquin, & Escobar Ortiz, Javier. (2025). skforecast (v0.16.0). Zenodo. https://doi.org/10.5281/zenodo.8382788

APA:

Amat Rodrigo, J., & Escobar Ortiz, J. (2025). skforecast (Version 0.16.0) [Computer software]. https://doi.org/10.5281/zenodo.8382788

BibTeX:

@software{skforecast, author = {Amat Rodrigo, Joaquin and Escobar Ortiz, Javier}, title = {skforecast}, version = {0.16.0}, month = {05}, year = {2025}, license = {BSD-3-Clause}, url = {https://skforecast.org/}, doi = {10.5281/zenodo.8382788} }

¿Te ha gustado el artículo? Tu ayuda es importante

Tu contribución me ayudará a seguir generando contenido divulgativo gratuito. ¡Muchísimas gracias! 😊

Become a GitHub Sponsor Become a GitHub Sponsor

Creative Commons Licence

Este documento creado por Joaquín Amat Rodrigo y Javier Escobar Ortiz tiene licencia Attribution-NonCommercial-ShareAlike 4.0 International.

Se permite:

  • Compartir: copiar y redistribuir el material en cualquier medio o formato.

  • Adaptar: remezclar, transformar y crear a partir del material.

Bajo los siguientes términos:

  • Atribución: Debes otorgar el crédito adecuado, proporcionar un enlace a la licencia e indicar si se realizaron cambios. Puedes hacerlo de cualquier manera razonable, pero no de una forma que sugiera que el licenciante te respalda o respalda tu uso.

  • No-Comercial: No puedes utilizar el material para fines comerciales.

  • Compartir-Igual: Si remezclas, transformas o creas a partir del material, debes distribuir tus contribuciones bajo la misma licencia que el original.