Tutoriel : Création de modèles de régression - Amazon Redshift

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Tutoriel : Création de modèles de régression

Dans ce tutoriel, vous utilisez Amazon Redshift ML pour créer un modèle de régression de machine learning et exécuter des requêtes de prédiction sur le modèle. Les modèles de régression vous permettent de prédire des résultats numériques, tels que le prix d'une maison ou le nombre de personnes qui utiliseront le service de location de vélos d'une ville. Vous utilisez la CREATE MODEL commande dans Amazon Redshift avec vos données d'entraînement. Amazon Redshift ML compile ensuite le modèle, importe le modèle entraîné dans Redshift et prépare une fonction de prédiction. SQL Vous pouvez utiliser la fonction de prédiction dans les SQL requêtes dans Amazon Redshift.

Dans ce tutoriel, vous allez utiliser Amazon Redshift ML pour créer un modèle de régression qui prédira le nombre de personnes qui utilisent le service de vélos en libre-service de la ville de Toronto à une heure donnée de la journée. Les entrées du modèle incluent les jours fériés et les conditions météorologiques. Vous allez utiliser un modèle de régression, car vous souhaitez obtenir un résultat numérique pour ce problème.

Vous pouvez utiliser la CREATE MODEL commande pour exporter des données d'entraînement, entraîner un modèle et le rendre disponible dans Amazon Redshift en tant SQL que fonction. Utilisez cette CREATE MODEL opération pour spécifier les données d'entraînement sous forme de tableau ou d'SELECTinstruction.

Exemples de cas d'utilisation

Vous pouvez résoudre d'autres problèmes de régression avec Amazon Redshift ML, tels que la prédiction de la valeur à vie d'un client. Vous pouvez également utiliser Redshift ML pour prédire le prix le plus rentable et le chiffre d'affaires qui en résulte pour un produit.

Tâches

  • Prérequis

  • Étape 1 : charger les données d'Amazon S3 dans Amazon Redshift

  • Étape 2 : Créer le modèle de machine learning

  • Étape 3 : valider le modèle

Prérequis

Pour effectuer ce tutoriel, vous devez suivre la procédure Configuration administrative pour Amazon Redshift ML.

Étape 1 : charger les données d'Amazon S3 dans Amazon Redshift

