Projeção Linear em Java

5 respostas
S

Olá pessoal…
Estou com um problema bem complicado… Recebi uma planilha do excel que eu tenho que transformar para uma base de dados e gerar os relatórios via Java…
No excel eu tenho uma coluna que me mostra a progressão linear… ± assim

Delta Preço (%) Market Share (%) Progressão Linear
-9% 13,70% 0,00
-10% 14,52% -48,08
-9% 14,41% 0,00
-4% 13,67% -12,38
-5% 14,29% -8,47

No Excel, a formula usada é ÍNDICE(PROJ.LIN($D$20:D21;$B$20:B21);1)
Sendo que D são as linhas do Market Share, que eu tenho em uma variavel… e B o Delta Preço, que eu também ja carreguei em uma classe Java…
Ja tenho todos os dados separados por linha e tudo mais, só preciso saber como Transformar essa fórmula do Excel para Java…

Alguem sabe? Progressão Linear em java ?

5 Respostas

J

Não sei se serve de pontapé inicial, mas , ai vai:

Pelo que entendi a fórmula que você está utilizando no excel corresponde ao valor ‘gradient’…

m = (y - y1) / (x - x1)

e

y = m * x + c

(c é o ponto de intercessão de y, ou seja , onde ele é zero)

Obs. os valores que você passou no exemplo são reais ? porque aplicando a fórmula os resultados não batem… mesmo no excel

Abaixo um fonte de c# que encontrei para fazer o equivalente a função LINEST do excel (em português PROJ.LIN ),

/// <summary>
    /// Finds the Gradient using the Least Squares Method
    /// </summary>
    /// <returns>The y intercept of a trendline of best fit through the data X and Y</returns>
    public decimal LeastSquaresGradient()
    {

        //The DataSetsMatch method ensures that X and Y 
        //(both List<decimal> in this situation) have the same number of elements
        if (!DataSetsMatch())
        {
            throw new ArgumentException("X and Y must contain the same number of elements");
        }

        //These variables are used store the variances of each point from its associated mean
        List<decimal> varX = new List<decimal>();
        List<decimal> varY = new List<decimal>();

        foreach (decimal x in X)
        {
            varX.Add(x - AverageX());
        }
        foreach (decimal y in Y)
        {
            varY.Add(y - AverageY());
        }

        decimal topLine = 0;
        decimal bottomLine = 0;

        for (int i = 0; i < X.Count; i++)
        {
            topLine += (varX[i] * varY[i]);
            bottomLine += (varX[i] * varX[i]);
        }

        if (bottomLine != 0)
        {
            return topLine / bottomLine;
        }
        else
        {
            return 0;
        }
    }

    /// <summary>
    /// Finds the Y Intercept using the Least Squares Method
    /// </summary>
    /// <returns>The y intercept of a trendline of best fit through the data X and Y</returns>
    public decimal LeastSquaresYIntercept()
    {
        return AverageY() - (LeastSquaresGradient() * AverageX());
    }



    /// <summary>
    /// Averages the Y.
    /// </summary>
    /// <returns>The average of the List Y</returns>
    public decimal AverageX()
    {
        decimal temp = 0;
        foreach (decimal t in X)
        {
            temp += t;
        }

        if (X.Count == 0)
        {
            return 0;
        }
        return temp / X.Count;
    }

    /// <summary>
    /// Averages the Y.
    /// </summary>
    /// <returns>The average of the List Y</returns>
    public decimal AverageY()
    {
        decimal temp = 0;
        foreach (decimal t in Y)
        {
            temp += t;
        }

        if (Y.Count == 0)
        {
            return 0;
        }

        return temp / Y.Count;
    }

Adaptado para java:

