0

当我使用胡萝卜 2 网络应用程序将我自己的数据与 lucene 索引进行聚类时,我发现结果与我的预期不同。

错误一: [在右边的结果列表中只列出了集群文件名,没有匹配的文本段落和文件位置,我不确定是什么导致的问题,我猜可能是我使用lucene创建索引文件格式时错了,还是我的配置carrot2 web-app项目有问题,希望有人能告诉我答案][抱歉我的图片不能po,你可以看图二。]

错误二: 我发现我的搜索结果显示“其他主题”不仅仅是一个特定的主题,它困扰着我。我认为可能是聚类算法有问题或者是我提供的测试数据主题太少的原因。

当我使用K-means聚类算法时,结果出来了很多主题,但没有具体的主题名称,只有文件名。

如果有人可以回答我的疑问,我将不胜感激,您的回答会有所帮助。

这是我创建 lucene 索引文件的代码:

  package test2;

import org.apache.lucene.index.IndexFileNames;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Version;
import org.carrot2.source.lucene.SimpleFieldMapper;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.FileReader;


//lucene 4.9
public class LuceneDemo2 {
    public static void main(String[] args) throws Exception {
        String indexDir = "D:\\data\\lucene\\odp\\index-all";
        String dataDir = "D:\\data";

        long start = System.currentTimeMillis();
        LuceneDemo2 indexer = new LuceneDemo2(indexDir);

        int numIndexed;
        try {
            numIndexed = indexer.index(dataDir,new TextFilesFilter());
        } finally {
            indexer.close();
        }
        long end = System.currentTimeMillis();

        System.out.println("Indexing " + numIndexed + " files took " + (end-start) + " milliseconds.");
    }

    private IndexWriter writer;

    public LuceneDemo2(String indexDir) throws IOException {
        // TODO Auto-generated constructor stub
        Directory directory = FSDirectory.open(new File(indexDir));
        Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_9);
        IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_9,analyzer);
        config.setOpenMode(OpenMode.CREATE);
        writer = new IndexWriter(directory,config);
    }

    public void close() throws IOException {
        writer.close();
    }

    public int index (String dataDir,FileFilter filter) throws Exception {
        File[] files = new File(dataDir).listFiles();

        //if(files == null) return writer.numDocs();
        for(File f: files) {
            if(!f.isDirectory()&&
                !f.isHidden()&&
                f.exists()&&
                f.canRead()&&
                (filter == null || filter.accept(f))) {
                indexFile(f);
            }
        }

        /*
        if(files == null) return writer.numDocs();
        for(int i=0;i<files.length&&files!=null;i++) {
            if(!files[i].isDirectory()&&
                !files[i].isHidden()&&
                files[i].exists()&&
                files[i].canRead()&&
                (filter == null || filter.accept(files[i]))) {
                indexFile(files[i]);
            }
        }
        */
        return writer.numDocs();
    }

    private static class TextFilesFilter implements FileFilter {
        public boolean accept(File path) {
            return path.getName().toLowerCase().endsWith(".txt");
        }   
    }

    private Document getDocument(File f) throws Exception {
        // TODO Auto-generated method stub
        Document document = new Document();
        document.add(new StringField("path",  f.getAbsolutePath(), Field.Store.YES));
        document.add(new LongField("modified", f.lastModified(), Field.Store.NO)); 
        document.add(new TextField("content", new FileReader(f)));
        document.add(new TextField("title", f.getName(), Field.Store.YES));

        return document;
    }

    private void indexFile(File f) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("Indexing "+ f.getCanonicalPath());
        Document document = getDocument(f);
        writer.addDocument(document);
    }   
}

这是我的索引 PDF 文件代码(其中的一部分):

private void indexFile(File f) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("Indexing "+ f.getCanonicalPath());
        //Document d = LucenePDFDocument.getDocument(f);
        String executeStr = "D:\\xpdf\\xpdfbin-win-3.04\\bin64\\pdftotext.exe";
        String[] cmd = new String[]{executeStr,"-enc","UTF-8","-q",f.getAbsolutePath(),"-"};  
        String str = null ; 
        Process p = null ;     
        BufferedReader br = null ;  
        StringBuffer sb = new StringBuffer() ;
        try {  
            p = Runtime.getRuntime().exec(cmd) ;               
            br = new BufferedReader(new InputStreamReader(p.getInputStream(),"UTF-8")) ;    
            while((str = br.readLine() ) != null ){  
                sb.append(str).append("\n") ;  
            }               
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } finally{  
            if (br != null){  
                try {  
                    br.close() ;  
                } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        }  
        String content = sb.toString();
        Document document = new Document();
        document.add(new StringField("url",  f.getAbsolutePath(), Store.YES));
        document.add(new TextField("content", content,Store.YES));
        document.add(new TextField("title", f.getName(), Store.YES));
        writer.addDocument(document);
    }   
4

1 回答 1

1

Carrot2 算法对文档的原始文本进行操作,因此需要存储您想要聚类的所有内容字段 ( Field.Store.YES)。要将“内容”字段存储在索引中,最简单的解决方案是将相应文件的内容读入 a String,然后使用类的基于字符串的构造函数TextField

一旦您重新索引您的内容并将 Carrot2 设置为基于您的“标题”和“内容”字段的集群,您应该会看到一些有意义的集群。

于 2016-05-10T08:26:14.507 回答