/** * Gives back the relevant node based on the given radius * * @param position starting point to calculate recommendation * @param radius defines how many levels above start position should be incorporated */ public INode collectNode(INode position, int radius) { INode relevantNode = null; // Going one level up if radius parameter stills allows it if (radius > 0) { if (!position.isRoot()) { INode parent = position.getParent(); relevantNode = collectNode(parent, radius - 1); } else { relevantNode = position; } } else { relevantNode = position; } return relevantNode; }
/** * Collect all the content that should be recommended based on given user and radius * * @param position starting point to calculate recommendation * @param radiusU defines how many levels of users should be incorporated * @param radiusC defines how many levels of content should be incorporated */ public Map<INode, IAttribute> recommend(INode position, int radiusU, int radiusC) { Map<INode, IAttribute> recommendation = new HashMap<INode, IAttribute>(); // Find relevant User INode relUser = collectNode(position, radiusU); System.out.println("starting recommendation from user node: " + relUser.toString()); // collect leaf content nodes from relUser content items Set<INode> userAttributes = relUser.getAttributeKeys(); for (INode content : userAttributes) { Map<INode, IAttribute> contentLeafNodes = collectLeaves(content, null); for (INode leafNode : contentLeafNodes.keySet()) { recommendation.put(leafNode, contentLeafNodes.get(leafNode)); } } return recommendation; }
/** * Gives back the leaf nodes related to a given node * * @param position this node is the starting point to find leaves * @param leaves collection of all leaves */ public Map<INode, IAttribute> collectLeaves(INode position, Map<INode, IAttribute> leaves) { // Create leaves set if not exists if (leaves == null) { leaves = new HashMap<INode, IAttribute>(); } // If position is leaf if (position.isLeaf()) { System.out.println(position.getAttributesString()); leaves.put(position, position.getAttributeValue(position)); return leaves; } // If position is no leaf Iterator<INode> children = position.getChildren(); while (children.hasNext()) { INode child = children.next(); Map<INode, IAttribute> tempLeaves = (collectLeaves(child, leaves)); for (INode tempLeaf : tempLeaves.keySet()) { if (!leaves.keySet().contains(tempLeaf)) { leaves.put(tempLeaf, tempLeaf.getAttributeValue(tempLeaf)); } } } return leaves; }
/** * Runs a test that compares the tree calculation with the real values of a given user This * recommendation type allows to calculate an RMSE value that indicates the quality of the * recommendations produced by the clusterer */ public Map<Integer, IAttribute> runTestRecommendation(INode testNode) { // Find position of the similar node in the tree INode position = leavesMapU.get((int) testNode.getDatasetId()); if (position == null) { return null; } else { // Collect ratings of all content given by the input node Map<Integer, IAttribute> contentRatings = collectRatings(position, testNode, null); return contentRatings; } }
/** * Collect ratings of all content given by the input node * * @param position this is the starting point for collecting * @param inputNodeID this node defines the content that needs to be collected */ public Map<Integer, IAttribute> collectRatings( INode position, INode testNode, Map<Integer, IAttribute> contentRatings) { // Create Map for content of test user with empty values if not existing if (contentRatings == null) { contentRatings = new HashMap<Integer, IAttribute>(); // DatasetID, AttributeData Set<INode> testContentKeys = testNode.getAttributeKeys(); for (INode testContentKey : testContentKeys) { contentRatings.put((int) testContentKey.getDatasetId(), null); } } // Look for content nodes on the list and add it to collected ratings map Set<INode> posContentKeys = position.getAttributeKeys(); Map<Integer, IAttribute> posContentMap = new HashMap<Integer, IAttribute>(); for (INode posContentKey : posContentKeys) { // Find Dataset ID of Content Node -> FIXME: very inefficient int contentDatasetID = 0; for (Iterator<Entry<Integer, INode>> iter = leavesMapC.entrySet().iterator(); iter.hasNext(); ) { Map.Entry<Integer, INode> e = (Map.Entry<Integer, INode>) iter.next(); if (posContentKey.getId() == e.getValue().getId()) { contentDatasetID = e.getKey(); } } posContentMap.put(contentDatasetID, position.getAttributeValue(posContentKey)); } for (Entry<Integer, IAttribute> contentRating : contentRatings.entrySet()) { int datasetID = contentRating.getKey(); IAttribute rating = contentRating.getValue(); // Check if value still needs to be found if (rating == null) { try { IAttribute contentAttributes = posContentMap.get(datasetID); contentRatings.put(datasetID, posContentMap.get(datasetID)); } catch (Exception e) { System.out.println(e); } } } // Check if all movies were found if (contentRatings.containsValue(null) != true) { return contentRatings; } else { // Go one level up if possible if (position.getParent() != null) { contentRatings = collectRatings(position.getParent(), testNode, contentRatings); if (contentRatings != null) { return contentRatings; } } else { return contentRatings; } } return null; }