Regressão Linear com muitas variáveis

May 31, 2017 | Autor: Manuel Leiria | Categoria: Machine Learning, Java Programming
Share Embed


Descrição do Produto

Regress˜ao Linear com muitas vari´aveis Manuel Leiria August 7, 2016

Abstract A regress˜ ao linear com muitas vari´aveis ´e uma generaliza¸c˜a matem´atica da Regress˜ao linear com uma vari´ avel, j´ a descrita no artigo anterior (Regress˜ao Linear com uma vari´avel). Tudo o que foi referido para uma vari´ avel, tamb´em se aplica ao caso de muitas vari´aveis (fun¸c˜ao de custo, gradiente descendente,...).

1

Introdu¸c˜ ao

Segue-se a nota¸c˜ ao utilizada para equa¸c˜oes com muitas vari´aveis de input: (i)

xj = valor da vari´ avel j (feature) no exemplo de treino i. Em termos matriciais ´e o valor do componente da linha i, coluna j. xi = vector coluna de todos os inputs das vari´aveis do exemplo de treino i. m = N´ umero de exemplos de treino. n = |xi | (n´ umero de inputs ou features).

A fun¸c˜ao de hip´ otese para muitas vari´aveis ´e:

hθ (x) = θ0 + θ1 x1 + θ2 x2 + ... + θn xn

(1)

Retomando o exemplo dos pre¸cos da venda de apartamentos em fun¸c˜ao das suas caracter´ısticas, podemos pensar, por exemplo que θ0 ´e o pre¸co b´asico da casa, θ1 ser´a o pre¸co por metro quadrado, θ2 o pre¸co por andar, etc. Ent˜ao x1 representa o n´ umero de metros quadrados da casa, x2 o n´ umero de andares, etc.

1

Introduzindo a vari´ avel dummy x0 = 1 para termos as dimens˜oes alinhadas, podemos reescrever a equa¸c˜ao 1 em termos matriciais (relembro que uma das propriedades b´asicas de multiplica¸c˜ ao de matrizes ´e que o n´ umero de colunas da primeira matriz tem de ser igual ao n´ umero de linhas da segunda matriz) da seguinte forma: 

hθ (x) = [θ0



     x1  T  θn ]   ..  = θ x  .    xn

···

θ1

x0

(2)

Se tivermos m exemplos de treino, cada um com n features, podemos construir a seguinte matriz:

 (1) x  0  (1) x1 X=    (1) xn

(2)

...

(2)

...

x0

x1

.. . (2)

xn

...

(m)

x0





1

   (1) (m)  x1  x1 =       (m) (1) xn xn

1

...

(2)

x1

1

 (m)  x1      (m) xn

... .. .

(2)

xn



...

(3)

Portanto, nesta representa¸c˜ ao, a primeira coluna representa o primeiro exemplo de treino, a segunda coluna, o segundo exemplo e por ai fora. Estamos em condi¸c˜ oes de definir hθ (X) como um vector linha que nos d´a o valor de hθ (x) em cada um dos m exemplos de treino: (1)

(1)

hθ (X) = [θ0 x0 +θ1 x1 +. . .+θn x(1) n

(2)

(2)

θ0 x0 +θ1 x1 +. . .+θn x(2) n

...

(m)

(m)

θ0 x0 +θ1 x1 +. . .+θn x(m) n ] (4)

ou seja,

hθ (X) = [θ0

θ1

···

 (1) x  0  (1) x1 θn ]     (1) xn

(2)

x0

(2) x1

(2)



x0

...

(m)  x1  

...

xn

.. . xn

(m)

...



(m)

T =θ X  

(5)

Nota: esta vers˜ ao da fun¸c˜ ao de hip´otese assume que a matrix X e o vector θ guardam os valores na seguinte forma:  (1) x0  X= (1) x1



(2) x0 (2) x2

(3) x0 ,θ (3) x3

2

  θ0 =  , θ1

(6)

Eu prefiro usar uma abordagem alternativa, onde cada linha corresponde a um exemplo de treino (row-wise). Neste caso:  (1) x  0  X = x(2)  0 (3) x0

(1)

x1



   θ0 (2)  x1  , θ =   ,  θ1 (3) x1

(7)

Acho esta abordagem mais intuitiva, at´e porque normalmente recebemos os dados de teste (seja a partir de um ficheiro csv ou bd) neste formato, onde cada linha corresponde a um exemplo de treino. Neste formato, a fun¸c˜ ao de hip´ otese escreve-se:

hθ (X) = Xθ

(8)

´ claro que nesta representa¸c˜ E ao hθ (X) ´e um vector coluna.

2

Fun¸c˜ ao de custo

A fun¸c˜ao de custo, tal como j´ a vimos, ´e: m

1 X J(θ) = (hθ (x(i) − y (i) )2 2m

(9)

i=1

ou, melhor ainda, na sua forma vectorial: J(θ) =

1 (Xθ − ~y )T (Xθ − ~y ) 2m

(10)

onde ~y ´e o vector de todos os valores y (no nosso exemplo ser´a o pre¸co do apartamento, a vari´avel sobre a qual queremos fazer previs˜oes.

3

Gradiente Descendente

A equa¸c˜ao do gradiente descendente, ´e (ver Regress˜ao Linear com uma vari´avel para mais informa¸c˜oes): (i)

1 θ0 := θ0 − α m

Pm

(i) )

− y (i) )x0

1 θ1 := θ1 − α m

Pm

(i) )

− y (i) )x(i)

i=1 (hθ (x i=1 (hθ (x

3

... ou seja, repetir 1 θj := θj − α m

Pm

i=1 (hθ (x

(i) )

(i)

− y (i) )xj

at´e convergir. (i)

N˜ao esquecer que x0 = 1 sempre (vari´avel dummy criada s´o para se conseguir generalizar a equa¸c˜ao). Mais interessante ´e a sua representa¸c˜ao vectorial:

θ := θ − α∇J(θ)

(11)

onde ∇J(θ) ´e um vector coluna da forma: 



∂J(θ)  ∂θ0   ∂J(θ)   ∂θ1   

∇J(θ) =  .  ,  ..   

(12)

∂J(θ) ∂θn

Calculando as derivadas parciais, obtemos para o gradiente:

∇J(θ) =

1 T X (Xθ − ~y ) m

(13)

Substituindo esta express˜ ao na equa¸c˜ao (11) obtemos, finalmente, a express˜ao do gradiente descendente na sua forma matricial (ou vectorial): θ := θ −

4 4.1

α T X (Xθ − ~y ) m

(14)

Exemplo pr´ atico com implementa¸ c˜ ao em Java An´ alise e pr´ e-processamento dos dados

NOTA: todos os ficheiros (classes java, dados, pdf) est˜ao aqui

Vamos come¸car por olhar para os dados. Tenho um ficheiro (housePrice.txt) com 47 registos. A primeira coluna representa o tamanho em m2 do apartamento, a segunda coluna diz-nos quantos quartos o apartamento tem (estas s˜ao as vari´aveis de input x ou features) e

4

por fim, na terceira e u ´ltima coluna, est´a o pre¸co

Table 1: Pre¸co dos apartamentos em Lisboa. Tamanho (m2 )

N´ um. quartos

Pre¸co (euros)

195.5

3

399900

148.6

3

329900

223.0

3

369000

131.6

2

232000

278.7

4

539900

184.4

4

299900

142.5

3

314900

132.6

3

198999

128.2

3

212000

138.8

3

242500

...

...

...

79.2

2

179900

172.1

4

299900

111.8

3

239500

Vamos ver o pre¸co em fun¸c˜ ao do tamanho: C´odigo Python

import matplotlib.pyplot as plt

work_dir = ’/home/manuel/tools/adalineProcesses/mlearning/dataFiles/’ input_file = ’housePrice’ ext = ’.txt’ file_to_process = work_dir + input_file + ext x1 = [] #tamanho em m^2 x2 = [] #num. quartos

5

y = [] #preco de venda f = open(file_to_process, ’r’) for line in f: values = line.split(’,’) x1.append(float(values[0])) x2.append(float(values[1])) y.append(float(values[2])) f.close() plt.scatter(x1,y) plt.xlabel(’Tamanho em m^2’) plt.ylabel(’Preo em euros’) plt.show()

Olhando para a tabela, podemos constatar que os valores do tamanho do apartamento s˜ ao muito superiores aos valores do n´ umero de quartos (pelo menos por uma ordem de 10).Quando as features diferem por ordens de magnitude, normalizar os falores (feature scaling) pode fazer o gradiente descendente convergir muito mais depressa. Isto porque θ desce muito mais depressa em intervalos pequenos e ´e muito lento em intervalos grandes. Uma forma de prevenir oscila¸c˜ oes desnecess´arias e ineficientes na descida do gradiente, ´e normalizar os valores. Idealmente ter qualquer coisa do g´enero −1 ≤ xi ≤ 1 ou −0.5 ≤ xi ≤ 0.5

6

Uma das t´ecnicas utilizadas para nos auxiliar nesta tarefa ´e a normaliza¸c˜ao pela m´edia e desvio padr˜ao: xi :=

xi − µ i σi

(15)

Portanto, o que h´ a a fazer, ´e para cada feature nos dados, subtrair a m´edia e depois dividir pelo desvio padr˜ ao. O desvio padr˜ ao d´a-nos uma forma de medir a varia¸c˜ao que existe no intervalo de valores de cada feature.

4.2 4.2.1

Implementa¸ c˜ ao Carregar os dados

Classe que vai correr a regress˜ ao: package pt.mleiria.machinelearning;

import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import pt.mleiria.machinelearning.matrixAlgebra.Matrix;

/** * * @author manuel */ public class LinearRegMultiple {

private static final String path = "/home/manuel/tools/adalineProcesses/mlearning/dataFiles/"; private final static String dataFile = path + "housePrice.txt";

7

private final static String costHistory = path +"JGDM.txt";

public static void main(String[] args) { try { double[][] rawData = loadFileToComponents(dataFile, ","); Matrix matrix = new Matrix(rawData); //We can check the data loaded System.out.println(matrix.toString()); } catch (Exception ex) { Logger.getLogger(LinearRegMultiple.class.getName()).log(Level.SEVERE, null, ex); } }

/** * load a file in csv style into a matrix, 1.34,2.34,0.3 13.45,0.2231,1.33 * * @param pathToFile * @param separator * @return * @throws java.io.FileNotFoundException */ public static double[][] loadFileToComponents(final String pathToFile, final String separator) throws FileNotFoundException, IOException { final List rows; try (BufferedReader br = new BufferedReader(new FileReader(pathToFile))) { String line; rows = new ArrayList(); while ((line = br.readLine()) != null) { rows.add(line.split(separator)); }

8

} double[][] data = new double[rows.size()][]; for (int i = 0; i < rows.size(); i++) { final String[] rowArr = rows.get(i); final int colSize = rowArr.length; data[i] = new double[colSize]; for (int j = 0; j < colSize; j++) { data[i][j] = Double.parseDouble(rowArr[j]); } } return data; } } Esta classe tem o public static void main(String[] args) que vai ser usada para correr o programa e tem um m´etodo auxiliar (loadFileToComponents(...)) que carrega um ficheiro estilo csv (dados separados por v´ırgulas) para um double[][]. Correndo este c´odigo, obtenho um objecto Matrix com 47 linhas e 3 colunas. Segundo passo ser´ a separar as features dos target values, ou seja, x para um lado e y para o outro (vou-me fixar no peda¸co de c´ odigo dentro do public static void main(...) para n˜ao estar sempre a repetir: try { double[][] rawData = loadFileToComponents(dataFile, ","); Matrix matrix = new Matrix(rawData); //We can check the data loaded System.out.println(matrix.toString()); //split the matrix in x (features) and y (target value) Matrix[] dMatrix = matrix.split(1); //Let’s see: Matrix x = dMatrix[0]; Matrix y = dMatrix[1]; System.out.println(x.toString());

9

System.out.println(y.toString()); } O m´etodo split pertence ` a classe Matrix.java: /** * Splits the receiver in two Matrices * * @param numCols number of columns of the Matrix[1] * @return Matrix[2] where Matrix[0] = Matrix[rows, cols-numCols] Matrix[1] * = Matrix[rows, numCols */ public Matrix[] split(final int numCols) { if (numCols >= columns()) { throw new IllegalArgumentException("numCols must be smaller than columns"); } final int rows = this.rows(); final int cols = this.columns(); final int diffCols = cols - numCols; final double[][] a = new double[rows][diffCols]; final double[][] b = new double[rows][numCols]; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (j < diffCols) { a[i][j] = components[i][j]; } else { b[i][diffCols - j] = components[i][j]; } } } final Matrix[] result = new Matrix[2];

10

final Matrix aa = new Matrix(a); final Matrix bb = new Matrix(b); result[0] = aa; result[1] = bb; return result;

} Tenho, ent˜ ao duas matrizes, uma com as features x e outra com o y. Este m´etodo tem de ser revisto porque nos casos em que uma das matrizes final ´e uma coluna (nx1) em vez de uma matriz posso ter um vector que sempre ´e mais leve. Um caso a ver... Pr´oximo passo: normalizar (feature normalization) as features (matriz x ). Para normalizar, e porque pode haver diferentes formas de normalizar os dados, comecei por criar um interface: package pt.mleiria.machinelearning.preprocess;

import pt.mleiria.machinelearning.matrixAlgebra.Matrix; /** * * @author manuel */ public interface FeatureNormalization {

Matrix normalize(final Matrix matrix); } e tenho a seguinte implementa¸c˜ ao: package pt.mleiria.machinelearning.preprocess;

import pt.mleiria.machinelearning.matrixAlgebra.Matrix; import pt.mleiria.machinelearning.statistics.StatisticalMoments;

/**

11

* * @author manuel */ public class FeatNormMeanStdev implements FeatureNormalization {

private double[] mean; private double[] stdev;

/** * new Matrix = (elements - mean)/std * * @param matrix the Matrix to be normalizes * @return the normalized matrix */ @Override public Matrix normalize(final Matrix matrix) { mean = new double[matrix.columns()]; stdev = new double[matrix.columns()];

final int rows = matrix.rows(); final int columns = matrix.columns(); double[][] components = matrix.toComponents(); /** * The normalized matrix */ final double[][] newComponents = new double[rows][columns]; for (int i = 0; i < columns; i++) { final StatisticalMoments sm = new StatisticalMoments(); int j = 0; for (j = 0; j < rows; j++) { sm.accumulate(components[j][i]); }

12

mean[i] = sm.average(); stdev[i] = sm.standardDeviation(); for (j = 0; j < rows; j++) { newComponents[j][i] = (components[j][i] - mean[i]) / stdev[i]; } } return new Matrix(newComponents); } /** * * @return an array with the mean of all columns */ public double[] getMean() { return mean; } /** * * @return an array with the stdev of all columns */ public double[] getStdev() { return stdev; } } Aqui est˜ao a acontecer algumas coisas, sendo que o principal a referir ´e que estou a fazer uso de uma nova classe (StatisticalMoments.java). Esta classe acumula os valores e retorna os v´arios momentos estat´ısticos, nomeadamente a m´edia, a variˆancia, skweness e kurtosis. Vamos ver: package pt.mleiria.machinelearning.statistics;

/** * * @author manuel

13

*/ public class StatisticalMoments { /** * Vector containing the points */ protected double[] moments; /** * Default constructor methods: declare space for 5 moments. */ public StatisticalMoments() { this(5); } /** * * @param n number of moments to accumulate */ public StatisticalMoments(final int n) { moments = new double[n]; reset(); } /** * * @param x */ public void accumulate(final double x) { double value = 1.0; for (int n = 0; n < moments.length; n++) { moments[n] += value; value *= x; } } /**

14

* @return double average. */ public double average() { return moments[1] / moments[0]; } /** * The kurtosis measures the sharpness of the distribution near the maximum. * Note: The kurtosis of the Normal distribution is 0 by definition. * * @return double kurtosis. */ public double kurtosis() throws ArithmeticException { if (moments[0] < 4) { return Double.NaN; } double x1 = average(); double x2 = moments[2] / moments[0]; double x3 = moments[3] / moments[0]; double x4 = moments[4] / moments[0]; double xSquared = x1 * x1; double m4 = x4 - (4 * x1 * x3) + 3 * xSquared * (2 * x2 - xSquared); double kFact = moments[0] * (moments[0] + 1) / ((moments[0] - 1) * (moments[0] - 2) * (moments[0] - 3)); double kConst = 3 * (moments[0] - 1) * (moments[0] - 1) / ((moments[0] - 2) * (moments[0] - 3)); x4 = variance(); x4 *= x4; return kFact * (m4 * moments[0] / x4) - kConst; }

15

/** * @return double skewness. */ public double skewness() throws ArithmeticException { if (moments[0] < 3) { return Double.NaN; } double x1 = average(); double x2 = moments[2] / moments[0]; double x3 = moments[3] / moments[0]; double m3 = x3 + x1 * (2 * x1 * x1 - 3 * x2); x1 = standardDeviation(); x2 = x1 * x1; x2 *= x1; return m3 * moments[0] * moments[0] / (x2 * (moments[0] - 1) * (moments[0] - 2)); } /** * Returns the standard deviation. May throw divide by zero exception. * * @return double standard deviation. */ public double standardDeviation() { return Math.sqrt(variance()); } /** * Unnormalized central moment of 2nd order (needed to compute the t-test). * * @return double */ public double unnormalizedVariance() {

16

double average = average(); return moments[2] - average * average * moments[0]; } /** * Note: the variance includes the Bessel correction factor. * * @return double variance. */ public double variance() throws ArithmeticException { if (moments[0] < 2) { return Double.NaN; } double average = average(); return (moments[0] / (moments[0] - 1)) * (moments[2] / moments[0] - average * average); } /** * Reset all counters */ private void reset() { for (int i = 0; i < moments.length; i++) { moments[i] = 0; } } } Vamos normalizar: try { double[][] rawData = loadFileToComponents(dataFile, ","); Matrix matrix = new Matrix(rawData); //We can check the data loaded System.out.println(matrix.toString());

17

//split the matrix in x (features) and y (target value) Matrix[] dMatrix = matrix.split(1); //Let’s see: Matrix x = dMatrix[0]; Matrix y = dMatrix[1]; System.out.println(x.toString()); System.out.println(y.toString()); //Feature normalization final FeatureNormalization ftn = new FeatNormMeanStdev(); final Matrix xNorm = ftn.normalize(x); //Check it System.out.println(xNorm.toString());

} Vamos agora faze uso da classe GradientDescent.java. Esta classe extende a IteratorProcessor.java que ´e uma classe abstracta gen´erica para processos iterativos. try { double[][] rawData = loadFileToComponents(dataFile, ","); Matrix matrix = new Matrix(rawData); //We can check the data loaded System.out.println(matrix.toString()); //split the matrix in x (features) and y (target value) Matrix[] dMatrix = matrix.split(1); //Let’s see: Matrix x = dMatrix[0]; Matrix y = dMatrix[1]; System.out.println(x.toString()); System.out.println(y.toString()); //Feature normalization final FeatureNormalization ftn = new FeatNormMeanStdev(); final Matrix xNorm = ftn.normalize(x);

18

//Check it System.out.println(xNorm.toString()); //alpha value double alpha = 0.01; //Num max iter int numIter = 400; //desired precision double precision = 0.00001; GradientDescent gd = new GradientDescent(xNorm, y, alpha); gd.setMaximumIterations(numIter); gd.setDesiredPrecision(precision); gd.evaluate(); saveArrayToFile(costHistory, gd.getCostHistory()); } ´ um utilit´ario para O m´etodo saveArrayToFile() pertence `a classe LinearRegMultiple.java. E gravar os resultados em ficheiro. O construtor do GradientDescent.java recebe trˆes parˆametros, a matrix x normalizada, a matrix y (ou vector coluna) e o α que optei por come¸car com um valor de 0.01 mas pode ser reajustado. Fazemos tamb´em o set do n´ umero m´aximo de iterac¸c˜oes e da precis˜ao desejada. O processo iterativo para quando um deles for alcan¸cado. O m´etodo gd.evaluate vai at´e ` a classe abstracta IteratorPorcessor.java: public abstract class IteratorProcessor { //Code...

/** * Performs the iterative process */ public void evaluate() { iterations = 0; initializeIterations(); while (iterations++ < maximumIterations) {

19

precision = evaluateIteration(); if (hasConverged()) { log.info("Converged at iteration: [" + iterations + "]"); log.info("Converged with precision:[" + precision + "]"); break; } } finalizeIterations(); } //more code } onde initializeIterations() e evaluateIteration() est˜a overrided na classe GradientDescent.java: @Override public void initializeIterations() { costHistory = new double[getMaximumIterations() + 1]; setFeaturesX(featuresX.addOnes()); setTheta(new Matrix(featuresX.columns(), 1)); computeCost(); } /** * */ private void computeCost() { double coeff = 1.0 / (2.0 * dataSize); final Matrix a = featuresX.multiply(theta); final Matrix b = a.subtract(outputY); final Matrix c = b.transpose(); final Matrix d = c.multiply(b); final Matrix result = d.multiply(coeff); costHistory[iterations] = result.component(0, 0); }

20

/** * theta = theta - (alpha / m) * X’ * (X * theta - y); * * b = X * theta * c = b - y * d = X’ * c * e = (alpha/m) * d * * @return */ @Override public double evaluateIteration() { double coeff = (alpha / (double) dataSize); Matrix b = featuresX.multiply(theta); Matrix c = b.subtract(outputY); Matrix d = featuresX.transpose(); Matrix e = d.multiply(c); Matrix f = e.multiply(coeff); theta = theta.subtract(f); computeCost(); double precision = costHistory[iterations] - costHistory[iterations 1]; return Math.abs(precision); } O m´etodo computeCost() refere-se a` eq.(10), para o c´alculo de J(θ). O m´etodo evaluateIteration() refere-se `a eq.(14). O Hist´orico de J(θ) ´e guardado porque serve para analisar como correram as itera¸c˜oes e, eventualemte, afinar alguns parˆametros (e.g. α) Note-se que no m´etodo initializeIterations temos featuresX.addOnes(). Estamos a adicionar uma coluna de 1 na posi¸c˜ ao 0, tal como falado na parte te´orica. Correndo o m´etodo public static void main(String[] args), obtemos os valores de θ. Adicionalmente ´e gravado um ficheiro (JGDM.txt) com o hist´ orico da fun¸c˜ao de custo, J(θ).

21

Vamos, ent˜ ao analisar os resultados. Comecemos por ver a evolu¸cao da fun¸c˜ao de custo, J(θ): C´odigo Python import matplotlib.pyplot as plt

work_dir = ’/home/manuel/tools/adalineProcesses/mlearning/dataFiles/’ input_file = ’JGDM’ ext = ’.txt’ file_to_process = work_dir + input_file + ext num_iter = [] #Numero de iteraccoes cost_func = [] #Funcao de custo

f = open(file_to_process, ’r’) for line in f: values = line.split(’,’) num_iter.append(int(values[0])) cost_func.append(float(values[1]))

f.close()

plt.plot(num_iter,cost_func) plt.xlabel(’Num. Iter.’) plt.ylabel(’J(theta)’) plt.show()

22

Nota-se a convergˆencia da fun¸c˜ ao de custo. Pode-se, no entanto, redimensionar o parˆametro α, voltar a correr e analisar novamente a evolu¸c˜ao. Se constatarmos que J(θ) aumenta, provavelmente temos de baixar o α. Para obtermos os valores de θ, fazemos (neste caso θ0

θ1

θ2 e θ ´e uma matriz coluna) temos:

gd.getTheta().component(0, 0) gd.getTheta().component(1, 0) gd.getTheta().component(2, 0) Por fim, e o grande objectivo: prever o pre¸co de um apartamento que n˜ao est´a nos dados. Tenho um apartamento para venda com 140 m2 e 3 quartos. Quanto vale? Tenho θ0 , θ1 , θ2 dados pelo c´ odigo supra. Tenho x0 = 1, x1 = 140, x2 = 3. Ent˜ao posso usar a eq. (1) para n = 3: hθ (x) = θ0 x0 + θ1 x1 + θ2 x2 try { double[][] rawData = loadFileToComponents(dataFile, ","); Matrix matrix = new Matrix(rawData); //We can check the data loaded System.out.println(matrix.toString()); //split the matrix in x (features) and y (target value) Matrix[] dMatrix = matrix.split(1); //Let’s see: Matrix x = dMatrix[0];

23

Matrix y = dMatrix[1]; System.out.println(x.toString()); System.out.println(y.toString()); //Feature normalization final FeatureNormalization ftn = new FeatNormMeanStdev(); final Matrix xNorm = ftn.normalize(x); //Check it System.out.println(xNorm.toString()); //alpha value double alpha = 0.01; //Num max iter int numIter = 400; //desired precision double precision = 0.00001; GradientDescent gd = new GradientDescent(xNorm, y, alpha); gd.setMaximumIterations(numIter); gd.setDesiredPrecision(precision); gd.evaluate(); saveArrayToFile(costHistory, gd.getCostHistory());

double x1 = 140.0; double x2 = 3; double yPrev = gd.getTheta().component(0, 0) + ((x1 - ((FeatNormMeanStdev)ftn).getMean()[0])/ ((FeatNormMeanStdev)ftn).getStdev()[0]) * gd.getTheta().component(1, 0) + ((x2 - ((FeatNormMeanStdev)ftn).getMean()[1])/ ((FeatNormMeanStdev)ftn).getStdev()[1]) * gd.getTheta().component(2, 0); System.out.println("Previsao:" + yPrev);

}

24

Aten¸c˜ao porque os valores tˆem de ser normalizados, `a semelha¸ca dos outros, antes de serem utilizados. A classe FeatNormMeanStdev.java guarda, convenientemente, as m´edias e desvio padr˜ao calculados para serem reutilizados. Finalmente, a previs˜ ao de venda d´ a: Previsao:271289.7561951509 euros

25

Lihat lebih banyak...

Comentários

Copyright © 2017 DADOSPDF Inc.