from sklearn.dummy import DummyRegressor
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import ShuffleSplit
import pandas as pd
from sklearn.metrics import mean_squared_error
from random import randrange
from csv import reader
from math import sqrt

"""
Explanation: Regressão Linear Simples - Trabalho
Estudo de caso: Seguro de automóvel sueco
Agora, sabemos como implementar um modelo de regressão linear simples. Vamos aplicá-lo ao conjunto de dados do seguro de automóveis sueco. Esta seção assume que você baixou o conjunto de dados para o arquivo insurance.csv, o qual está disponível no notebook respectivo.
O conjunto de dados envolve a previsão do pagamento total de todas as reclamações em milhares de Kronor sueco, dado o número total de reclamações. É um dataset composto por 63 observações com 1 variável de entrada e 1 variável de saída. Os nomes das variáveis são os seguintes:

Número de reivindicações.
Pagamento total para todas as reclamações em milhares de Kronor sueco.

Voce deve adicionar algumas funções acessórias à regressão linear simples. Especificamente, uma função para carregar o arquivo CSV chamado load_csv (), uma função para converter um conjunto de dados carregado para números chamado str_column_to_float (), uma função para avaliar um algoritmo usando um conjunto de treino e teste chamado split_train_split (), a função para calcular RMSE chamado rmse_metric () e uma função para avaliar um algoritmo chamado evaluate_algorithm().
Utilize um conjunto de dados de treinamento de 60% dos dados para preparar o modelo. As previsões devem ser feitas nos restantes 40%.
Compare a performance do seu algoritmo com o algoritmo baseline, o qual utiliza a média dos pagamentos realizados para realizar a predição ( a média é 72,251 mil Kronor).
End of explanation
"""


def mean(values):
    return sum(values) / float(len(values))

def coefficients(dataset):
    x = [row[0] for row in dataset]
    y = [row[1] for row in dataset]
    x_mean, y_mean = mean(x), mean(y)
    b2 = covariance(x, x_mean, y, y_mean) / variance(x, x_mean)
    b1 = y_mean - b2 * x_mean
    return [b1, b2]

def variance(values, mean):
    return sum([(x-mean)**2 for x in values])

def covariance(x, mean_x, y, mean_y):
    covar = 0.0
    for i in range(len(x)):
        covar += (x[i] - mean_x) * (y[i] - mean_y)
    return covar


def str_column_to_float(dataset, column):
    for row in dataset:
        row[column] = float(row[column].strip())


def load_csv(filename):
    dataset = list()
    with open(filename, 'r') as file:
        csv_reader = reader(file)
        for row in csv_reader:
            if not row:
                continue
            dataset.append(row)
    return dataset


def train_test_split(dataset, split):
    train = list()
    train_size = split * len(dataset)
    dataset_copy = list(dataset)
    while len(train) < train_size:
        index = randrange(len(dataset_copy))
        train.append(dataset_copy.pop(index))
    return train, dataset_copy

def rmse_metric(actual, predicted):
    sum_error = 0.0
    for i in range(len(actual)):
        prediction_error = predicted[i] - actual[i]
        sum_error += (prediction_error ** 2)
    mean_error = sum_error / float(len(actual))
    return sqrt(mean_error)

def simple_linear_regression(train, test):
    predictions = list()
    b1, b2 = coefficients(train)
    for row in test:
        yhat = b1 + b2 * row[0]
        predictions.append(yhat)
    return predictions

def evaluate_algorithm(dataset, algorithm, split, *args):
    train, test = train_test_split(dataset, split)
    test_set = list()
    for row in test:
        row_copy = list(row)
        row_copy[-1] = None
        test_set.append(row_copy)
    predicted = algorithm(train, test_set, *args)
    actual = [row[-1] for row in test]
    rmse = rmse_metric(actual, predicted)
    return rmse

ds = load_csv('insurance.csv')

for i in range(len(ds[0])):
    str_column_to_float(ds, i)

split = 0.6
rmse = evaluate_algorithm(ds, simple_linear_regression, split)
print('RMSE: %.3f' % (rmse))

"""
Explanation: Regressao Linear
End of explanation
"""


df = pd.read_csv("insurance.csv", header=None, names=['n_rei', 'pgtTot'])

dm = DummyRegressor()
param_grid = {"strategy": ["mean", "median"]}
ss = ShuffleSplit(n_splits=1, test_size=.4, random_state=100)

cv = GridSearchCV(dm, cv=ss, param_grid=param_grid, scoring="neg_mean_squared_error")

cv.fit(df[['n_rei']], df['pgtTot'])

cv.best_score_ * -1

"""
Explanation: Algoritmo Baseline
End of explanation
"""


