Example usage for org.apache.commons.math4.optim PointValuePair getPoint

List of usage examples for org.apache.commons.math4.optim PointValuePair getPoint

Introduction

In this page you can find the example usage for org.apache.commons.math4.optim PointValuePair getPoint.

Prototype

public double[] getPoint() 

Source Link

Document

Gets the point.

Usage

From source file:delfos.rs.collaborativefiltering.als.ALSRecommender.java

@Override
public MatrixFactorizationModel buildRecommendationModel(DatasetLoader<? extends Rating> datasetLoader)
        throws CannotLoadRatingsDataset, CannotLoadContentDataset, CannotLoadUsersDataset {

    int numIter = 1;
    int dimension = 5;
    long seed = getSeedValue();

    final double lambda = 0.1;

    Bias bias = new Bias(datasetLoader);

    Map<User, List<Double>> randomUserVectors = datasetLoader.getUsersDataset().parallelStream()
            .collect(Collectors.toMap(user -> user, user -> {
                Random random = new Random(seed + user.getId());
                List<Double> vector = random.doubles(-10, 10).limit(dimension).boxed()
                        .collect(Collectors.toList());
                return vector;
            }));/* w w w. j a v a  2  s . c  o  m*/

    Map<Item, List<Double>> randomItemVectors = datasetLoader.getContentDataset().parallelStream()
            .collect(Collectors.toMap(item -> item, item -> {
                Random random = new Random(seed + item.getId());
                List<Double> vector = random.doubles(-10, 10).limit(dimension).boxed()
                        .collect(Collectors.toList());
                return vector;
            }));

    MatrixFactorizationModel model = new MatrixFactorizationModel(randomUserVectors, randomItemVectors, bias);

    for (int iterationIndex = 0; iterationIndex < numIter; iterationIndex++) {

        final int iteration = iterationIndex;
        final MatrixFactorizationModel initialModel = model;

        double error = getModelError(bias, datasetLoader, initialModel);

        System.out.println("Error in iteration " + iterationIndex + " is " + error);

        ProgressChangedController userProgress = new ProgressChangedController(
                getAlias() + " for dataset " + datasetLoader.getAlias() + " userOptimization iteration "
                        + iteration,
                datasetLoader.getUsersDataset().size(), this::fireBuildingProgressChangedEvent);

        Map<User, List<Double>> trainedUserVectors = datasetLoader.getUsersDataset().parallelStream()
                .collect(Collectors.toMap(user -> user, (User user) -> {
                    Map<Integer, ? extends Rating> userRatings = datasetLoader.getRatingsDataset()
                            .getUserRatingsRated(user.getId());

                    ObjectiveFunction objectiveFunction = new ObjectiveFunction((double[] pu) -> {
                        List<Double> userVector = Arrays.stream(pu).boxed().collect(Collectors.toList());
                        double predictionError = userRatings.values().parallelStream()
                                .map(bias.getBiasApplier()).map(rating -> {
                                    List<Double> itemVector = initialModel.getItemFeatures(rating.getItem());
                                    double prediction = IntStream.range(0, userVector.size())
                                            .mapToDouble(index -> userVector.get(index) * itemVector.get(index))
                                            .sum();

                                    double value = rating.getRatingValue().doubleValue();

                                    double errorThisRating = prediction - value;

                                    return errorThisRating;
                                }).map(value -> Math.pow(value, 2)).mapToDouble(value -> value).sum();

                        double penalty = Arrays.stream(pu).map(value -> Math.pow(value, 2)).sum();
                        double objectiveFunctionValue = predictionError + lambda * penalty;
                        return objectiveFunctionValue;
                    });

                    SimplexOptimizer simplexOptimizer = new SimplexOptimizer(0, 0);

                    double[] initialGuess = new Random(seed + user.getId()).doubles(-10, 10).limit(dimension)
                            .toArray();

                    List<Double> initialGuessList = Arrays.stream(initialGuess).boxed()
                            .collect(Collectors.toList());

                    double initialGuessPenalty = objectiveFunction.getObjectiveFunction().value(initialGuess);

                    try {
                        PointValuePair optimize = simplexOptimizer.optimize(
                                new MultiDirectionalSimplex(dimension), new InitialGuess(initialGuess),
                                objectiveFunction, GoalType.MINIMIZE, MAX_EVAL, MAX_ITER);
                        double optimizedPenalty = optimize.getValue();
                        userProgress.setTaskFinished();

                        List<Double> optimizedUserVector = Arrays.stream(optimize.getPoint()).boxed()
                                .collect(Collectors.toList());
                        return optimizedUserVector;
                    } catch (Exception ex) {
                        System.out.println("Vector cannot be optimized for user " + user + " (numRatings="
                                + userRatings.size() + ")");
                        return initialModel.getUserFeatures(user);
                    }
                }));

        ProgressChangedController itemProgress = new ProgressChangedController(
                getAlias() + " for dataset " + datasetLoader.getAlias() + " item optimization iteration "
                        + iteration,
                datasetLoader.getContentDataset().size(), this::fireBuildingProgressChangedEvent);

        Map<Item, List<Double>> trainedItemVectors = datasetLoader.getContentDataset().parallelStream()
                .collect(Collectors.toMap(item -> item, item -> {
                    Map<Integer, ? extends Rating> itemRatings = datasetLoader.getRatingsDataset()
                            .getItemRatingsRated(item.getId());

                    ObjectiveFunction objectiveFunction = new ObjectiveFunction((double[] pu) -> {
                        List<Double> itemVector = Arrays.stream(pu).boxed().collect(Collectors.toList());
                        double predictionError = itemRatings.values().parallelStream()
                                .map(bias.getBiasApplier()).map(rating -> {
                                    List<Double> userVector = initialModel.getUserFeatures(rating.getUser());
                                    double prediction = IntStream.range(0, userVector.size())
                                            .mapToDouble(index -> userVector.get(index) * itemVector.get(index))
                                            .sum();

                                    double value = rating.getRatingValue().doubleValue();

                                    double errorThisRating = prediction - value;

                                    return errorThisRating;
                                }).map(value -> Math.pow(value, 2)).mapToDouble(value -> value).sum();

                        double penalty = Arrays.stream(pu).map(value -> Math.pow(value, 2)).sum();
                        double objectiveFunctionValue = predictionError + lambda * penalty;
                        return objectiveFunctionValue;
                    });

                    SimplexOptimizer simplexOptimizer = new SimplexOptimizer(0, 0);

                    double[] initialGuess = new Random(seed + item.getId()).doubles(-10, 10).limit(dimension)
                            .toArray();

                    List<Double> initialGuessList = Arrays.stream(initialGuess).boxed()
                            .collect(Collectors.toList());

                    double initialGuessPenalty = objectiveFunction.getObjectiveFunction().value(initialGuess);

                    try {
                        PointValuePair optimize = simplexOptimizer.optimize(
                                new MultiDirectionalSimplex(dimension), new InitialGuess(initialGuess),
                                objectiveFunction, GoalType.MINIMIZE, MAX_EVAL, MAX_ITER);
                        double optimizedPenalty = optimize.getValue();
                        itemProgress.setTaskFinished();

                        List<Double> optimizedVector = Arrays.stream(optimize.getPoint()).boxed()
                                .collect(Collectors.toList());

                        return optimizedVector;
                    } catch (Exception ex) {
                        System.out.println("Vector cannot be optimized " + item
                                + " cannot be optimized (numRatings=" + itemRatings.size() + ")");
                        return initialModel.getItemFeatures(item);
                    }
                }));

        model = new MatrixFactorizationModel(trainedUserVectors, trainedItemVectors, bias);

    }
    return model;

}