/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.mahout.cf.taste.impl.recommender.svd; import java.util.Arrays; import java.util.Map; import com.google.common.base.Preconditions; import org.apache.mahout.cf.taste.common.NoSuchItemException; import org.apache.mahout.cf.taste.common.NoSuchUserException; import org.apache.mahout.cf.taste.impl.common.FastByIDMap; /** * a factorization of the rating matrix */ public class Factorization { /** used to find the rows in the user features matrix by userID */ private final FastByIDMap<Integer> userIDMapping; /** used to find the rows in the item features matrix by itemID */ private final FastByIDMap<Integer> itemIDMapping; /** user features matrix */ private final double[][] userFeatures; /** item features matrix */ private final double[][] itemFeatures; public Factorization(FastByIDMap<Integer> userIDMapping, FastByIDMap<Integer> itemIDMapping, double[][] userFeatures, double[][] itemFeatures) { this.userIDMapping = Preconditions.checkNotNull(userIDMapping); this.itemIDMapping = Preconditions.checkNotNull(itemIDMapping); this.userFeatures = userFeatures; this.itemFeatures = itemFeatures; } public double[] getUserFeatures(long userID) throws NoSuchUserException { Integer index = userIDMapping.get(userID); if (index == null) { throw new NoSuchUserException(userID); } return userFeatures[index]; } public double[] getItemFeatures(long itemID) throws NoSuchItemException { Integer index = itemIDMapping.get(itemID); if (index == null) { throw new NoSuchItemException(itemID); } return itemFeatures[index]; } public Iterable<Map.Entry<Long,Integer>> getUserIDMappings() { return userIDMapping.entrySet(); } public Iterable<Map.Entry<Long,Integer>> getItemIDMappings() { return itemIDMapping.entrySet(); } public int numFeatures() { return userFeatures[0].length; } public int numUsers() { return userIDMapping.size(); } public int numItems() { return itemIDMapping.size(); } @Override public boolean equals(Object o) { if (o instanceof Factorization) { Factorization other = (Factorization) o; return userIDMapping.equals(other.userIDMapping) && itemIDMapping.equals(other.itemIDMapping) && Arrays.deepEquals(userFeatures, other.userFeatures) && Arrays.deepEquals(itemFeatures, other.itemFeatures); } return false; } @Override public int hashCode() { int hashCode = 31 * userIDMapping.hashCode() + itemIDMapping.hashCode(); hashCode = 31 * hashCode + Arrays.deepHashCode(userFeatures); hashCode = 31 * hashCode + Arrays.deepHashCode(itemFeatures); return hashCode; } }