Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #define __USE_MINGW_ANSI_STDIO 0
- #pragma comment(linker, "/STACK:256000000")
- #pragma GCC optimize("Ofast")
- #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
- #include <stdio.h>
- #include <math.h>
- #define MIN(a,b) (((a)<(b))?(a):(b))
- #define MAX(a,b) (((a)>(b))?(a):(b))
- #define LEARNING_RATE 0.1
- #define MAX_TRAIN_SET_SIZE 10000
- #define MAX_CATEGORIES_SIZE 1000 + 1
- #define STEPS_COUNT 5000
- /******************** Common data *******************/
- int n; // train sets size
- int m; // categories size
- double x_sets[MAX_TRAIN_SET_SIZE][MAX_CATEGORIES_SIZE];
- double y_sets[MAX_TRAIN_SET_SIZE];
- double weights[MAX_CATEGORIES_SIZE];
- void loadData();
- /************* Packet settings **********************/
- #define PACKET_SIZE_FRACTION 0.1 // 10%
- int packet_start_index;
- int packet_end_index;
- int packet_size;
- void initializePacketSettings() {
- //packet_size = 1;
- //if (n < 100) {
- // packet_size = n;
- //}
- //else {
- // packet_size = n * PACKET_SIZE_FRACTION;
- //}
- if (n < 20) {
- packet_size = n;
- }
- else {
- packet_size = 20;
- }
- packet_start_index = 0;
- packet_end_index = packet_size;
- }
- /***** Normalization and denoramlization **********/
- double mean_for_category[MAX_CATEGORIES_SIZE];
- double mean_for_y;
- double standard_deviation_for_category[MAX_CATEGORIES_SIZE];
- double standard_deviation_for_y;
- void normalize();
- void denormalize();
- void calculateMeans();
- void calculateStandardDeviations();
- /******** Gradient descent **************/
- double grad_for_sets[MAX_TRAIN_SET_SIZE][MAX_CATEGORIES_SIZE];
- double grad[MAX_CATEGORIES_SIZE];
- void train();
- void updateGrad();
- void updateGradForSet(int set_number);
- double predict(double* x);
- void updateWeights();
- void moveToTheNextPacket();
- int main() {
- loadData();
- initializePacketSettings();
- normalize();
- train();
- denormalize();
- for (int i = 0; i < m; i++) {
- printf("%lf\n", weights[i]);
- }
- return 0;
- }
- // Read data
- void loadData() {
- scanf("%d%d", &n, &m);
- m++;
- for (int i = 0; i < n; i++) {
- for (int j = 0; j <= m; j++) {
- if (j == m - 1) {
- x_sets[i][m] = 1;
- continue;
- }
- if (j == m) {
- scanf("%lf", &y_sets[i]);
- continue;
- }
- scanf("%lf", &x_sets[i][j]);
- }
- }
- }
- // Normalization and denoramlization
- void normalize() {
- calculateMeans();
- calculateStandardDeviations();
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < m; j++) {
- double x = x_sets[i][j];
- double mean = mean_for_category[j];
- double standard_deviation = standard_deviation_for_category[j];
- /* if standard deviation is zero, it means that all 'x' have the same
- values, therefore we do not normalize them. Do not forget this point when
- you are using denormalization algorithm */
- if (standard_deviation != 0) {
- x_sets[i][j] = (x - mean) / standard_deviation;
- }
- }
- y_sets[i] = (y_sets[i] - mean_for_y) / standard_deviation_for_y;
- }
- }
- void calculateMeans() {
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < m; j++) {
- mean_for_category[j] += x_sets[i][j];
- }
- mean_for_y += y_sets[i];
- }
- mean_for_y /= n;
- for (int j = 0; j < m; j++) {
- mean_for_category[j] /= n;
- }
- }
- void calculateStandardDeviations() {
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < m; j++) {
- double x = x_sets[i][j];
- double mean = mean_for_category[j];
- standard_deviation_for_category[j] += (x - mean) * (x - mean);
- }
- standard_deviation_for_y += (y_sets[i] - mean_for_y) * (y_sets[i] - mean_for_y);
- }
- standard_deviation_for_y /= n;
- standard_deviation_for_y = sqrt(standard_deviation_for_y);
- for (int j = 0; j < m; j++) {
- standard_deviation_for_category[j] /= n;
- standard_deviation_for_category[j] = sqrt(standard_deviation_for_category[j]);
- }
- }
- void denormalize() {
- for (int i = 0; i < m - 1; i++) {
- if (standard_deviation_for_category[i] != 0) {
- double res = weights[i] * standard_deviation_for_y / standard_deviation_for_category[i];
- weights[i] = res;
- weights[m - 1] -= res * mean_for_category[i];
- }
- }
- weights[m - 1] += mean_for_y;
- }
- // Gradient descent
- void train() {
- for (int i = 0; i < STEPS_COUNT; i++) {
- updateGrad();
- updateWeights();
- moveToTheNextPacket();
- }
- }
- void moveToTheNextPacket() {
- if (packet_end_index == n) {
- packet_start_index = 0;
- packet_end_index = packet_size;
- }
- else {
- packet_start_index = packet_end_index;
- packet_end_index = MIN(packet_end_index + packet_size, n);
- }
- }
- void updateGrad() {
- for (int i = packet_start_index; i < packet_end_index; i++) {
- updateGradForSet(i);
- for (int j = 0; j < m; j++) {
- if (i == 0) {
- grad[j] = grad_for_sets[0][j];
- }
- else {
- grad[j] += grad_for_sets[i][j];
- }
- }
- }
- }
- void updateGradForSet(int set_number) {
- double* x = x_sets[set_number];
- double y = y_sets[set_number];
- double y_pred = predict(x);
- double residual = (y_pred - y);
- for (int i = 0; i < m; i++) {
- double grad = residual * x[i];
- grad_for_sets[set_number][i] = grad;
- }
- }
- double predict(double* x) {
- double prediction = 0;
- for (int i = 0; i < m; i++) {
- prediction += weights[i] * x[i];
- }
- return prediction;
- }
- void updateWeights() {
- for (int i = 0; i < m; i++) {
- weights[i] -= LEARNING_RATE * grad[i];
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement