Example usage for org.apache.commons.math4.optim.nonlinear.scalar.noderiv SimplexOptimizer SimplexOptimizer

List of usage examples for org.apache.commons.math4.optim.nonlinear.scalar.noderiv SimplexOptimizer SimplexOptimizer

Introduction

In this page you can find the example usage for org.apache.commons.math4.optim.nonlinear.scalar.noderiv SimplexOptimizer SimplexOptimizer.

Prototype

public SimplexOptimizer(double rel, double abs) 

Source Link

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;
            }));/*from  www  .ja va 2 s .  co  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;

}