Utilisez l'éditeur de requête v2 Amazon Redshift pour exécuter les requêtes suivantes.

  1. Vous devez créer trois tables pour charger les trois jeux de données publics dans Amazon Redshift. Les jeux de données sont Bike Share Toronto Ridership Data, Données climatiques historiques et Données historiques des jours fériés. Exécutez la requête suivante dans l'éditeur de requête Amazon Redshift pour créer des tables nommées ridership, weather et holiday.

    CREATE TABLE IF NOT EXISTS ridership ( trip_id INT, trip_duration_seconds INT, trip_start_time timestamp, trip_stop_time timestamp, from_station_name VARCHAR(50), to_station_name VARCHAR(50), from_station_id SMALLINT, to_station_id SMALLINT, user_type VARCHAR(20) ); CREATE TABLE IF NOT EXISTS weather ( longitude_x DECIMAL(5, 2), latitude_y DECIMAL(5, 2), station_name VARCHAR(20), climate_id BIGINT, datetime_utc TIMESTAMP, weather_year SMALLINT, weather_month SMALLINT, weather_day SMALLINT, time_utc VARCHAR(5), temp_c DECIMAL(5, 2), temp_flag VARCHAR(1), dew_point_temp_c DECIMAL(5, 2), dew_point_temp_flag VARCHAR(1), rel_hum SMALLINT, rel_hum_flag VARCHAR(1), precip_amount_mm DECIMAL(5, 2), precip_amount_flag VARCHAR(1), wind_dir_10s_deg VARCHAR(10), wind_dir_flag VARCHAR(1), wind_spd_kmh VARCHAR(10), wind_spd_flag VARCHAR(1), visibility_km VARCHAR(10), visibility_flag VARCHAR(1), stn_press_kpa DECIMAL(5, 2), stn_press_flag VARCHAR(1), hmdx SMALLINT, hmdx_flag VARCHAR(1), wind_chill VARCHAR(10), wind_chill_flag VARCHAR(1), weather VARCHAR(10) ); CREATE TABLE IF NOT EXISTS holiday (holiday_date DATE, description VARCHAR(100));
  2. La requête suivante charge les données d'exemple dans les tables que vous avez créées à l'étape précédente.

    COPY ridership FROM 's3://redshift-ml-bikesharing-data/bike-sharing-data/ridership/' IAM_ROLE default FORMAT CSV IGNOREHEADER 1 DATEFORMAT 'auto' TIMEFORMAT 'auto' REGION 'us-west-2' gzip; COPY weather FROM 's3://redshift-ml-bikesharing-data/bike-sharing-data/weather/' IAM_ROLE default FORMAT csv IGNOREHEADER 1 DATEFORMAT 'auto' TIMEFORMAT 'auto' REGION 'us-west-2' gzip; COPY holiday FROM 's3://redshift-ml-bikesharing-data/bike-sharing-data/holiday/' IAM_ROLE default FORMAT csv IGNOREHEADER 1 DATEFORMAT 'auto' TIMEFORMAT 'auto' REGION 'us-west-2' gzip;
  3. La requête suivante effectue des transformations sur les jeux de données ridership et weather pour éliminer les biais ou les anomalies. La suppression des biais et des anomalies améliore la précision du modèle. La requête simplifie les tables en créant deux nouvelles vues appelées ridership_view et weather_view.

    CREATE OR REPLACE VIEW ridership_view AS SELECT trip_time, trip_count, TO_CHAR(trip_time, 'hh24') :: INT trip_hour, TO_CHAR(trip_time, 'dd') :: INT trip_day, TO_CHAR(trip_time, 'mm') :: INT trip_month, TO_CHAR(trip_time, 'yy') :: INT trip_year, TO_CHAR(trip_time, 'q') :: INT trip_quarter, TO_CHAR(trip_time, 'w') :: INT trip_month_week, TO_CHAR(trip_time, 'd') :: INT trip_week_day FROM ( SELECT CASE WHEN TRUNC(r.trip_start_time) < '2017-07-01' :: DATE THEN CONVERT_TIMEZONE( 'US/Eastern', DATE_TRUNC('hour', r.trip_start_time) ) ELSE DATE_TRUNC('hour', r.trip_start_time) END trip_time, COUNT(1) trip_count FROM ridership r WHERE r.trip_duration_seconds BETWEEN 60 AND 60 * 60 * 24 GROUP BY 1 ); CREATE OR REPLACE VIEW weather_view AS SELECT CONVERT_TIMEZONE( 'US/Eastern', DATE_TRUNC('hour', datetime_utc) ) daytime, ROUND(AVG(temp_c)) temp_c, ROUND(AVG(precip_amount_mm)) precip_amount_mm FROM weather GROUP BY 1;
  4. La requête suivante crée une table qui combine tous les attributs d'entrée pertinents de ridership_view et weather_view dans la table trip_data.

    CREATE TABLE trip_data AS SELECT r.trip_time, r.trip_count, r.trip_hour, r.trip_day, r.trip_month, r.trip_year, r.trip_quarter, r.trip_month_week, r.trip_week_day, w.temp_c, w.precip_amount_mm,CASE WHEN h.holiday_date IS NOT NULL THEN 1 WHEN TO_CHAR(r.trip_time, 'D') :: INT IN (1, 7) THEN 1 ELSE 0 END is_holiday, ROW_NUMBER() OVER ( ORDER BY RANDOM() ) serial_number FROM ridership_view r JOIN weather_view w ON (r.trip_time = w.daytime) LEFT OUTER JOIN holiday h ON (TRUNC(r.trip_time) = h.holiday_date);

Afficher les données d'exemple (facultatif)

La requête suivante montre les entrées de la table. Vous pouvez exécuter cette opération pour vous assurer que la table a été créée correctement.

SELECT * FROM trip_data LIMIT 5;

Voici un exemple de la sortie de l'opération précédente.

+---------------------+------------+-----------+----------+------------+-----------+--------------+-----------------+---------------+--------+------------------+------------+---------------+ | trip_time | trip_count | trip_hour | trip_day | trip_month | trip_year | trip_quarter | trip_month_week | trip_week_day | temp_c | precip_amount_mm | is_holiday | serial_number | +---------------------+------------+-----------+----------+------------+-----------+--------------+-----------------+---------------+--------+------------------+------------+---------------+ | 2017-03-21 22:00:00 | 47 | 22 | 21 | 3 | 17 | 1 | 3 | 3 | 1 | 0 | 0 | 1 | | 2018-05-04 01:00:00 | 19 | 1 | 4 | 5 | 18 | 2 | 1 | 6 | 12 | 0 | 0 | 3 | | 2018-01-11 10:00:00 | 93 | 10 | 11 | 1 | 18 | 1 | 2 | 5 | 9 | 0 | 0 | 5 | | 2017-10-28 04:00:00 | 20 | 4 | 28 | 10 | 17 | 4 | 4 | 7 | 11 | 0 | 1 | 7 | | 2017-12-31 21:00:00 | 11 | 21 | 31 | 12 | 17 | 4 | 5 | 1 | -15 | 0 | 1 | 9 | +---------------------+------------+-----------+----------+------------+-----------+--------------+-----------------+---------------+--------+------------------+------------+---------------+

