文章相似度比較
阿新 • • 發佈:2018-11-23
比較兩個檔案中的文字的相似度(純文字檔案);
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 = newFileInputStream(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(" ","")).body().text(); // 標點符號會被單獨分為一個Term,去除之 return HanLP.segment(sentence).stream().map(a -> a.word).filter(s -> !"`[email protected]#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、? ".contains(s)).collect(Collectors.toList()); }
注:文字比較相似度,主要使用HanLP分詞工具進行對語句分析,去重等操作。
得到的結果為,兩種不同格式檔案文章的相似度。