Author: srowen
Date: Tue Jan 20 14:24:40 2009
New Revision: 736137
URL: http://svn.apache.org/viewvc?rev=736137&view=rev
Log:
Add a few handy methods to IOUtils, improve TanimotoCoefficientSimilarity and
pull out useless log statements
Modified:
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/IOUtils.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/BooleanTanimotoCoefficientSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/LogLikelihoodSimilarity.java
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java
Modified:
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/IOUtils.java
URL:
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/IOUtils.java?rev=736137&r1=736136&r2=736137&view=diff
==============================================================================
---
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/IOUtils.java
(original)
+++
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/IOUtils.java
Tue Jan 20 14:24:40 2009
@@ -22,10 +22,17 @@
import java.io.Closeable;
import java.io.IOException;
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.ByteArrayOutputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.net.URL;
+import java.nio.charset.Charset;
/**
* <p>I/O-related utility methods that don't have a better home.</p>
@@ -94,4 +101,37 @@
quietClose(connection);
}
+ public static void copyStreamToFile(InputStream in, File file) throws
IOException {
+ OutputStream out = new FileOutputStream(file, false);
+ copyInToOut(in, out);
+ }
+
+ public static String readURL(URL url) throws IOException {
+ InputStream in = url.openStream();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ copyInToOut(in, out);
+ return new String(out.toByteArray(), Charset.forName("UTF-8"));
+ }
+
+ public static File createTempFile(String copySuffixFrom) throws IOException {
+ int period = copySuffixFrom.lastIndexOf('.');
+ String suffix = period < 0 ? "" : copySuffixFrom.substring(period);
+ File tempFile = File.createTempFile("mahout-taste-", suffix);
+ tempFile.deleteOnExit();
+ return tempFile;
+ }
+
+ public static void copyInToOut(InputStream in, OutputStream out) throws
IOException {
+ try {
+ int bytesRead;
+ byte[] buffer = new byte[65536];
+ while ((bytesRead = in.read(buffer)) > 0) {
+ out.write(buffer, 0, bytesRead);
+ }
+ } finally {
+ quietClose(in);
+ quietClose(out);
+ }
+ }
+
}
Modified:
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/BooleanTanimotoCoefficientSimilarity.java
URL:
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/BooleanTanimotoCoefficientSimilarity.java?rev=736137&r1=736136&r2=736137&view=diff
==============================================================================
---
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/BooleanTanimotoCoefficientSimilarity.java
(original)
+++
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/BooleanTanimotoCoefficientSimilarity.java
Tue Jan 20 14:24:40 2009
@@ -25,19 +25,19 @@
import org.apache.mahout.cf.taste.impl.model.BooleanPrefUser;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.User;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.Collection;
/**
- * Variant of {...@link TanimotoCoefficientSimilarity} which is appropriate
- * for use with the "boolean" classes like {...@link BooleanPrefUser}
+ * <p>Variant of {...@link TanimotoCoefficientSimilarity} which is appropriate
+ * for use with the "boolean" classes like {...@link BooleanPrefUser}.</p>
+ *
+ * <p>If you need an {...@link
org.apache.mahout.cf.taste.similarity.ItemSimilarity},
+ * just use {...@link
org.apache.mahout.cf.taste.impl.similarity.TanimotoCoefficientSimilarity},
+ * even with "boolean" classes.</p>
*/
public final class BooleanTanimotoCoefficientSimilarity implements
UserSimilarity {
- private static final Logger log =
LoggerFactory.getLogger(BooleanTanimotoCoefficientSimilarity.class);
-
private final DataModel dataModel;
public BooleanTanimotoCoefficientSimilarity(DataModel dataModel) {
@@ -71,12 +71,7 @@
int unionSize = prefs1.size() + prefs2.size() - intersectionSize;
- double result = (double) intersectionSize / (double) unionSize;
-
- if (log.isTraceEnabled()) {
- log.trace("User similarity between " + user1 + " and " + user2 + " is "
+ result);
- }
- return result;
+ return (double) intersectionSize / (double) unionSize;
}
Modified:
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/LogLikelihoodSimilarity.java
URL:
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/LogLikelihoodSimilarity.java?rev=736137&r1=736136&r2=736137&view=diff
==============================================================================
---
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/LogLikelihoodSimilarity.java
(original)
+++
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/LogLikelihoodSimilarity.java
Tue Jan 20 14:24:40 2009
@@ -37,6 +37,9 @@
this.dataModel = dataModel;
}
+ // TODO also implement UserSimilarity if someone wants it
+ // This would involve refactoring out the bits that are similar to
TanimotoCoefficientSimilarity
+
@Override
public double itemSimilarity(Item item1, Item item2) throws TasteException {
if (item1 == null || item2 == null) {
Modified:
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java
URL:
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java?rev=736137&r1=736136&r2=736137&view=diff
==============================================================================
---
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java
(original)
+++
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java
Tue Jan 20 14:24:40 2009
@@ -27,8 +27,6 @@
import org.apache.mahout.cf.taste.model.Item;
import org.apache.mahout.cf.taste.model.Preference;
import org.apache.mahout.cf.taste.model.User;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.Collection;
@@ -46,8 +44,6 @@
*/
public final class TanimotoCoefficientSimilarity implements UserSimilarity,
ItemSimilarity {
- private static final Logger log =
LoggerFactory.getLogger(TanimotoCoefficientSimilarity.class);
-
private final DataModel dataModel;
public TanimotoCoefficientSimilarity(DataModel dataModel) {
@@ -110,68 +106,18 @@
int unionSize = xPrefs.length + yPrefs.length - intersectionSize;
- double result = (double) intersectionSize / (double) unionSize;
-
- if (log.isTraceEnabled()) {
- log.trace("User similarity between " + user1 + " and " + user2 + " is "
+ result);
- }
- return result;
+ return (double) intersectionSize / (double) unionSize;
}
@Override
public double itemSimilarity(Item item1, Item item2) throws TasteException {
-
if (item1 == null || item2 == null) {
throw new IllegalArgumentException("item1 or item2 is null");
}
-
- Preference[] xPrefs =
dataModel.getPreferencesForItemAsArray(item1.getID());
- Preference[] yPrefs =
dataModel.getPreferencesForItemAsArray(item2.getID());
-
- if (xPrefs.length == 0 && yPrefs.length == 0) {
- return Double.NaN;
- }
- if (xPrefs.length == 0 || yPrefs.length == 0) {
- return 0.0;
- }
-
- Preference xPref = xPrefs[0];
- Preference yPref = yPrefs[0];
- User xIndex = xPref.getUser();
- User yIndex = yPref.getUser();
- int xPrefIndex = 1;
- int yPrefIndex = 1;
-
- int intersectionSize = 0;
- while (true) {
- int compare = xIndex.compareTo(yIndex);
- if (compare == 0) {
- intersectionSize++;
- }
- if (compare <= 0) {
- if (xPrefIndex == xPrefs.length) {
- break;
- }
- xPref = xPrefs[xPrefIndex++];
- xIndex = xPref.getUser();
- }
- if (compare >= 0) {
- if (yPrefIndex == yPrefs.length) {
- break;
- }
- yPref = yPrefs[yPrefIndex++];
- yIndex = yPref.getUser();
- }
- }
-
- int unionSize = xPrefs.length + yPrefs.length - intersectionSize;
-
- double result = (double) intersectionSize / (double) unionSize;
-
- if (log.isTraceEnabled()) {
- log.trace("Item similarity between " + item1 + " and " + item2 + " is "
+ result);
- }
- return result;
+ int preferring1and2 =
dataModel.getNumUsersWithPreferenceFor(item1.getID(), item2.getID());
+ int preferring1 = dataModel.getNumUsersWithPreferenceFor(item1.getID());
+ int preferring2 = dataModel.getNumUsersWithPreferenceFor(item2.getID());
+ return (double) preferring1and2 / (double) (preferring1 + preferring2 -
preferring1and2);
}
@Override