Java 使用Lucene 4.4生成术语文档矩阵
我正在尝试为一个小语料库创建术语文档矩阵,以进一步试验LSI。然而,我找不到一种方法来使用Lucene 4.4 我知道如何获取每个文档的TermVector,如下所示:Java 使用Lucene 4.4生成术语文档矩阵,java,lucene,term-document-matrix,Java,Lucene,Term Document Matrix,我正在尝试为一个小语料库创建术语文档矩阵,以进一步试验LSI。然而,我找不到一种方法来使用Lucene 4.4 我知道如何获取每个文档的TermVector,如下所示: //创建布尔查询以搜索特定文档(未显示) TopDocs hits=searcher.search(查询,1); Terms termVector=reader.getTermVector(hits.scoreDocs[0].doc,“contents”); System.out.println(termVector.size(
//创建布尔查询以搜索特定文档(未显示)
TopDocs hits=searcher.search(查询,1);
Terms termVector=reader.getTermVector(hits.scoreDocs[0].doc,“contents”);
System.out.println(termVector.size())//只是测试
我想我可以把所有的向量项合并成矩阵中的列,得到矩阵。但是,不同文档的termVector具有不同的大小。我们不知道如何将0填充到术语向量中。因此,这种方法肯定行不通
我找到了解决我问题的办法。Sujit先生给出了一个非常详细的例子,虽然代码是用Lucene的旧版本编写的,但很多东西都需要修改。我将在完成代码后更新详细信息。 这是我在Lucene 4.4上的解决方案
公共类BuildTermDocumentMatrix{
公共BuildTermDocumentMatrix(文件索引、文件语料库)引发IOException{
reader=DirectoryReader.open(FSDirectory.open(index));
搜索器=新索引搜索器(读卡器);
this.corpus=语料库;
termIdMap=computeTermIdMap(读卡器);
}
/**
*将术语映射到一个固定整数,以便我们以后可以构建文档矩阵。
*用于将术语分配到术语文档矩阵中的特定行
*/
私有映射computeTermIdMap(IndexReader阅读器)引发IOException{
Map termIdMap=newhashmap();
int id=0;
Fields=MultiFields.getFields(读卡器);
术语=字段。术语(“内容”);
TermsEnum itr=terms.iterator(null);
BytesRef term=null;
而((term=itr.next())!=null){
字符串termText=term.utf8ToString();
if(termIdMap.containsKey(termText))
继续;
//系统输出打印项次(termText);
put(termText,id++);
}
返回termIdMap;
}
/**
*为给定目录构建术语文档矩阵
*/
公共RealMatrix buildTermDocumentMatrix()引发IOException{
//遍历目录以处理每个文档
int col=0;
int numDocs=countDocs(语料库);//在此处获取文档数
int numTerms=termIdMap.size();//术语总数
RealMatrix tdMatrix=新的Array2DroArralMatrix(numTerms,numDocs);
对于(文件f:corpus.listFiles()){
如果(!f.ishiden()&&f.canRead()){
//我为语料库的一个子集建立术语文档矩阵
//我需要按路径名查找文档。
//如果您构建整个语料库,只需遍历所有文档
字符串路径=f.getPath();
BooleanQuery路径查询=新建BooleanQuery();
add(newtermquery(newterm(“path”,path)),BooleanClause.occure.SHOULD);
TopDocs hits=searcher.search(路径查询,1);
//获取项向量
Terms termVector=reader.getTermVector(hits.scoreDocs[0].doc,“contents”);
TermsEnum itr=termVector.iterator(null);
BytesRef term=null;
//计算项权重
而((term=itr.next())!=null){
字符串termText=term.utf8ToString();
int row=termIdMap.get(termText);
长期频率=itr.totalTermFreq();
long docCount=itr.docFreq();
双倍重量=计算FIDFW重量(termFreq、docCount、numDocs);
tdMatrix.setEntry(行、列、权重);
}
col++;
}
}
返回矩阵;
}
}
也可以参考此代码。在最新的Lucene版本中,这将非常简单
Example 15
public void testSparseFreqDoubleArrayConversion() throws Exception {
Terms fieldTerms = MultiFields.getTerms(index, "text");
if (fieldTerms != null && fieldTerms.size() != -1) {
IndexSearcher indexSearcher = new IndexSearcher(index);
for (ScoreDoc scoreDoc : indexSearcher.search(new MatchAllDocsQuery(), Integer.MAX_VALUE).scoreDocs) {
Terms docTerms = index.getTermVector(scoreDoc.doc, "text");
Double[] vector = DocToDoubleVectorUtils.toSparseLocalFreqDoubleArray(docTerms, fieldTerms);
assertNotNull(vector);
assertTrue(vector.length > 0);
}
}
}
您的类缺少一些函数。比如ComputeFidfweight和countDocs。此外,布尔子句不存在。我正在使用lucene 4.6。你能延长你的回答吗?我很想测试你的代码。
Example 15
public void testSparseFreqDoubleArrayConversion() throws Exception {
Terms fieldTerms = MultiFields.getTerms(index, "text");
if (fieldTerms != null && fieldTerms.size() != -1) {
IndexSearcher indexSearcher = new IndexSearcher(index);
for (ScoreDoc scoreDoc : indexSearcher.search(new MatchAllDocsQuery(), Integer.MAX_VALUE).scoreDocs) {
Terms docTerms = index.getTermVector(scoreDoc.doc, "text");
Double[] vector = DocToDoubleVectorUtils.toSparseLocalFreqDoubleArray(docTerms, fieldTerms);
assertNotNull(vector);
assertTrue(vector.length > 0);
}
}
}