1. 程式人生 > >文章相似度比較

文章相似度比較

比較兩個檔案中的文字的相似度(純文字檔案);
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 -> !"`[email protected]#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、? ".contains(s)).collect(Collectors.toList());
        }

注:文字比較相似度,主要使用HanLP分詞工具進行對語句分析,去重等操作。
得到的結果為,兩種不同格式檔案文章的相似度。