Calcular o Coeficiente de Determinação (R²) em C

CBeginner
Pratique Agora

Introdução

Neste laboratório, aprenderemos a calcular o Coeficiente de Determinação (R²) em C. O laboratório cobre os seguintes passos:

Primeiro, calcularemos os valores preditos de y usando regressão linear. Criaremos um programa que calcula os valores preditos com base num modelo de regressão linear simples. Em seguida, calcularemos o valor de R² usando as variações explicada e total. Finalmente, imprimiremos o valor de R².

Este laboratório fornece uma abordagem prática para compreender o conceito do Coeficiente de Determinação e sua implementação na programação em C, uma habilidade valiosa para a análise estatística de dados.

Calcular y Preditivo Usando Regressão

Neste passo, aprenderemos a calcular valores preditos de y usando regressão linear em C. Criaremos um programa que calcula os valores preditos com base num modelo de regressão linear simples.

Primeiro, vamos criar um ficheiro C para o nosso cálculo de regressão:

cd ~/project
nano regression_prediction.c

Agora, insira o seguinte código:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// Função para calcular valores preditos de y
void computePredictedY(double *x, double *y, int n, double slope, double intercept, double *predicted_y) {
    for (int i = 0; i < n; i++) {
        predicted_y[i] = slope * x[i] + intercept;
    }
}

int main() {
    // Pontos de dados de amostra
    double x[] = {1.0, 2.0, 3.0, 4.0, 5.0};
    double y[] = {2.0, 4.0, 5.0, 4.0, 5.0};
    int n = sizeof(x) / sizeof(x[0]);

    // Declive e intercepto pré-definidos (para demonstração)
    double slope = 0.6;
    double intercept = 1.5;

    // Array para armazenar valores preditos de y
    double predicted_y[n];

    // Calcular valores preditos de y
    computePredictedY(x, y, n, slope, intercept, predicted_y);

    // Imprimir valores originais e preditos de y
    printf("Valores Originais vs. Preditos de Y:\n");
    for (int i = 0; i < n; i++) {
        printf("X: %.1f, Y Original: %.1f, Y Predito: %.1f\n",
               x[i], y[i], predicted_y[i]);
    }

    return 0;
}

Compile o programa:

gcc -o regression_prediction regression_prediction.c -lm

Execute o programa:

./regression_prediction

Exemplo de saída:

Valores Originais vs. Preditos de Y:
X: 1.0, Y Original: 2.0, Y Predito: 2.1
X: 2.0, Y Original: 4.0, Y Predito: 2.7
X: 3.0, Y Original: 5.0, Y Predito: 3.3
X: 4.0, Y Original: 4.0, Y Predito: 3.9
X: 5.0, Y Original: 5.0, Y Predito: 4.5

Vamos decompor os componentes chave deste código:

  1. A função computePredictedY() calcula os valores preditos de y usando a equação de regressão linear: y = mx + b
  2. Usamos declive (0.6) e intercepto (1.5) pré-definidos para demonstração
  3. O programa imprime os valores originais e preditos de y para comparação

Calcular R² Usando Variação Explicada/Total

Neste passo, estenderemos o nosso programa de regressão anterior para calcular o Coeficiente de Determinação (R²), que mede quão bem o modelo de regressão se ajusta aos dados.

Primeiro, vamos modificar o nosso ficheiro C existente:

cd ~/project
nano r_squared_calculation.c

Introduza o seguinte código completo:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// Função para calcular a média de um array
double calculateMean(double *arr, int n) {
    double sum = 0.0;
    for (int i = 0; i < n; i++) {
        sum += arr[i];
    }
    return sum / n;
}

// Função para calcular R-quadrado
double computeRSquared(double *x, double *y, int n, double slope, double intercept) {
    // Calcular valores preditos de y
    double predicted_y[n];
    double total_variation = 0.0;
    double explained_variation = 0.0;

    // Calcular a média dos valores reais de y
    double y_mean = calculateMean(y, n);

    // Calcular as variações
    for (int i = 0; i < n; i++) {
        // Valor previsto de y
        predicted_y[i] = slope * x[i] + intercept;

        // Variação total (distância da média)
        total_variation += pow(y[i] - y_mean, 2);

        // Variação explicada (distância dos valores preditos aos valores reais)
        explained_variation += pow(y[i] - predicted_y[i], 2);
    }

    // Calcular R-quadrado
    return 1 - (explained_variation / total_variation);
}

int main() {
    // Pontos de dados de amostra
    double x[] = {1.0, 2.0, 3.0, 4.0, 5.0};
    double y[] = {2.0, 4.0, 5.0, 4.0, 5.0};
    int n = sizeof(x) / sizeof(x[0]);

    // Declive e intercepto pré-definidos (para demonstração)
    double slope = 0.6;
    double intercept = 1.5;

    // Calcular e imprimir R-quadrado
    double r_squared = computeRSquared(x, y, n, slope, intercept);

    printf("Resultados da Análise de Regressão:\n");
    printf("Declive: %.2f\n", slope);
    printf("Intercepto: %.2f\n", intercept);
    printf("R-quadrado (R²): %.4f\n", r_squared);

    return 0;
}

Compile o programa:

gcc -o r_squared_calculation r_squared_calculation.c -lm

Execute o programa:

./r_squared_calculation

Exemplo de saída:

Resultados da Análise de Regressão:
Declive: 0.60
Intercepto: 1.50
R-quadrado (R²): 0.5600

