Skip to content

Commit

Permalink
Mahout's DataModel as DataModel for issue #83
Browse files Browse the repository at this point in the history
  • Loading branch information
abellogin committed Sep 6, 2016
1 parent 4dc7001 commit 84a2579
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 0 deletions.
7 changes: 7 additions & 0 deletions rival-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,17 @@
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.0</version>
</dependency>

<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-core</artifactId>
<version>${mahout.version}</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package net.recommenders.rival.core;

import net.recommenders.rival.core.ext.MahoutDataModel;

/**
*
* @author <a href="http://github.com/abellogin">Alejandro</a>
Expand All @@ -33,4 +35,7 @@ public static <U, I> TemporalDataModelIF<U, I> getSimpleTemporalModel() {
return new TemporalDataModel<>();
}

public static TemporalDataModelIF<Long, Long> getMahoutTemporalModel() {
return new MahoutDataModel();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* Copyright 2016 recommenders.net.
*
* Licensed 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 net.recommenders.rival.core.ext;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.recommenders.rival.core.TemporalDataModelIF;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.FastByIDMap;
import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
import org.apache.mahout.cf.taste.impl.model.GenericPreference;
import org.apache.mahout.cf.taste.model.Preference;
import org.apache.mahout.cf.taste.model.PreferenceArray;

/**
*
* @author <a href="http://github.com/abellogin">Alejandro</a>
*/
public class MahoutDataModel implements TemporalDataModelIF<Long, Long> {

private GenericDataModel model;
private FastByIDMap<Collection<Preference>> data;
private FastByIDMap<FastByIDMap<Long>> timestampData;

public MahoutDataModel() {
model = null;
data = new FastByIDMap<Collection<Preference>>();
timestampData = new FastByIDMap<FastByIDMap<Long>>();
}

private void generateDatamodel() {
FastByIDMap<PreferenceArray> userData = GenericDataModel.toDataMap(data, true);
model = new GenericDataModel(userData, timestampData);
data = null;
timestampData = null;
}

@Override
public void addPreference(Long u, Long i, Double d) {
if (model != null) {
throw new IllegalArgumentException("DataModel already generated. It is not possible to add more information.");
}
Collection<Preference> prefs = null;
if (!data.containsKey(u)) {
prefs = new ArrayList<Preference>();
data.put(u, prefs);
} else {
prefs = data.get(u);
}
prefs.add(new GenericPreference(u, i, d.floatValue()));
}

@Override
public void addTimestamp(Long u, Long i, Long t) {
if (model != null) {
throw new IllegalArgumentException("DataModel already generated. It is not possible to add more information.");
}
FastByIDMap<Long> prefs = null;
if (!timestampData.containsKey(u)) {
prefs = new FastByIDMap<Long>();
timestampData.put(u, prefs);
} else {
prefs = timestampData.get(u);
}
prefs.put(i, t);
}

@Override
public Double getUserItemPreference(Long u, Long i) {
if (model == null) {
generateDatamodel();
}
try {
return model.getPreferenceValue(u, i) * 1.0;
} catch (TasteException e) {
e.printStackTrace();
}
return Double.NaN;
}

@Override
public Iterable<Long> getUserItemTimestamps(Long u, Long i) {
if (model == null) {
generateDatamodel();
}
List<Long> t = new ArrayList<>();
try {
t.add(model.getPreferenceTime(u, i));
} catch (TasteException e) {
e.printStackTrace();
}
return t;
}

@Override
public Iterable<Long> getUserItems(Long u) {
if (model == null) {
generateDatamodel();
}
try {
return model.getItemIDsFromUser(u);
} catch (TasteException e) {
e.printStackTrace();
}
return null;
}

@Override
public Iterable<Long> getItems() {
if (model == null) {
generateDatamodel();
}
List<Long> items = new ArrayList<>();
LongPrimitiveIterator lpi = model.getItemIDs();
while (lpi.hasNext()) {
items.add(lpi.nextLong());
}
return items;
}

@Override
public Iterable<Long> getUsers() {
if (model == null) {
generateDatamodel();
}
List<Long> users = new ArrayList<>();
LongPrimitiveIterator lpi = model.getUserIDs();
while (lpi.hasNext()) {
users.add(lpi.nextLong());
}
return users;
}

@Override
public int getNumItems() {
if (model == null) {
generateDatamodel();
}
return model.getNumItems();
}

@Override
public int getNumUsers() {
if (model == null) {
generateDatamodel();
}
return model.getNumUsers();
}

@Override
public void clear() {
model = null;
data = new FastByIDMap<Collection<Preference>>();
timestampData = new FastByIDMap<FastByIDMap<Long>>();
}
}

0 comments on commit 84a2579

Please sign in to comment.