public List<BigDecimal> xarray = new ArrayList<BigDecimal>();
	public List<BigDecimal> yarray = new ArrayList<BigDecimal>();
	
	public void teste() {
		
		xarray.add(new BigDecimal(-9));
		yarray.add(new BigDecimal(13.7));

		System.out.println(leastSquaresGradient()); // 0

		xarray.add(new BigDecimal(-10));
		yarray.add(new BigDecimal(14.52));
		System.out.println(leastSquaresGradient()); // -0.[telefone removido]

		xarray.add(new BigDecimal(-9));
		yarray.add(new BigDecimal(14.41));
		System.out.println(leastSquaresGradient()); // -0.[telefone removido]

		xarray.add(new BigDecimal(-4));
		yarray.add(new BigDecimal(13.67));
		System.out.println(leastSquaresGradient()); // -0.[telefone removido]

		xarray.add(new BigDecimal(-5));
		yarray.add(new BigDecimal(14.29));
		System.out.println(leastSquaresGradient()); // -0.[telefone removido]
		
		
		
	}
	
	
	/**
	 * Cálculo Gradient 
	 * @return
	 */
	
	public BigDecimal leastSquaresGradient() {

		// Variáveis utilizadas para guardar as variancias de cada ponto de sua
		// média
		List<BigDecimal> varX = new ArrayList<BigDecimal>();
		List<BigDecimal> varY = new ArrayList<BigDecimal>();

		for (BigDecimal x : xarray) {
			varX.add(x.subtract(averageX()));
		}
		for (BigDecimal y : yarray) {
			varY.add(y.subtract(averageY()));
		}

		BigDecimal topLine = BigDecimal.ZERO;
		BigDecimal bottomLine = BigDecimal.ZERO;

		for (int i = 0; i < xarray.size(); i++) {
			topLine = topLine.add(varX.get(i).multiply(varY.get(i)));
			bottomLine = bottomLine.add(varX.get(i).multiply(varX.get(i)));
		}

		if (bottomLine.compareTo(BigDecimal.ZERO)!=0) {
			return topLine.divide(bottomLine,10,RoundingMode.FLOOR);
		} else {
			return BigDecimal.ZERO;
		}
	}
	
	/**
	 * Intercept Y
	 * @return
	 */
	
	public BigDecimal leastSquaresYIntercept() {
		return averageY().subtract(leastSquaresGradient().multiply(averageX()));
	}

	/**
	 * Média de X
	 * 
	 * @return média do array xarray
	 */
	public BigDecimal averageX() {
		BigDecimal temp = BigDecimal.ZERO;
		for (BigDecimal t : xarray) {
			temp = temp.add(t);
		}

		if (xarray.size() == 0) {
			return BigDecimal.ZERO;
		}
		return temp.divide(BigDecimal.valueOf(xarray.size()),10,RoundingMode.FLOOR);
	}

	/**
	 * Média de Y
	 * 
	 * @return média do array yarray
	 */

	public BigDecimal averageY() {

		BigDecimal temp = BigDecimal.ZERO;
		for (BigDecimal t : yarray) {
			temp = temp.add(t);
		}

		if (yarray.size() == 0) {
			return BigDecimal.ZERO;
		}
		return temp.divide(BigDecimal.valueOf(yarray.size()),10,RoundingMode.FLOOR);
	}

Espero ter ajudado…

S

Po cara, é isso ai mesmo…
E Os valores bateram, é só porque o Y e o X estão invertidos…
Podes observar ali no calculo do Excel mesmo… Bateu direitinho…

Porém… alguem sabe como funciona a função Indice…?

Vlw jamir…

J

Opa, que bom que era só inversão de x e y.

Sobre a função INDEX, ela retorna uma posição de uma matriz e a função PROJ.LIN retorna uma matriz de acordo com o parâmetro [estatísticas]

PROJ.LIN(val_conhecidos_y, [val_conhecidos_x], [constante], [estatísticas])
[i]
"Estatística é um valor lógico que especifica se as estatísticas de regressão adicionais são devolvidas.

* Se a estatística for VERDADEIRO, PROJ.LIN devolve a estatística de regressão adicional, de forma a que a matriz devolvida seja {mn,mn-1,...,m1,b;sen,sen-1,...,se1,seb;r2,sey;F,df;ssreg,ssresid}.

* Se a estatística for FALSO ou omitida, PROJ.LIN devolve apenas os coeficientes m e a constante b."[/i]   <---  ou seja, o índice = 1 é o valor m e 2 é a intercessão

Dá uma olhada neste link de onde tirei as informações, tem uma explicação mais completa.

http://office.microsoft.com/pt-br/excel-help/funcao-proj-lin-HP010069838.aspx

Blz?

S

Yeap, relamente ja tinha visto esse site antes, na verdade vi mais de 100 páginas na internet buscando esse conhecimento…
O que não estou conseguindo fazer é o calculo do R2…

'R2, que indica a precisão com que a equação resultante da análise de regressão descreve a relação entre as variáveis. O valor de r2 é igual a ssreg/sstotal."

Infelizmente essa documentação não mostra qual a equação para o cálculo do sstotal e o ssreg = sstotal - ssresid…
Isso seria equivalente ao Indice(Proj.Lin(…,…,Verdadeiro);3)

J

Mais um pouco de teoria, creio que tenha exemplo de como calcular r2, SSTotal, SSResidual e SSReg:

http://www.bertolo.pro.br/Adminfin/AnalInvest/Notas%20sobre%20Regress%C3%A3o.pdf

Criado 11 de março de 2011
Ultima resposta 16 de mar. de 2011
Respostas 5
Participantes 2