Componentes chave do cálculo de R²:

  1. calculateMean() calcula a média de um array
  2. computeRSquared() calcula R² usando a fórmula: 1 - (Variação Explicada / Variação Total)
  3. A Variação Total mede a dispersão dos valores reais de y em torno da sua média
  4. A Variação Explicada mede a dispersão dos valores preditos dos valores reais
  5. R² varia de 0 a 1, com valores mais elevados a indicar um melhor ajuste do modelo

Imprimir o Valor de R²

Neste passo final, criaremos um programa completo que lê dados de um ficheiro, calcula os parâmetros de regressão e imprime o valor de R² com uma interpretação detalhada.

Primeiro, crie um ficheiro de dados de amostra:

cd ~/project
nano regression_data.txt

Adicione dados de regressão de amostra:

1.0 2.0
2.0 4.0
3.0 5.0
4.0 4.0
5.0 5.0

Agora, crie o programa final de cálculo de R²:

nano r_squared_print.c

Introduza o seguinte código:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// Função para calcular os parâmetros de regressão linear
void calculateRegressionParameters(double *x, double *y, int n,
                                   double *slope, double *intercept) {
    double sum_x = 0, sum_y = 0, sum_xy = 0, sum_x_squared = 0;

    for (int i = 0; i < n; i++) {
        sum_x += x[i];
        sum_y += y[i];
        sum_xy += x[i] * y[i];
        sum_x_squared += x[i] * x[i];
    }

    // Calcular o declive e o intercepto usando o método dos mínimos quadrados
    *slope = (n * sum_xy - sum_x * sum_y) / (n * sum_x_squared - sum_x * sum_x);
    *intercept = (sum_y - *slope * sum_x) / n;
}

// Função para calcular R-quadrado
double computeRSquared(double *x, double *y, int n, double slope, double intercept) {
    double total_variation = 0.0;
    double explained_variation = 0.0;
    double y_mean = 0.0;

    // Calcular a média de y
    for (int i = 0; i < n; i++) {
        y_mean += y[i];
    }
    y_mean /= n;

    // Calcular as variações
    for (int i = 0; i < n; i++) {
        total_variation += pow(y[i] - y_mean, 2);
        double predicted_y = slope * x[i] + intercept;
        explained_variation += pow(y[i] - predicted_y, 2);
    }

    // Calcular R-quadrado
    return 1 - (explained_variation / total_variation);
}

// Função para interpretar o valor de R-quadrado
void interpretRSquared(double r_squared) {
    printf("\nInterpretação de R²:\n");
    if (r_squared < 0.3) {
        printf("Modelo fraco: O modelo explica menos de 30%% da variância.\n");
    } else if (r_squared < 0.5) {
        printf("Modelo moderado: O modelo explica 30-50%% da variância.\n");
    } else if (r_squared < 0.7) {
        printf("Bom modelo: O modelo explica 50-70%% da variância.\n");
    } else {
        printf("Excelente modelo: O modelo explica mais de 70%% da variância.\n");
    }
}

int main() {
    FILE *file;
    int n = 0, max_lines = 100;
    double x[100], y[100];
    double slope, intercept, r_squared;

    // Abrir o ficheiro de dados
    file = fopen("regression_data.txt", "r");
    if (file == NULL) {
        printf("Erro ao abrir o ficheiro!\n");
        return 1;
    }

    // Ler dados do ficheiro
    while (fscanf(file, "%lf %lf", &x[n], &y[n]) == 2) {
        n++;
        if (n >= max_lines) break;
    }
    fclose(file);

    // Calcular os parâmetros de regressão
    calculateRegressionParameters(x, y, n, &slope, &intercept);

    // Calcular R-quadrado
    r_squared = computeRSquared(x, y, n, slope, intercept);

    // Imprimir resultados
    printf("Resultados da Análise de Regressão:\n");
    printf("Número de Pontos de Dados: %d\n", n);
    printf("Declive: %.4f\n", slope);
    printf("Intercepto: %.4f\n", intercept);
    printf("R-quadrado (R²): %.4f\n", r_squared);

    // Interpretar R-quadrado
    interpretRSquared(r_squared);

    return 0;
}

Compile o programa:

gcc -o r_squared_print r_squared_print.c -lm

Execute o programa:

./r_squared_print

Exemplo de saída:

Resultados da Análise de Regressão:
Número de Pontos de Dados: 5
Declive: 0.6000
Intercepto: 1.5000
R-quadrado (R²): 0.5600

Interpretação de R²:
Bom modelo: O modelo explica 50-70% da variância.

Pontos chave:

  1. Lê dados de um ficheiro externo
  2. Calcula os parâmetros de regressão usando o método dos mínimos quadrados
  3. Calcula o valor de R²
  4. Fornece uma interpretação do valor de R²
  5. Ajuda a compreender o poder preditivo do modelo

Resumo

Neste laboratório, aprendemos a calcular os valores preditos de y utilizando um modelo de regressão linear simples em C. Criámos um programa que recebe os pontos de dados x e y, bem como o declive e o intercepto da reta de regressão, e calcula os valores preditos de y. Os passos chave envolveram o cálculo dos valores preditos de y com base na equação de regressão e a impressão dos valores originais e preditos de y para comparação.

Em seguida, aprenderemos a calcular o coeficiente de determinação (R²) utilizando a variação explicada e total dos dados.