Nesta trabalho, treinaremos um modelo de regressão linear usando descendência de gradiente estocástico no conjunto de dados da Qualidade do Vinho. O exemplo pressupõe que uma cópia CSV do conjunto de dados está no diretório de trabalho atual com o nome do arquivo winequality-white.csv.
O conjunto de dados de qualidade do vinho envolve a previsão da qualidade dos vinhos brancos em uma escala, com medidas químicas de cada vinho. É um problema de classificação multiclasse, mas também pode ser enquadrado como um problema de regressão. O número de observações para cada classe não é equilibrado. Existem 4.898 observações com 11 variáveis de entrada e 1 variável de saída. Os nomes das variáveis são os seguintes:
O desempenho de referencia de predição do valor médio é um RMSE de aproximadamente 0.148 pontos de qualidade.
Utilize o exemplo apresentado no tutorial e altere-o de forma a carregar os dados e analisar a acurácia de sua solução.
In [174]:
#Importando bibliotecas
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import preprocessing
In [175]:
#Lendo dataset
data = pd.read_csv('winequality-white.csv',delimiter=';')
data.head()
Out[175]:
In [176]:
#Normaliza os dados, para o gradiente convergir mais rápido. E todas as features ter o mesmo peso na função de custo
x = data.values #returns a numpy array
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled = min_max_scaler.fit_transform(data)
data = pd.DataFrame(x_scaled)
data.head()
Out[176]:
In [177]:
from math import sqrt
# Calculate root mean squared error
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)
# Estimate linear regression coefficients using stochastic gradient descent
def coefficients_sgd(train, l_rate, n_epoch):
m = len(train)
cost = [0.0 for i in range(n_epoch)]
coef = [0.0 for i in range(len(train[0]))]
print ('Coeficiente Inicial={0}' % (coef))
for epoch in range(n_epoch):
sum_error = 0
for i,row in enumerate(train):
yhat = predict(row, coef)
error = yhat - row[-1]
sum_error += (error**2)/m
coef[0] = coef[0] - l_rate * error
for i in range(len(row)-1):
coef[i + 1] = coef[i + 1] - l_rate * error * row[i]
print(('epoch=%d, lrate=%.3f, error=%.3f' % (epoch, l_rate, sum_error)))
predicts = [0.0 for i in range(len(train))]
for i,row in enumerate(df):
predicts[i] = predict(row, coef)
cost[epoch] = rmse_metric(train[-1],predicts)
return coef,cost
# Example of making a prediction with coefficients
# Make a prediction
def predict(row, coefficients):
yhat = coefficients[0]
for i in range(len(row)-1):
yhat += coefficients[i + 1] * row[i]
return yhat
In [178]:
#Defini o passo de aprendizagem e o número de épocas
lr = 0.001
epoch = 50
In [179]:
#Executa o regressão linear multvariável com gradiente estocástico
[coefficients,cost] = coefficients_sgd(df,ls,epoch)
In [180]:
plt.plot(cost)
plt.xlabel('Época')
plt.ylabel('RMSE')
plt.title('Erro por época')
plt.show()
In [181]:
print('Para lr = {0} e epoch = {1}\nRMSE = {2}'.format(ls,epoch,cost[-1]))
É possível observar através do gráfico de erro por época, que o algoritmo esta aprendendo. O erro foi próximo do esperado, mas não foi exato. Isto porque, foi utilizado o método do gradiente estocástico. Apesar do método convergir mais rápido para próximo do ponto de mínimo, ele fica variando muito em torno do mínimo. Uma solução seria utilizar o gradiente em lotes, que demora mais para convergir, porém não fica variando. Ou utilizar o método dos mínimos quadrados que chega no mínimo em uma interação.
Os dados de erro foram calculados no conjunto de treino. Caso fosse utilizado um conjunto de teste, o erro provavelmente seria maior, e poderia estar havendo overfitting. A solução para isto, seria utilizar regularização.