mahout数据承载之FileDataModel的一个小插曲

FileDataModel在官方说是除了装载csv,tsv文件外,还可以装载压缩文件例如zip或gzip的,mahout in action书中也是那样说的。于是我抱着学习的态度去试验了一把,结果是出人意料的报错了:

Exception in thread "main" java.util.NoSuchElementException 
    at com.google.common.collect.AbstractIterator.peek(AbstractIterator.java:169) 
    at org.apache.mahout.cf.taste.impl.model.file.FileDataModel.<init>(FileDataModel.java:193) 
    at org.apache.mahout.cf.taste.impl.model.file.FileDataModel.<init>(FileDataModel.java:169) 
    at org.apache.mahout.cf.taste.impl.model.file.FileDataModel.<init>(FileDataModel.java:149) 
    at mahout.TestRecommenderEvaluator.main(TestRecommenderEvaluator.java:26) 

于是下载了源码打开去看看到底是什么情况,也是发现了问题,改了改代码:FileLineIterator这个类中的getFileInputStream方法
static InputStream getFileInputStream(File file) throws IOException {
		InputStream is = new FileInputStream(file);
		String name = file.getName();
		if ("gz".equalsIgnoreCase(Files.getFileExtension(name.toLowerCase()))) {
			return new GZIPInputStream(is);
		} else if ("zip".equalsIgnoreCase(Files.getFileExtension(name
				.toLowerCase()))) {
			//这是我改过的
			ZipFile zf = null;
			ZipInputStream zis = null;
			try {
				zf = new ZipFile(file);
				zis = new ZipInputStream(is);
				ZipEntry entry = zis.getNextEntry();
				if (entry == null) {
					throw new IOException("空的zip压缩文件,无法获得偏好值文件");
				}
				return zf.getInputStream(entry);
			} finally {
				if (zis != null) {
					zis.close();
				}

			}
			//这是源码中的写法
			//return new ZipInputStream(is);

		} else {
			return is;
		}
	}
源码中只是返回了ZipInputStream,而不是返回zip文件中某个具体的entry的stream。所以到外层调用String firstLine = iterator.peek();会报错。

我把源码中FileLineIterator的代码全部考了出来,在项目中按照全路径建了一个一样的类,然后修改代码,可以覆盖掉JAR包中的这个类。
mahout数据承载之FileDataModel的一个小插曲_第1张图片


现在我们可以测试一下装载zip文件了,写个main方法,添加一下代码:

		DataModel dataModel = new FileDataModel(new File(
				MyFirstRecommender.class.getResource("intro.zip").getPath()));

		FastIDSet items = dataModel.getItemIDsFromUser(1);
		System.out.println(items);
可以正确的装载并打印出userid=1的所有items。

最后我也思考了一下,为什么这个问题官方都没有修复,可能是因为实际当中根本就不会去装载zip文件,zip文件只是减少了一些磁盘的开销,虽然对于偏好值这种文本文件压缩比例非常高,但是并不能减少装载偏好值文件的内存的开销,因为后面还是要把zip文件在内存中解压然后读取里面的entry,返到由于解压zip消耗了更宝贵的cpu资源。

因为目前还没有实际经验,所以只是一个个人的看法,有误也请留言指正

你可能感兴趣的:(mahout数据承载之FileDataModel的一个小插曲)