这两天由于项目需求,要手动构造weka的instances实例,其实weka有现成的InstanceQuery类可以直接访问数据库,一般的数据库都有支持,不过我访问的特殊点,是derbydb的数据库,weka中还真没提供此类支持,因此根据上一篇博文将org.apache.derby.jdbc.EmbeddedDriver驱动添加到weka的expeirment中的DatabaseUtils.props中,此问题得以解决,之后使用InstanceQuery检索数据库,得到Instances实例:
InstanceQuery query = new InstanceQuery();
query.setDatabaseURL(strUrl+databaseDir+";create=true");
query.setUsername("");
query.setPassword("");
query.setQuery(sql);
// if your data is sparse, then you can say so, too:
// query.setSparseData(true);
Instances data = query.retrieveInstances();
不过由于我的sql语句中检索出来的字段是自然语言的,也就是文档内容,而不是weka需要的那种数值类型的,因此需要做转换,通过研究weka中的TextDirectoryLoader发现了解决方案,TextDirectoryLoader是将一个文档数据集转换成instances的类,但是要求文档集(目录)中需要包含若干个子目录(类别),每个子目录下在包含文档列表。而我现在做的是聚类任务,另外貌似不需要分类属性,因此这个TextDirectoryLoader不太适合我,那么如何构造自己的instances,并转换成数值型呢,通过研究TextDirectoryLoader的实现,最后自己写出了一个构造instances类,并对其进行StringToWordVector转换,变成词向量,这样的数据就适合进行实验了。
关键代码如下:
public static InstancesgetInstancesFromDatabase(String whereSql) throws Exception
{
Instances data=getStructure();//获取instances框架
open();
ResultSet rs=executeSQLReturnResultSet(sql);
while(rs.next())
{
double[] newInst=new double[1]; //不算分类属性
newInst[0]=(double)data.attribute(0).addStringValue(rs.getString("字段1")+""+rs.getString("字段2"));
data.add(new Instance(1.0,newInst));
}
close();
//将字符串属性转换为表示词频的词属性向量空间
StringToWordVector filter = newStringToWordVector();
filter.setUseStoplist(true);
filter.setTFTransform(true);
filter.setIDFTransform(true);
LovinsStemmer stemmer = newLovinsStemmer ();
filter.setStemmer(stemmer);
filter.setMinTermFreq(1);
filter.setWordsToKeep(500);【】
filter.setInputFormat(data);
Instances newtrain =Filter.useFilter(data, filter);
BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile("D:\text.arff")),"UTF-8"));
bw.write(newtrain.toString());
bw.flush();
bw.close();
return newtrain;
}
publicstatic Instances getStructure()
{
FastVector atts=new FastVector();
atts.addElement(new Attribute("text",(FastVector)null));
Instances structure=new Instances("patent",atts,0);
//structure.setClassIndex(0);
return structure;
}
全文结束,新浪博客的代码显示功能真不好,以后没准去cnblogs,唉。。