文章相似度比较

比较两个文件中的文本的相似度(纯文本文件);
5种文件:word、excel、ppt、pdf、txt;提取5中文件中的所有文本,作比对。计算相似度;
1.读取文件

1).读word文件

    //读取 word   path参数为文件绝对路径
  // word2003转换为2007
    public String readWord(String path) {
        String buffer = "";
        try {
            if (path.endsWith(".doc")) {
                InputStream is = new FileInputStream(new File(path));
                WordExtractor ex = new WordExtractor(is);
                buffer = ex.getText();
                ex.close();
            } else if (path.endsWith("docx")) {
                OPCPackage opcPackage = POIXMLDocument.openPackage(path);
                POIXMLTextExtractor extractor = new XWPFWordExtractor(opcPackage);
                buffer = extractor.getText();
                extractor.close();
            } else {
                System.out.println("此文件不是word文件!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buffer;
    }

2).读取PDF

        //读取PDF
    public String readPdf(String file){  
           // 是否排序  
           boolean sort = false;  
           // pdf文件名  
           String pdfFile = file;  
           // 开始提取页数  
          int startPage = 1;  
           // 结束提取页数  
           int endPage = Integer.MAX_VALUE;    
           // 内存中存储的PDF Document  
           PDDocument document = null;  
           try {  
            try {  
                
         // 首先当作一个URL来装载文件,如果得到异常再从本地文件系统//去装载文件  
             URL url = new URL(pdfFile);  
            //注意参数已不是以前版本中的URL.而是File。  
             document = PDDocument.load(pdfFile); 
             String fileName = url.getFile();  
            } catch (Exception e) {  
             // 如果作为URL装载得到异常则从文件系统装载  
            //注意参数已不是以前版本中的URL.而是File。  
             document = PDDocument.load(pdfFile);   
            }   
            // PDFTextStripper来提取文本  
            PDFTextStripper stripper = null;  
            stripper = new PDFTextStripper();  
            // 设置是否排序  
            stripper.setSortByPosition(sort);  
            // 设置起始页  
            stripper.setStartPage(startPage);  
            // 设置结束页  
            stripper.setEndPage(endPage);  
           // 调用PDFTextStripper的writeText提取并输出文本  
            String text = stripper.getText(document);
            return text;
           } finally {  
            if (document != null) {   
            document.close();  
            }  
           }  
          }

3).读txt文件

    //读取txt文件
     public static String readTxt(String path){
             File file = new File(path);
            StringBuilder result = new StringBuilder();
            try{
                BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
                String s = null;
                while((s = br.readLine())!=null){//使用readLine方法,一次读一行
                    result.append(System.lineSeparator()+s);
                }
                br.close();    
            }catch(Exception e){
                e.printStackTrace();
            }
            return result.toString();
        }

4.读取PPT

      //读取 PPT
     // 读取Powerpoint97-2003的全部内容 ppt  
     private static String getppt(byte[] file){
        String text = ""; 
        InputStream fis;
        PowerPointExtractor ex;
        try {
            //  图片不会被读取  
            fis = new ByteArrayInputStream(file);
            ex = new PowerPointExtractor(fis);
            text = ex.getText();
            ex.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
     return text;
     }
    
     
     // 抽取幻灯片2007+全部内容 pptx  
     private static String getTextFromPPT2007(byte[] file){
         InputStream is;
         XMLSlideShow slide;
             String text = "";
             try {
         is = new ByteArrayInputStream(file);
         slide = new XMLSlideShow(is);
         XSLFPowerPointExtractor extractor = new XSLFPowerPointExtractor(slide);
         text = extractor.getText();
             extractor.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }
            return text;
     }

5.读Excel

     // 读取Excel2007+的全部内容 xlsx
     private static String getTextFromExcel2007(byte[] file) {
        InputStream is;
        XSSFWorkbook workBook;
        String text = "";
        try {
        is = new ByteArrayInputStream(file);
        workBook = new XSSFWorkbook(is);
        XSSFExcelExtractor extractor = new XSSFExcelExtractor(workBook);
        extractor.setIncludeSheetNames(false);
        text = extractor.getText();
        extractor.close();
        } catch (IOException e){
        e.printStackTrace();
        }
        return text;
        }

文件转换为二进制的方法:

    //将文件转换为二进制
    public static byte[] File2byte(String filePath){
        byte[] buffer = null;
        try{
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1){
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        }catch (Exception e){
            e.printStackTrace();
        }
        return buffer;
    }

6.准备工作:

6.1.获取文件内容

        String content1 = tp.readPdf("F://test//test.pdf"); 
        String content2 = tp.readWord("F://test//test.docx");
     getSimilarity(content2, content5);//获取相似度
     //0.992801059146564

7.获取相似度的方法

        /**
         * 获得两个句子的相似度
         *
         * @param sentence1
         * @param sentence2
         * @return
         */
        public static double getSimilarity(String sentence1, String sentence2) {
            List<String> sent1Words = getSplitWords(sentence1);
            System.out.println(sent1Words);
            List<String> sent2Words = getSplitWords(sentence2);
            System.out.println(sent2Words);
            List<String> allWords = mergeList(sent1Words, sent2Words);

            int[] statistic1 = statistic(allWords, sent1Words);
            int[] statistic2 = statistic(allWords, sent2Words);

            double dividend = 0;
            double divisor1 = 0;
            double divisor2 = 0;
            for (int i = 0; i < statistic1.length; i++) {
                dividend += statistic1[i] * statistic2[i];
                divisor1 += Math.pow(statistic1[i], 2);
                divisor2 += Math.pow(statistic2[i], 2);
            }

            return dividend / (Math.sqrt(divisor1) * Math.sqrt(divisor2));
        }

        private static int[] statistic(List<String> allWords, List<String> sentWords) {
            int[] result = new int[allWords.size()];
            for (int i = 0; i < allWords.size(); i++) {
                result[i] = Collections.frequency(sentWords, allWords.get(i));
            }
            return result;
        }

        private static List<String> mergeList(List<String> list1, List<String> list2) {
            List<String> result = new ArrayList<>();
            result.addAll(list1);
            result.addAll(list2);
            return result.stream().distinct().collect(Collectors.toList());
        }

        private static List<String> getSplitWords(String sentence) {
            // 去除掉html标签
            sentence = Jsoup.parse(sentence.replace("&nbsp;","")).body().text();
            // 标点符号会被单独分为一个Term,去除之
            return HanLP.segment(sentence).stream().map(a -> a.word).filter(s -> !"`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、? ".contains(s)).collect(Collectors.toList());
        }

注:文本比较相似度,主要使用HanLP分词工具进行对语句分析,去重等操作。
得到的结果为,两种不同格式文件文章的相似度。 

posted @ 2018-11-23 13:58  atimo  阅读(2594)  评论(0编辑  收藏  举报