Montrer la corrélation entre les attributs (facultatif)

La détermination de la corrélation vous aide à mesurer la force de l'association entre les attributs. Le niveau d'association peut vous aider à déterminer ce qui affecte votre résultat cible. Dans ce tutoriel, le résultat cible est trip_count.

La requête suivante crée ou remplace la procédure sp_correlation. Vous utilisez la procédure stockée appelée sp_correlation pour montrer la corrélation entre un attribut et d'autres attributs d'une table dans Amazon Redshift.

CREATE OR REPLACE PROCEDURE sp_correlation(source_schema_name in varchar(255), source_table_name in varchar(255), target_column_name in varchar(255), output_temp_table_name inout varchar(255)) AS $$ DECLARE v_sql varchar(max); v_generated_sql varchar(max); v_source_schema_name varchar(255)=lower(source_schema_name); v_source_table_name varchar(255)=lower(source_table_name); v_target_column_name varchar(255)=lower(target_column_name); BEGIN EXECUTE 'DROP TABLE IF EXISTS ' || output_temp_table_name; v_sql = ' SELECT ''CREATE temp table '|| output_temp_table_name||' AS SELECT ''|| outer_calculation|| '' FROM (SELECT COUNT(1) number_of_items, SUM('||v_target_column_name||') sum_target, SUM(POW('||v_target_column_name||',2)) sum_square_target, POW(SUM('||v_target_column_name||'),2) square_sum_target,''|| inner_calculation|| '' FROM (SELECT ''|| column_name|| '' FROM '||v_source_table_name||'))'' FROM ( SELECT DISTINCT LISTAGG(outer_calculation,'','') OVER () outer_calculation ,LISTAGG(inner_calculation,'','') OVER () inner_calculation ,LISTAGG(column_name,'','') OVER () column_name FROM ( SELECT CASE WHEN atttypid=16 THEN ''DECODE(''||column_name||'',true,1,0)'' ELSE column_name END column_name ,atttypid ,''CAST(DECODE(number_of_items * sum_square_''||rn||'' - square_sum_''||rn||'',0,null,(number_of_items*sum_target_''||rn||'' - sum_target * sum_''||rn|| '')/SQRT((number_of_items * sum_square_target - square_sum_target) * (number_of_items * sum_square_''||rn|| '' - square_sum_''||rn||''))) AS numeric(5,2)) ''||column_name outer_calculation ,''sum(''||column_name||'') sum_''||rn||'',''|| ''SUM(trip_count*''||column_name||'') sum_target_''||rn||'',''|| ''SUM(POW(''||column_name||'',2)) sum_square_''||rn||'',''|| ''POW(SUM(''||column_name||''),2) square_sum_''||rn inner_calculation FROM ( SELECT row_number() OVER (order by a.attnum) rn ,a.attname::VARCHAR column_name ,a.atttypid FROM pg_namespace AS n INNER JOIN pg_class AS c ON n.oid = c.relnamespace INNER JOIN pg_attribute AS a ON c.oid = a.attrelid WHERE a.attnum > 0 AND n.nspname = '''||v_source_schema_name||''' AND c.relname = '''||v_source_table_name||''' AND a.atttypid IN (16,20,21,23,700,701,1700) ) ) )'; EXECUTE v_sql INTO v_generated_sql; EXECUTE v_generated_sql; END; $$ LANGUAGE plpgsql;

La requête suivante montre la corrélation entre la colonne cible, trip_count, et d'autres attributs numériques de notre jeu de données.

call sp_correlation( 'public', 'trip_data', 'trip_count', 'tmp_corr_table' ); SELECT * FROM tmp_corr_table;

Voici un exemple de la sortie de l'opération sp_correlation précédente.

+------------+-----------+----------+------------+-----------+--------------+-----------------+---------------+--------+------------------+------------+---------------+ | trip_count | trip_hour | trip_day | trip_month | trip_year | trip_quarter | trip_month_week | trip_week_day | temp_c | precip_amount_mm | is_holiday | serial_number | +------------+-----------+----------+------------+-----------+--------------+-----------------+---------------+--------+------------------+------------+---------------+ | 1 | 0.32 | 0.01 | 0.18 | 0.12 | 0.18 | 0 | 0.02 | 0.53 | -0.07 | -0.13 | 0 | +------------+-----------+----------+------------+-----------+--------------+-----------------+---------------+--------+------------------+------------+---------------+

Étape 2 : Créer le modèle de machine learning

  1. La requête suivante divise vos données en un jeu d'entraînement et un jeu de validation en désignant 80 % du jeu de données pour l'entraînement et 20 % pour la validation. Le jeu d'entraînement est l'entrée du modèle ML utilisée pour identifier le meilleur algorithme possible pour le modèle. Une fois le modèle créé, vous utilisez le jeu de validation pour valider la précision du modèle.

    CREATE TABLE training_data AS SELECT trip_count, trip_hour, trip_day, trip_month, trip_year, trip_quarter, trip_month_week, trip_week_day, temp_c, precip_amount_mm, is_holiday FROM trip_data WHERE serial_number > ( SELECT COUNT(1) * 0.2 FROM trip_data ); CREATE TABLE validation_data AS SELECT trip_count, trip_hour, trip_day, trip_month, trip_year, trip_quarter, trip_month_week, trip_week_day, temp_c, precip_amount_mm, is_holiday, trip_time FROM trip_data WHERE serial_number <= ( SELECT COUNT(1) * 0.2 FROM trip_data );
  2. La requête suivante crée un modèle de régression pour prédire la valeur trip_count pour n'importe quelles date et heure d'entrée. Dans l'exemple suivant, remplacez amzn-s3-demo-bucket par votre propre compartiment S3.

    CREATE MODEL predict_rental_count FROM training_data TARGET trip_count FUNCTION predict_rental_count IAM_ROLE default PROBLEM_TYPE regression OBJECTIVE 'mse' SETTINGS ( s3_bucket 'amzn-s3-demo-bucket', s3_garbage_collect off, max_runtime 5000 );

Étape 3 : valider le modèle

  1. Utilisez la requête suivante pour générer des aspects du modèle et recherchez la métrique d'écart quadratique moyen dans la sortie. L'écart quadratique moyen est une métrique de précision standard des problèmes de régression.

    show model predict_rental_count;
  2. Exécutez les requêtes de prédiction suivantes par rapport aux données de validation pour comparer le nombre prédit de trajets au nombre réel de trajets.

    SELECT trip_time, actual_count, predicted_count, (actual_count - predicted_count) difference FROM ( SELECT trip_time, trip_count AS actual_count, PREDICT_RENTAL_COUNT ( trip_hour, trip_day, trip_month, trip_year, trip_quarter, trip_month_week, trip_week_day, temp_c, precip_amount_mm, is_holiday ) predicted_count FROM validation_data ) LIMIT 5;
  3. La requête suivante calcule l'écart quadratique moyen et l'écart-type en fonction de vos données de validation. Vous utilisez l'écart quadratique moyen et l'écart-type pour mesurer la distance entre la cible numérique prédite et la réponse numérique réelle. Un bon modèle présente un faible score pour les deux métriques. La requête suivante renvoie la valeur des deux métriques.

    SELECT ROUND( AVG(POWER((actual_count - predicted_count), 2)), 2 ) mse, ROUND( SQRT(AVG(POWER((actual_count - predicted_count), 2))), 2 ) rmse FROM ( SELECT trip_time, trip_count AS actual_count, PREDICT_RENTAL_COUNT ( trip_hour, trip_day, trip_month, trip_year, trip_quarter, trip_month_week, trip_week_day, temp_c, precip_amount_mm, is_holiday ) predicted_count FROM validation_data );
  4. La requête suivante calcule le pourcentage d'erreur dans le nombre de trajets pour chaque heure de trajet le 01/01/2017. La requête ordonne les heures de trajet de l'heure avec le pourcentage d'erreur le plus bas jusqu'à l'heure avec le pourcentage d'erreur le plus haut.

    SELECT trip_time, CAST(ABS(((actual_count - predicted_count) / actual_count)) * 100 AS DECIMAL (7,2)) AS pct_error FROM ( SELECT trip_time, trip_count AS actual_count, PREDICT_RENTAL_COUNT ( trip_hour, trip_day, trip_month, trip_year, trip_quarter, trip_month_week, trip_week_day, temp_c, precip_amount_mm, is_holiday ) predicted_count FROM validation_data ) WHERE trip_time LIKE '2017-01-01 %%:%%:%%' ORDER BY 2 ASC;

Pour plus d'informations sur Amazon Redshift ML, consultez la documentation suivante :

Pour plus d'informations sur le machine learning, consultez la documentation suivante :