Жесткий возврат или жесткий перенос — это разрыв строки, предназначенный для удержания ширины текста в пределах определенного значения, обычно 80 символов. Они делают текст более читабельным и являются соглашением по форматированию документов в определенных текстовых редакторах. Однако в некоторых приложениях (таких как обработка естественного языка и преобразование форматов) они могут раздражать.

Из начальной школы вы усвоили основные правила переноса строк при письме на листе бумаги: вы никогда не начинаете новую строку, начинающуюся с символа, вы не разрываете слова, если в этом нет особой необходимости, и т. д. Эти правила легко понять. программируется в компьютерах, поэтому обтекание одной строки в несколько строк является тривиальной задачей. Чтобы ваши читатели могли по-прежнему отличать разрывы строк, разделяющие абзацы, от жестких оберток, вы придерживаетесь определенных правил, таких как двойной разрыв между абзацами или отступ первых строк всех абзацев. Эти сигналы новых абзацев значительно облегчают развертывание текста.

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

Прежде всего, учитываем основные, начальные школьные правила переноса текста на лист бумаги:

Функция №1: указывает, заканчивается ли каждая строка символом, который можно использовать для завершения абзаца;

Функция № 2. Начинается ли первое слово следующей строки после удаления пробелов с заглавной буквы.

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

В приведенном выше примере строка №3 заканчивается точкой, а строка №4 начинается с заглавного слова. По признакам № 1 и № 2 мы бы наивно решили сохранить разрыв строки между этими двумя строками, в то время как отступ здесь должен фактически быть доминирующим индикатором создания новых абзацев.

Функция №3: количество начальных пробелов в следующих строках. Интуитивный подход заключается в том, что если строка имеет отступ с достаточным количеством пробелов, то она не должна объединяться с предыдущей строкой. Эта функция очень информативна при строгом соблюдении соглашений.

Реальность такова, что немногие на самом деле следуют условностям; и даже если они это сделают, соглашения могут иметь много предостережений, которые усложняют задачу развертывания, например. количество пробелов, используемых для отступа). Возьмите этот фрагмент текста в качестве примера:

  • Сколько символов пробела должно составлять отступ, разделяющий абзац? В строке № 3 у нас есть 5, в строке № 7 у нас есть 6 и в строке № 11 у нас есть 3. Этот единственный параметр сам по себе заслуживает трюка машинного обучения.
  • Можем ли мы сказать: «Если строка имеет отступ более чем x пробелов, то мы должны назвать ее новым абзацем?» В этом случае абзац с полным отступом, строки с 11 по 14, будут несправедливо рассматриваться как 4 отдельные строки.
  • Строка №15 вообще не имеет отступа, и ее не следует объединять со строкой №14. Почему? Не вводя долговременных функций, учитывающих слишком много строк вокруг, мы, вероятно, можем сказать, потому что, если бы она была соединена со строкой № 14, слова «Ut cursus massa» также должны быть размещены в конце строки №. 14 — там просто слишком много лишнего места.

Это рассмотрение приводит нас к следующей особенности:

Функция № 4. Толщина линии. Интуитивно я смотрю на слишком короткие строки: если они слишком короткие, это, вероятно, потому, что после этого автор ввел новый абзац.

Это звучит правдоподобно, но подождите, пока вы не проверите следующий пример:

В приведенном выше документе строка № 18 действительно занимает почти 100% максимальной ширины строки этого документа, но достаточно ли этого, чтобы сказать, что ее следует соединить со строкой № 19?

Функция №5. Может ли оставшееся пространство в конце каждой строки вместить первое слово в следующей строке. Ответ на последний вопрос должен быть «возможно, нет», поскольку первое слово в строке № 19, «Интерес», слишком длинный, чтобы его можно было втиснуть в пробел в конце строки № 18. Это вполне может быть причиной переноса слова, а НЕ с целью создания нового абзаца.

Положительным примером являются строки № 28 и строки № 29: оставшееся пространство в конце строки № 28 может вместить несколько первых слов в строке № 29, но этого не произошло. Это явный признак того, что между этими двумя строками должен быть разрыв абзаца.

Прежде чем мы завершим (каламбур) наш поток мыслей, я заметил возможный угловой случай:

Строка №2 не заканчивалась точкой (или знаком вопроса, восклицательным знаком и т.д.). Если бы мой классификатор по ошибке придал слишком большое значение признаку № 1, он мог бы объединить эту строку со строкой № 3, ошибка слишком глупая, чтобы ее принять. Как опытные английские читатели, мы можем легко сказать, что эти две строки не должны быть объединены, поскольку строка № 2 полностью в верхнем регистре, а строка № 3 — нет. В переводе на характеристики это означает:

Функция № 6: указана ли каждая строка в верхнем регистре.

Функция № 7: указана ли следующая строка в верхнем регистре.

Я вручную пометил 1700 строк (в качестве обучающих примеров) и обучил на них классификатор SVM. Гиперпараметры можно очень быстро найти с помощью GridSearch: C=384 и gamma=0,011 (здесь я привожу значения, чтобы дать вам представление о порядке цифр для этих двух параметров; НЕ используйте их как- есть!). Производительность очень удовлетворительная:

Надеюсь, вы нашли этот пост полезным для своих идей по проектированию функций. Оставайтесь с нами в моей серии Medium для Data Science!