package com.rdlze.radializebase.utils; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.mahout.cf.taste.impl.common.FastByIDMap; /** * * @author Alex Amorim Dutra * */ public class MathNervous { /** * Normaliza os valores do Map entre 0 e 1. * * @param idsValues * @return */ public FastByIDMap normalizingValues(FastByIDMap idsValues) { float maxValue = -99999999; float minValue = 99999999; Iterator iteratorValues = idsValues.keySetIterator(); while (iteratorValues.hasNext()) { long id = iteratorValues.next(); float value = idsValues.get(id); if (maxValue < value) maxValue = value; if (minValue > value) minValue = value; idsValues.put(id, value); } FastByIDMap mapToReturn = new FastByIDMap(); iteratorValues = idsValues.keySetIterator(); while (iteratorValues.hasNext()) { long id = iteratorValues.next(); float value = idsValues.get(id); float newValue = 0; if ((maxValue - minValue) == 0) { newValue = 0.0f; } else { newValue = (value - minValue) / (maxValue - minValue); } mapToReturn.put(id, newValue); } return mapToReturn; } /** * Normaliza os valores do Map entre o menor valor desejado e o maior valor * desejado. * * @param idsValues * @return */ public FastByIDMap normalizingValues(FastByIDMap idsValues, float minValueDesired, float maxValueDesired) { float realMaxValue = -99999999; float realMinValue = 99999999; Iterator iteratorValues = idsValues.keySetIterator(); while (iteratorValues.hasNext()) { long id = iteratorValues.next(); float value = idsValues.get(id); if (realMaxValue < value) realMaxValue = value; if (realMinValue > value) realMinValue = value; idsValues.put(id, value); } FastByIDMap mapToReturn = new FastByIDMap(); iteratorValues = idsValues.keySetIterator(); while (iteratorValues.hasNext()) { long id = iteratorValues.next(); float value = idsValues.get(id); float newValue = 0; if ((realMaxValue - realMinValue) == 0) { newValue = maxValueDesired; } else { newValue = minValueDesired + ((value - realMinValue) * (maxValueDesired - minValueDesired)) / (realMaxValue - realMinValue); } mapToReturn.put(id, newValue); } return mapToReturn; } public FastByIDMap normalizingSortedList( List listToNormalize) { float maxValue = 100; FastByIDMap mapToReturn = new FastByIDMap(); for (AIRecommendedItem item : listToNormalize) { mapToReturn.put(item.getItemID(), maxValue); // evita que os valores ficam abaixo de 20, pois isto atrapalha para // mostrar no front-end. if (maxValue > 80) maxValue -= 4; else if (maxValue > 60) maxValue -= 3; else if (maxValue > 50) maxValue -= 2; else if (maxValue > 30) maxValue -= 1; else if (maxValue > 20) maxValue -= 0.5; } return mapToReturn; } public FastByIDMap normalizingSortedListRadio( List listToNormalize) { // Pelo fato dos nomes das rádios serem maiores então é feita uma // normalização mais agressiva quanto as diferenças de valores. float maxValue = 100; FastByIDMap mapToReturn = new FastByIDMap(); for (AIRecommendedItem item : listToNormalize) { mapToReturn.put(item.getItemID(), maxValue); if (maxValue > 89) maxValue -= 5; else if (maxValue > 60) maxValue -= 4; else if (maxValue > 40) maxValue -= 3; else if (maxValue > 30) maxValue -= 1.5; else if (maxValue > 20) maxValue -= 0.5; } return mapToReturn; } /** * Normaliza os valores utilizando ZScore. * * @param idValue * @return */ public FastByIDMap normalizingValuesZScore(FastByIDMap idValue) { List values = new ArrayList(); Iterator iteratorValues = idValue.keySetIterator(); while (iteratorValues.hasNext()) { long id = iteratorValues.next(); float value = idValue.get(id); values.add(value); idValue.put(id, value); } float mean = getMean(values); float desvPad = getStandardDeviation(values); FastByIDMap mapReturn = new FastByIDMap(); iteratorValues = idValue.keySetIterator(); while (iteratorValues.hasNext()) { long id = iteratorValues.next(); float value = idValue.get(id); float newValue = (value - mean) / desvPad; mapReturn.put(id, newValue); if (Float.isNaN(value)) value = 0.f; idValue.put(id, value); } return mapReturn; } /** * Calcula a media dos valores. * * @param values * @return */ public float getMean(List values) { float totalValue = 0; for (Float value : values) totalValue += value; if (totalValue == 0) return 0; return totalValue / values.size(); } /** * Calcula o desvio padrao dos valores. * * @param values * @return */ public float getStandardDeviation(List values) { float mean = getMean(values); float totalValue = 0; for (Float value : values) { totalValue += Math.pow((value - mean), 2); } float desvPad = (float) Math.sqrt(totalValue / (values.size() - 1)); return desvPad; } /** * Cada item contem uma lista de valores de Features. * * @param idValuesFeatures * @return */ public FastByIDMap> normalizingValuesMap( FastByIDMap> idValuesFeatures) { FastByIDMap> valuesNormalized = new FastByIDMap>(); // normaliza feature por feature de cada item. // primeira feature itera sobre todos itens. int size = 1; for (int i = 0; i < size; i++) { FastByIDMap idValue = new FastByIDMap(); Iterator iteratorIds = idValuesFeatures.keySetIterator(); while (iteratorIds.hasNext()) { long id = iteratorIds.next(); List features = idValuesFeatures.get(id); size = features.size(); float value = features.get(i); idValue.put(id, value); } FastByIDMap mapReturn = normalizingValues(idValue); iteratorIds = mapReturn.keySetIterator(); while (iteratorIds.hasNext()) { long id = iteratorIds.next(); float value = mapReturn.get(id); List features = idValuesFeatures.get(id); // setando o valor normalizado features.set(i, value); valuesNormalized.put(id, features); } } return valuesNormalized; } /** * Cada item contem uma lista de valores de Features. * * @param idValuesFeatures * @return */ public FastByIDMap> normalizingValuesZScoreMap( FastByIDMap> idValuesFeatures) { FastByIDMap> valuesNormalized = new FastByIDMap>(); // normaliza feature por feature de cada item. // primeira feature itera sobre todos itens. int size = 1; for (int i = 0; i < size; i++) { FastByIDMap idValue = new FastByIDMap(); Iterator iteratorIds = idValuesFeatures.keySetIterator(); while (iteratorIds.hasNext()) { long id = iteratorIds.next(); List features = idValuesFeatures.get(id); size = features.size(); float value = features.get(i); if (Float.isNaN(value)) value = 0.0f; idValue.put(id, value); } FastByIDMap mapReturn = normalizingValuesZScore(idValue); iteratorIds = mapReturn.keySetIterator(); while (iteratorIds.hasNext()) { long id = iteratorIds.next(); float value = mapReturn.get(id); List features = idValuesFeatures.get(id); // setando o valor normalizado if (Float.isNaN(value)) value = 0.0f; features.set(i, value); valuesNormalized.put(id, features); } } return valuesNormalized; } public float getMax(List values) { float max = -99999999999999999999999999999999999999.f; for (float value : values) { if (max < value) max = value; } return max; } public float getMin(List values) { float min = 99999999999999999999999999999999999999.f; for (float value : values) { if (min > value) min = value; } return min; } public float getCoefficientVariation(List values) { float mean = getMean(values); float totalValue = 0; for (Float value : values) totalValue += Math.pow((value - mean), 2); float desvPad = (float) Math.sqrt(totalValue / (values.size() - 1)); float cv = desvPad / mean; return cv; } public double normalizingValues(double value, double realMinValue, double realMaxValue, double minValueDesired, double maxValueDesired) { double newValue = 0; if ((realMaxValue - realMinValue) == 0) { newValue = minValueDesired; } else { newValue = minValueDesired + ((value - realMinValue) * (maxValueDesired - minValueDesired)) / (realMaxValue - realMinValue); } // if (newValue < value) // System.out.println("MINVALUEDESIRED " + minValueDesired // + " VALUE " + value + " MAXVALUEDESIRED " // + maxValueDesired + " REALMINVALUE " + realMinValue // + " REALMAXVALUE " + realMaxValue+" NEWVALUE "+newValue); return newValue; } public static void main(String[] args) { List values = new ArrayList(); values.add(2.f); values.add(2.f); values.add(2.f); values.add(120.f); MathNervous normalizing = new MathNervous(); double realMinValue = 0.2; System.out.println("OKK " + normalizing.normalizingValues(0.27, realMinValue, 0.27, realMinValue, 40)); System.out.println("Mean " + normalizing.getMean(values)); System.out.println("DesvPad " + normalizing.getStandardDeviation(values)); FastByIDMap idValue = new FastByIDMap(); idValue.put(1, 0.f); idValue.put(2, 2.f); idValue.put(3, 500.f); idValue.put(4, 1000.f); System.out.println("Normalizing " + normalizing.normalizingValues(idValue)); System.out.println("Normalizing Min and Max " + normalizing.normalizingValues(idValue, 1, 80)); System.out.println("ZScore " + normalizing.normalizingValuesZScore(idValue)); } }