Java, Machine Learning, Text mining

Проверка моделей с помощью Java

Время прочтения: 4 мин.

В чем заключается проверка модели? После того как модель разработана, по ней проводится ряд регламентированных тестов. Так вот, помимо проверки логики работы модели, нам нужно проверять сам факт проведения регламентированных тестов, а также их корректность. Таким образом, определённое количество тестов плюс их результаты должны быть стандартно обработаны.

Вот мы и решили, а давайте с помощью мощи языка Java соберем для этих целей собственную Machine Learning библиотеку, используя элементарные методы и работу с файлами и изображениями. Для начала, реализуем функционал считывания файлов с отчетами. В нашем случае это документы формата .docx. Для этого воспользуемся классами XWPFDocument и XWPFParagraph библиотеки Apache POI.

public List<String> readFile (String path) {
    List<String> lines = new ArrayList<>();
    File docxFile = new File(path);
    FileInputStream fileInputStream = null;
    XWPFDocument xwpfDocument = null;
    try {
        fileInputStream = new FileInputStream(docxFile.getAbsolutePath());
        xwpfDocument = new XWPFDocument(fileInputStream);
    } catch (IOException e) {
        e.printStackTrace();
    }
    List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs();

    for (XWPFParagraph p : paragraphs) {
        lines.add(p.getText());
    }
    return lines;

Следующим шагом можно проанализировать текстовую часть, а именно, определить, где в тексте находится информация по каждому из тестов. Здесь нам поможет Text Mining модуль с методами регулярных выражений. На выходе мы получаем информацию о том, проводился тест или нет, а также о его позиции в тексте. Ниже приведен упрощенный метод поиска позиции нужного нам теста в отчете и определения проводился тест или нет.

public String findString (String searchString, List<String> lines) {
    boolean marker = false;
    String result = "Не найдено";
    Pattern patternStart = Pattern.compile(searchString);
    Pattern patternEnd = Pattern.compile("Конец теста.");
    Pattern patternNotRun = Pattern.compile(searchString + ".+Не проводился.");
    List <String> cutLines = new ArrayList<>();
    cutLines.addAll(lines);
    int cut = 0;
    for (String i:lines) {
        if (!marker) {

            Matcher matcherStart = patternStart.matcher(i);
            while (matcherStart.find()) {
                result = "\nНомер абзатца " + lines.indexOf(i) + "\nПозиция начала теста "
                        + matcherStart.start();
                Matcher matcherEnd = patternEnd.matcher(i);
                while (matcherEnd.find()) {
                    result += "\nНомер абзатца " + (cutLines.indexOf(i) + cut) + "\nПозиция конца теста "
                            + matcherEnd.end();
                }
                marker = true;
            }

            Matcher matcherNotRun = patternNotRun.matcher(i);
            while (matcherNotRun.find()) {
                result = "Тест не проводился!" + "\nНомер абзатца " + (cutLines.indexOf(i) + cut) + "\nПозиция начала теста "
                        + matcherNotRun.start() + "\nПозиция конца теста " + matcherNotRun.end();
                marker = false;
            }

        } else {
            Matcher matcherEnd = patternEnd.matcher(i);
            while (matcherEnd.find()) {
                result += "\nНомер абзатца " + (cutLines.indexOf(i) + cut) + "\nПозиция конца теста "
                        + matcherEnd.end();
                return result;
            }
        }

        cutLines.remove(0);
        cut += 1;

    }
    return result;
}

Как уже упоминалось ранее, у нас отчеты снабжаются типовыми графиками и диаграммами, которые нам необходимо проверить на соответствие требуемому формату в рамках каждого из тестов. Для этого, на основании информации об абзацах, в которых находится необходимый нам текст, получим информацию об изображениях с помощью модуля распознавания изображений.

public List<XWPFPictureData> readPictureFromFile (String path, int positionStart, int positionEnd) {
    List<XWPFPictureData> lines = new ArrayList<>();
    FileReader fileReader = new FileReader();
    XWPFDocument xwpfDocument = fileReader.getDocument(path);

    List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs();

    XWPFDocument sum = null;

    for (int x = positionStart; x <= positionEnd; x = x + 1) {
        List <XWPFPictureData> par = paragraphs.get(x).getDocument().getAllPictures();
        try {
            CTPicture ctPicture = CTPicture.Factory.parse(paragraphs.get(x).getCTP().toString());
            System.out.println(ctPicture);
        } catch (XmlException e) {
            e.printStackTrace();
        }

        lines.addAll(par);


    }

    return lines;

}

Следующий блок позволит нам получить информацию о том, проведен ли анализ в рамках теста и отражены ли все необходимые данные. Ниже приведен код для поиска картинок в фрагменте текста и последующего их сохранения.

public void findImg (XWPFDocument document) {
    List lst = document.getAllPictures();
    for (Iterator i = lst.iterator(); i.hasNext(); ) {
        XWPFPictureData picture = (XWPFPictureData) i.next();
        String sug = picture.suggestFileExtension();
        byte[] pictureGet = picture.getData();
        if (sug.equals("jpeg")) {
            FileOutputStream stream = null;
            try {
                stream = new FileOutputStream("График.jpg");
                stream.write(pictureGet);
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

Для определения корректности формирования графика реализована модель попиксельного сравнения картинок.

public float compareImg (File report, File control) {

    float percent = 0;
    try {
        BufferedImage img1 = ImageIO.read(report);
        DataBuffer dataBuffer1 = img1.getData().getDataBuffer();
        int size1 = dataBuffer1.getSize();
        BufferedImage img2 = ImageIO.read(control);
        DataBuffer dataBuffer2 = img2.getData().getDataBuffer();
        int size2 = dataBuffer2.getSize();
        int count = 0;
        if (size1 == size2) {

            for (int i = 0; i < size1; i++) {

                if (dataBuffer1.getElem(i) == dataBuffer2.getElem(i)) {
                    count = count + 1;
                }

            }
            percent = (count * 100) / size1;
        } else {
            System.out.println("Изображения имеют разный размер");
        }

    } catch (Exception e) {
        System.out.println("Не удалось сравнить изображения ...");
    }
    return percent;
}

Данный метод возвращает процент сходства изображений, можно дополнительно задать процент, при котором мы считаем, что изображение соответствуют регламентированному формату.

Итак, результаты обработки изображений и обработки текста получены. Мы считываем файл отчета, определяем, где находится тест, получаем информацию о том, проводился ли он и, если проводился, то определяем соответствуют ли графики требуемому формату. Комбинация методов мощного языка java позволила нам осуществить смелый эксперимент по проверке полноты проводимых тестов путем реализации Machine Learning библиотеки с помощью элементарных методов и работы с файлами и изображениями.

Советуем почитать