

 O Amazon Redshift não permitirá mais a criação de UDFs do Python a partir do Patch 198. As UDFs do Python existentes continuarão a funcionar normalmente até 30 de junho de 2026. Para ter mais informações, consulte a [publicação de blog ](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

# Tutorial: Como criar modelos de regressão
<a name="tutorial_regression"></a>

Neste tutorial, você usa o Amazon Redshift ML para criar um modelo de regressão de machine learning e executar consultas de previsão no modelo. Os modelos de regressão permitem prever resultados numéricos, como o preço de uma casa ou quantas pessoas usarão o serviço de aluguel de bicicletas em uma cidade. Você usa o comando CREATE MODEL no Amazon Redshift com os dados de treinamento. Em seguida, o Amazon Redshift ML compila o modelo, importa o modelo treinado para o Redshift e prepara uma função de previsão SQL. Você pode usar a função de previsão em consultas SQL no Amazon Redshift.

Neste tutorial, você usará o Amazon Redshift ML para criar um modelo de regressão que prevê o número de pessoas que usam o serviço de compartilhamento de bicicletas da cidade de Toronto a qualquer hora do dia. As entradas para o modelo incluem feriados e condições climáticas. Você usará um modelo de regressão porque deseja um resultado numérico para esse problema.

Você pode usar o comando CREATE MODEL para exportar dados de treinamento, treinar e importar o modelo e disponibilizá-lo no Amazon Redshift como uma função SQL. Use a operação CREATE MODEL para especificar dados de treinamento como uma tabela ou instrução SELECT.

## Exemplos de casos de uso
<a name="tutorial_regression_tasks"></a>

Você pode resolver outros problemas de regressão com o Amazon Redshift ML, como prever o valor da vida útil de um cliente. Você também pode usar o Redshift ML para prever o preço mais lucrativo e a receita resultante de um produto.

**Tarefas**
+ Pré-requisitos
+ Etapa 1: Carregar dados do Amazon S3 para o Amazon Redshift
+ Etapa 2: Criar o modelo de machine learning
+ Etapa 3: Validar o modelo

## Pré-requisitos
<a name="tutorial_regression_prereqs"></a>

Para finalizar este tutorial, você deve concluir a [configuração administrativa](https://docs.aws.amazon.com/redshift/latest/dg/admin-setup.html) do Amazon Redshift ML.

## Etapa 1: Carregar dados do Amazon S3 para o Amazon Redshift
<a name="tutorial_regression_step_load"></a>

Use o [editor de consultas v2 do Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/query-editor-v2-using.html) para executar as consultas a seguir.

1. Você deve criar três tabelas para carregar os três conjuntos de dados públicos no Amazon Redshift. Os conjuntos de dados são [Toronto Bike Ridership Data](https://open.toronto.ca/dataset/bike-share-toronto-ridership-data/) (Dados sobre usuários de bicicleta em Toronto), [historical weather data](https://climate.weather.gc.ca/historical_data/search_historic_data_e.html) (dados climáticos históricos) e [historical holidays data](https://github.com/uWaterloo/Datasets/blob/master/Holidays/holidays.csv) (dados históricos de feriados). Execute a consulta a seguir no editor de consultas do Amazon Redshift para criar tabelas com os nomes `ridership`, `weather` e `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));
   ```

1. A consulta a seguir carrega os dados de exemplo nas tabelas que você criou na etapa anterior.

   ```
   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;
   ```

1. A consulta a seguir executa transformações nos conjuntos de dados `ridership` e `weather` para remover vieses ou anomalias. A remoção de vieses e anomalias resulta em melhor precisão do modelo. A consulta simplifica as tabelas criando duas novas visualizações chamadas `ridership_view` e `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;
   ```

1. A consulta a seguir cria uma tabela que combina todos os atributos de entrada relevantes de `ridership_view` e de `weather_view` na tabela `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);
   ```

### Visualizar os dados de exemplo (opcional)
<a name="tutorial_regression_view_data"></a>

A consulta a seguir mostra as entradas da tabela. Você pode executar essa operação para garantir se a tabela foi feita corretamente.

```
SELECT * 
FROM trip_data 
LIMIT 5;
```

Veja a seguir um exemplo de saída da operação anterior.

```
+---------------------+------------+-----------+----------+------------+-----------+--------------+-----------------+---------------+--------+------------------+------------+---------------+
|      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 |
+---------------------+------------+-----------+----------+------------+-----------+--------------+-----------------+---------------+--------+------------------+------------+---------------+
```

### Mostrar a correlação entre atributos (opcional)
<a name="tutorial_regression_show_correlation"></a>

Determinar a correlação ajuda a medir a consistência da associação entre os atributos. O nível de associação pode ajudar você a determinar o que afeta o resultado pretendido. Neste tutorial, o resultado pretendido é `trip_count`.

A consulta a seguir cria ou substitui o procedimento `sp_correlation`. Use o procedimento armazenado, denominado `sp_correlation`, para mostrar a correlação entre um atributo e outros atributos em uma tabela no 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;
```

A consulta a seguir mostra a correlação entre a coluna de destino, `trip_count`, e outros atributos numéricos em nosso conjunto de dados.

```
call sp_correlation(
    'public',
    'trip_data',
    'trip_count',
    'tmp_corr_table'
);

SELECT
    *
FROM
    tmp_corr_table;
```

Veja a seguir um exemplo de saída da operação anterior `sp_correlation`.

```
+------------+-----------+----------+------------+-----------+--------------+-----------------+---------------+--------+------------------+------------+---------------+
| 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 |
+------------+-----------+----------+------------+-----------+--------------+-----------------+---------------+--------+------------------+------------+---------------+
```

## Etapa 2: Criar o modelo de machine learning
<a name="tutorial_regression_create_model"></a>

1. A consulta a seguir divide os dados em um conjunto de treinamento e um conjunto de validação, designando 80% do conjunto de dados para treinamento e 20% para validação. O conjunto de treinamento é a entrada para o modelo de ML que visa identificar o melhor algoritmo possível para o modelo. Depois que o modelo é criado, o conjunto de validação é usado para validar a precisão do modelo.

   ```
   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
       );
   ```

1. A consulta a seguir cria um modelo de regressão para prever o valor `trip_count` referente a qualquer data e hora de entrada. No exemplo a seguir, substitua amzn-s3-demo-bucket por seu próprio bucket do 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
       );
   ```

## Etapa 3: Validar o modelo
<a name="tutorial_regression_step_validate"></a>

1. Use a consulta a seguir para gerar aspectos do modelo e encontrar a métrica de erro quadrático médio na saída. O erro quadrático médio é uma métrica de precisão típica para problemas de regressão.

   ```
   show model predict_rental_count;
   ```

1. Execute as consultas de previsão a seguir em relação aos dados de validação para comparar a contagem prevista com a contagem real de viagens.

   ```
   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;
   ```

1. A consulta a seguir calcula o erro quadrático médio e o erro quadrático médio da raiz com base nos dados de validação. O erro quadrático médio e o erro quadrático médio da raiz são usados para medir a distância entre o destino numérico previsto e a resposta numérica real. Um bom modelo tem uma pontuação baixa em ambas as métricas. A consulta a seguir retorna o valor de ambas as métricas.

   ```
   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
       );
   ```

1. A consulta a seguir calcula o erro percentual na contagem de viagens para cada tempo de viagem em 1.º/1/2017. A consulta ordena os tempos de viagem desde o momento com o menor erro percentual até o tempo com o erro percentual mais alto.

   ```
   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;
   ```

## Tópicos relacionados
<a name="tutorial_regression_related_topics"></a>

Para obter mais informações sobre o Amazon Redshift ML, consulte a seguinte documentação:
+ [Custos para usar o ML do Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/dg/cost.html)
+ [Operação CREATE MODEL](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_MODEL.html)
+ [Função EXPLAIN\$1MODEL](https://docs.aws.amazon.com/redshift/latest/dg/r_explain_model_function.html)

Para obter mais informações sobre machine learning, consulte a seguinte documentação:
+ [Visão geral do Machine Learning](https://docs.aws.amazon.com/redshift/latest/dg/machine_learning_overview.html)
+ [Machine Learning para iniciantes e especialistas](https://docs.aws.amazon.com/redshift/latest/dg/novice_expert.html)
+ [What Is Fairness and Model Explainability for Machine Learning Predictions? (O que é equidade e explicabilidade de modelo para previsões de machine learning?](https://docs.aws.amazon.com/sagemaker/latest/dg/clarify-fairness-and-explainability.html)