<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Homework 6
Step1:  Observa-se no gráfico uma relação clara entre o número de reinvidicações e o pagamento total.
Step2:  Como esperado, o modelo de regressão linear explica bem os dados, tendo um valor RSME menor que a predição pelo valor médio de pagamento.
<ASSISTANT_TASK:>
Python Code:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
% matplotlib inline
# Define uma função para carregar os dados
def load_csv(path):    
    df = pd.read_csv(path,names=['num_reinv','pag_total'])    
    return df
insdf = load_csv('insurance.csv')
insdf.head()
plt.scatter(insdf.num_reinv,insdf.pag_total)
plt.xlabel('Número de Reinvidicações')
plt.ylabel('Pagamento Total')
plt.grid(True)
Explanation: Homework 6: Regressão Linear Simples
Isac do Nascimento Lira, 371890
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 performabce 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
#Funções úteis
# Calculate the mean value of a list of numbers
def mean(values):
    return sum(values) / float(len(values))
# Calculate the variance of a list of numbers
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
# Implementa a classe do modelo de regressão linear simples
class simple_linear_regression(object):
    
    def _init_(self):
        self.train = None
        self.coef = None
        self.intercept = None
    
    def fit(self,train):
        self.train = train
        self.get_coefficients()
    
    def get_coefficients(self):
        x = [row[0] for row in self.train]
        y = [row[1] for row in self.train]
        x_mean, y_mean = mean(x), mean(y)
        self.coef = covariance(x, x_mean, y, y_mean) / variance(x, x_mean)
        self.intercept = y_mean - self.coef * x_mean
    
    def predict(self,data):
        predictions = []
        for row in data:
            ypred = self.intercept + self.coef * row[0]
            predictions.append(ypred)
        return predictions
# Avalia o modelo
from math import sqrt
# Realiza o cálculo da metrica RMSE
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)
# Função que separa os dados em treino e teste
def split_train_split(data,splitRatio):
    
    msk = np.random.rand(len(data)) < splitRatio
    trainSet = data[msk]#.values
    testSet = data[~msk]#.values 
    
    return trainSet,testSet
    
# Função para avaliar o modelo
def evaluate_algorithm(data,algorithm):
    
    train,test = split_train_split(data,0.6)
    
    lm = algorithm()
    lm.fit(train)    
    predicted = lm.predict(test)
    actual = test[:,1]
    pred_rmse= rmse_metric(actual, predicted)
    
    predictedMean = np.zeros_like(actual)
    predictedMean[:] = np.mean(actual)
    mean_rmse = rmse_metric(actual, predictedMean)
    return pred_rmse,mean_rmse,lm
pred_rmse,mean_rmse,lm = evaluate_algorithm(insdf.values,simple_linear_regression)
print('')
print("RMSE - Regressão Linear", pred_rmse)
print("RMSE - Predição pelo valor média", mean_rmse)
print('')
Explanation: Observa-se no gráfico uma relação clara entre o número de reinvidicações e o pagamento total.
End of explanation
# plota as predições vs dados reais e mostra o erro de predição
x = insdf['num_reinv'].values
y = insdf['pag_total'].values
y_hat = lm.intercept + x.dot(lm.coef)
fig,axs = plt.subplots(1,2,figsize=[15,5])
axs[0].plot(x,y_hat,'g-',label='Regression Line',alpha=0.6)
axs[0].scatter(x,y,alpha=0.5,label='Actual Values')
axs[0].set_xlabel('Nº Reinvidicações')
axs[0].set_ylabel('Pagamento Total')
axs[0].legend(loc='best')
error = (y_hat-y)
axs[1].scatter(x,error,alpha=0.5,color='b')
axs[1].axhline(0,color='k')
axs[1].set_xlabel('Nº Reinvidicações')
axs[1].set_ylabel('Erro de predição')
Explanation: Como esperado, o modelo de regressão linear explica bem os dados, tendo um valor RSME menor que a predição pelo valor médio de pagamento.
End of explanation
<END_TASK>