文章相似度比较
比较两个文件中的文本的相似度(纯文本文件);
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(" ","")).body().text(); // 标点符号会被单独分为一个Term,去除之 return HanLP.segment(sentence).stream().map(a -> a.word).filter(s -> !"`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、? ".contains(s)).collect(Collectors.toList()); }
注:文本比较相似度,主要使用HanLP分词工具进行对语句分析,去重等操作。
得到的结果为,两种不同格式文件文章的相似度。
提莫队长