Алгоритм линейной регрессии после определенного момента вычисляет некорректно - PullRequest
0 голосов
/ 08 мая 2020

Моя программа считывает значения из файла и сохраняет их в xArray и yArray. Я попытался реализовать алгоритм линейной регрессии, он работает, но после определенного момента перестает правильно рассчитывать, и ошибка становится все больше и больше. Где моя ошибка? Желаемый f (x): = 2x + 0

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

#define SIZE  20 //size of the sample input array
#define iterations_number 100
#define PI 3.14159

double  start_value = 5.5;
double xArray[SIZE] = { 0 };
double yArray[SIZE] = { 0 };
int array_size = sizeof(xArray) / sizeof(xArray[0]);

FILE* file;
FILE* file_xArray;
FILE* file_yArray;
FILE* sample;

void    print_result(double b0, double b1, double error);
void    calculate(); //calculate the best linear function
double  calculateAngle(double x2, double y2, double x1, double y1);
void    add_next_item_to_buffer_and_remove_last_item(double item, double* buffer);
void    generate_first_sample_data_and_fill_xArray();
void    generate_first_sample_data_and_fill_yArray();
void    generate_first_sample_data();
void    print_xArray();
void    print_yArray();
void    read_from_file_and_fill_xArray_and_yArray();
void    reverseArray(int arr[], int start, int end);
void    main(){
  generate_first_sample_data();
   read_from_file_and_fill_xArray_and_yArray();

   reverseArray(xArray, 0, 2*SIZE);
   reverseArray(yArray, 0, 2*SIZE);
   calculate();
  // print_xArray();
  //    print_yArray();
}

void add_next_item_to_buffer_and_remove_last_item(double item, double *buffer) { 

    for (int i = SIZE - 1; i > 0; i--) {
        buffer[i] = buffer[i - 1];
    }
    buffer[0] = item;
}

void print_result(double b0, double b1, double error) {
    printf("f(x) =  %5f x + %5f\n", b1, b0);
    printf("Error: %5f ", error);

}

void print_xArray() {
    for (int i = 0; i < array_size; i++) {
        printf("%f\n", xArray[i]);
    }
}

void print_yArray() {
    for (int i = 0; i <array_size; i++) {
        printf("%f\n", yArray[i]);
    }
}

void calculate() { 

    double y = 1;
    double err = 5.0; 
    double b0 = 0.0;
    double b1 = 0.0;
    double alpha = 0.01; //error rate
    double degree = 0;
    double prediction_number = 0.0;

    errno_t returnValue = fopen_s(&file, "data.txt", "w" );
    fprintf(file, "SAMPLE_NO,       ITERATION_NO,        REF_VAL,            MEASUREMENT,          ERROR\n");
    for (int i = 0; i < iterations_number; i++) {

            int L = i % SIZE; // L  -    iteration length - number of samples per iteration


            for (int j = 0; j < L; j++) {
                y = b0 + b1 * xArray[j]; //y - predicted y value, xArray[i] - x value
            }

            err = y - yArray[L];
            b0 = b0 - alpha * err;
            b1 = b1 - alpha * err * xArray[L];
            degree = calculateAngle(xArray[L], y, 0.0, 0.0);

            print_result(b0, b1, err);
            fprintf(file, "%.5f              ", xArray[L]);
            fprintf(file, "%d.              ", i);
            fprintf(file, "%.5f              ", y);
            fprintf(file, "%.5f              ", degree);
            fprintf(file, "%.5f\n", err);

   }

    fclose(file);
    print_result(b0, b1, err);
}

double calculateAngle(double x2, double y2, double x1, double y1){
    double deltaX = x2 - x1;
    double deltaY = y2 - y1;
    double rad = atan2(deltaY, deltaX); //radians
    double degree = rad * (180 / PI);

    return degree;
}


void generate_first_sample_data_and_fill_xArray() {
    //first data randomly generated
    errno_t returnValue = fopen_s(&file_xArray, "xArray.txt", "w");
    for (int i = 0; i < array_size; i++) {
        xArray[i] = 1.37 + i * 0.3;
        fprintf(file_xArray, "%f\n", xArray[i]);
    }
    fclose(file_xArray);
}

void generate_first_sample_data_and_fill_yArray() {
    //first data randomly generated
    errno_t returnValue = fopen_s(&file_yArray, "yArray.txt", "w");
    for (int i = 0; i < array_size; i++) {
        yArray[i] = 1.02 + i * 2.0;
        fprintf(file_yArray, "%f\n", yArray[i]);
    }
    fclose(file_yArray);
}

void generate_first_sample_data() {
    errno_t returnValue = fopen_s(&sample, "sample.txt", "w");

    for (int i = 0; i < array_size; i++) {
        xArray[i] = i;
        fprintf(sample, "%f ", xArray[i]);
        yArray[i] = i * 2.0;
        fprintf(sample, "%f\n", yArray[i]);
    }
    fclose(sample);
}


void read_from_file_and_fill_xArray_and_yArray() {
    errno_t returnValue = fopen_s(&sample, "sample.txt", "r");


    char line[SIZE];
    const char* standard_white_space = " ";
    char* xCoordinate= '\0';
    char* yCoordinate= '\0';


    while (fgets(line, sizeof line, sample) != NULL) {
         // printf("%s\n", buffer);

            // Token will point to the part before the
            xCoordinate = strtok(line, standard_white_space);
            add_next_item_to_buffer_and_remove_last_item(atof(xCoordinate), &xArray);

            // Token will point to the part after the 
            yCoordinate = strtok(NULL, standard_white_space);
            add_next_item_to_buffer_and_remove_last_item(atof(yCoordinate),  &yArray);

    }

    fclose(sample);
}

//example of reading from file in format
//x y degree 

void read_from_file() {
    errno_t returnValue = fopen_s(&sample, "sample.txt", "r");

    char line[sizeof(xArray)];
    char* search1 = " ";
    char* search2= " ";
    char* token;

    while (fgets(line, sizeof line, sample) != NULL) {
        // printf("%s\n", buffer);

        // Token will point to the part before the " " 
        token = strtok(line, search1);
        add_next_item_to_buffer_and_remove_last_item(strtod(token, NULL), &xArray);

        // Token will point to the part after the " " 
        token = strtok(search1, search2);
        add_next_item_to_buffer_and_remove_last_item(strtod(token, NULL), &yArray);

        // Token will point to the part at end of the line
        token = strtok(NULL, search2);
        //add_next_item_to_buffer_and_remove_last_item(strtod(token, NULL), &degreeArray);
    }

    fclose(sample);
}
void reverseArray(int arr [], int start, int end)
{
    if (start >= end)
        return;

    int temp = arr[start];
    arr[start] = arr[end];
    arr[end] = temp;

    // Recursive Function calling 
    reverseArray(arr, start + 1, end - 1);
}

Данный образец файла | xCoordinate yCoordinate | образец файла Вывод: вывод

Иногда я также получаю это исключение nullptrExceptrion здесь

yCoordinate = strtok(NULL, standard_white_space);
            add_next_item_to_buffer_and_remove_last_item(atof(yCoordinate),  &yArray);
...