Приветствую! Меня зовут Игорь Буянов, я NLP-разработчик в команде MTS AI. В рамках рабочих проектов группы обработки естественного языка я провожу исследования в области активного обучения, редукции шума и, в целом, занимаюсь подготовкой и обработкой датасетов.

В этой статье будут рассмотрены методы чистки данных – noise reduction – и результаты тестирования алгоритмов.

Чистка данных – значение и применение

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

Несмотря на то, что существует много способов разметки и контроля качества данных, подобный шум всегда будет присутствовать в датасетах. В задачах классификации одна из причин шума – невозможность однозначно провести границу между классами. Для большинства современных моделей наличие шума в данных объемом до 10% – несерьезная проблема. Поэтому, если датасет создан грамотно или найденный набор данных надежен, результат будет удовлетворительным. 

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

Алгоритмы, о которых пойдет речь ниже, в большей или меньшей степени используют три концепции:

  1. генерализация как способность обучающихся алгоритмов – свойство ML-алгоритмов обобщать знания о классах в результате обучения. Благодаря этому свойству можно делать прогнозы на данных, которые не были предъявлены ранее;

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

  3. опора на поведение при обучении: например, отслеживание изменения функции ошибки.

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

Averaged representation 1

Это простейший алгоритм, который основан на гипотезе: шумные или редкие примеры лежат далеко от усредненного по каждой метке отдельно центра в пространстве признаков.

Алгоритм выглядит следующим образом:

  1. генерируем векторы для всех примеров;

  2. для каждого класса считаем центр с помощью усреднения по примерам из класса

  3. рассчитываем расстояние от центра класса до каждого примера этого класса;

  4. ранжируем примеры по убыванию расстояния;

  5. выбираем первые топ-k кандидатов, где число k – количество желаемых кандидатов.

Hybrid 2 

Простой алгоритм, который строится на следующей гипотезе: модель может предсказывать истинный класс примера за счет генерализации. В теории это значит, что модель может исправить неверно размеченные примеры. С другой стороны, алгоритм обращает внимание на примеры, которые труднее всего даются классификатору, то есть те, которые лежат ближе всего к границе раздела классов. В качестве основного используется метод опорных векторов или Support Vector Machine SVM.

Полностью алгоритм выглядит следующим образом:

1. тренируем модель на данных;

2. делаем предсказание и сравниваем предсказания с разметкой. Сохраняем те варианты, где есть расхождение;

3.    для каждого предсказания рассчитываем меру неопределенности, как маржинальное расстояние:

Margin(x) = |P(c_1|\textbf{x} ) - P(c_2|\textbf{x} )|

где c_1и c_2 – первый и второй по вероятности классы вслучаееслиунасметокбольше,чемдве, \textbf{x}– вектор признаков.

4.    берем топ-k из пункта 3;

5.    объединяем результаты из пункта 4 и пункта 2.

plainILI или Iterative Label Improvement 3

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

Алгоритм будет выглядеть следующим образом:

0. делаем копию исходных меток датасета.

1. инициализируем модель.

2. обучаем модель на всех имеющихся данных.

3. на основе уверенности модели обновляем соответствующие метки в датасете предсказаниями модели.

4. повторяем все шаги с первого пункта n раз, либо пока есть расхождения.

NBSVM 4

Этот алгоритм сложнее предыдущих, он имеет иерархическую структуру. В нем используется SVM для нахождения наиболее значимых примеров для классификации – тех, которые составляют опорные вектора, – а также алгоритм классификации «наивный Байес» далееНБ. Он помогает получить апостериорную плотность вероятностей и используется для двух целей: предсказание метки для опорных векторов, где выделяются ошибочные примеры, и расчет оценочной ошибки estimatederror каждого кандидата. Роль оценочной ошибки – оценить уверенность того, что пример размечен некорректно.

Расчет ошибки производится с помощью функции потерь, которая относится к разделу активного обучения, посвященного вопросу эффективной разметки данных. Называется она Estimated Error Reduction и описать словами ее можно так: хорошим разметчиком можно считать того, кто размечает каждую итерацию такого примера из выборки, который, будучи объединенным с уже размеченной выборкой, дает минимальную ожидаемую ошибку (expected error) классификатора на тестовой выборке, в отличие от любых других примеров из выборки. Проще говоря, если мы каждый раз размечаем такой пример, который максимально увеличивает качества классификатора, то мы – хорошие разметчики. Математически ожидаемую оценку можно выразить так:

E_{\hat{P}_D}=\int_x L(P(y|x),\hat{P}(y|x))

где E_{\hat{P}_D} – ожидаемая ошибка, P(y|x) – истинное распределение, которое мы, в теории, знаем,  \hat{P}(y|x)предсказание классификатора или оценочное распределение, D – размеченный датасет, на котором обучается модель, а L – функция потерь log loss. Ее значение расшифровывается как мера несоответствия между истинным распределением и предсказанием классификатора. Математически выбор примера x', минимизирующего эту ошибку, записывается так:

\forall(x,y)E_{\hat{P}_{D+(x',y')}}<E_{\hat{P}_{D+(x,y)}}

Теперь – об истинном распределении. Мы можем его оценить при помощи беггинга – обучим несколько разных классификаторов НБ на подвыборках из основного размеченного датасета. В результате получим вероятности от всех классификаторов на датасет, усредним результат – получаем оценку истинного распределения.

Формула для оценки ожидаемой ошибки:

E_{\hat{P}_{D+(x,y)}}=-\frac{1}{|X|}\sum_{x\in X}\sum_{y\in Y}P(y|x)*log(\hat{P}_{D+(x,y)}(y|x))

Шаги алгоритма:

  1. обучаем SVM на датасете;

  2. извлекаем примеры, которые являются опорными векторами;

  3. обучаем НБ на данных, исключая опорные вектора.

  4. предсказываем метки опорных векторов с помощью НБ;

  5. извлекаем спорных кандидатов – те примеры, метки которых не совпали с меткой, предсказанной с помощью НБ;

  6. готовим новый датасет, удаляя из исходного спорных кандидатов;

  7. оцениваем истинное распределение датасета из пункта 6 с помощью бэггинга.

  8. обучаем другой НБ на датасете из пункта 6 и добавляем одного спорного кандидата с меткой, предсказанной НБ в пункте 4;

  9. считаем функцию потерь Expected Error Reduction

  10. повторяем шаги 8 и 9 для всех спорных кандидатов;

  11. чем меньше значение, тем вероятнее, что пример был размечен некорректно. Сортируем по возрастанию спорных кандидатов относительно значения функции потерь и берем топ-k.

Leitner system 5

Leitner system – хороший пример алгоритма, в котором исследователи имитируют естественные процессы. Он основан на одноименной методике, по которой люди учатся запоминать слова из нового языка. В этом методе используются карточки: на одной стороне человек пишет слово, которое нужно выучить, а на обратной стороне – перевод. Чтобы запомнить все карточки, нужно перевести их несколько раз. Чем больше раз человек переводит конкретную карточку правильно, тем реже он «испытывает» ее, проверяя себя сначала через две итерации, потом через три и так далее. Когда человек ошибается, счетчик обнуляется, и снова нужно повторять карточку в каждом прогоне. Этот метод основан на таком свойстве человеческого мозга: память с неустоявшимися знаниями гаснет во времени по экспоненте, но повторяющиеся элементы закрепляются в ней.

В качестве экзаменуемого в системе используется нейросеть, а алгоритм можно описать так:

0. пусть имеется несколько списков [, , ...], которые будут отражать «временные интервалы»;

1. записываем все примеры в первый список;

2. будем обучать систему n эпох;

3. сформируем обучающую выборку таким образом, чтобы в нее попали примеры из интервальных списков. Индексы этих списков – степени двойки, при делении номера эпохи по модулю должны давать ноль;

4. обучаем сеть;

5. делаем предсказания и сравниваем с метками.

6. те примеры, которые были предсказаны верно, переходят в новый список, а неверные помещаются обратно в первый.

7. подсчитываем «спорность» примеров хитрым способом, интуиция которого сводится к тому, что, если пример часто оказывается в первом списке, значит с ним, возможно, что-то не так.

8. выполняем все пункты, начиная с третьего, n эпох.

9. получаем top-k по убыванию метрики, рассчитанной в седьмом пункте.

TracIn 6

Первостепенная задача этого алгоритма – определить влияние тренировочных примеров на предсказание примера из тестовой выборки. Результат зависит от того, насколько изменится функция потерь на предсказании «тестового» примера после того, как сеть будет обучена на тренировочном.  Авторы статьи Estimating Training Data Influence by Tracing Gradient Descent называют примеры, которые снижают функцию потерь, пропонентами, а те, которые повышают, – оппонентами.

Побочная способность алгоритма – определять некорректные или редкие примеры с помощью подсчета самовлияния. Этот подсчет обозначает, какое влияние имеет пример для предсказания самого себя. По словам авторов, можно ожидать, что для себя самого некорректный пример будет являться сильным пропонентом. Он будет сильным, потому что нетипичный, а пропонентом – потому что для себя самого он будет снижать функцию потерь. Здесь, конечно, может возникнуть вопрос: «А какой пример сам для себя будет оппонентом?», на него пока нет ответа. Однако то, что подобный пример вызовет большое возмущение в функции потерь, выглядит логично – уже в процессе обученная сеть с помощью генерализации может предсказать пример верно, но в функцию потерь мы подставим неверную метку. Это приведет к ее большому значению, так как нужно «подвинуть» сеть в другую сторону.

В практической версии алгоритма нужно подсчитать сумму двойных произведений градиентов функции потерь l весов линейного wи примера z в количестве контрольных точек k. Причем в простом варианте есть несколько ограничений – скорость обучения learningrate неизменна, контрольные точки устанавливаются через равные промежутки tнапример, через каждую эпоху. Общая формула выглядит следующим образом:

TracInCP(z,z')=\sum_{i=1}^k\nabla_l(w_{t_i},z)*\nabla_l(w_{t_i},z')

Поскольку получается, что z=z'. В результате алгоритм сводится всего к трем шагам:

  1. обучить нейросеть на данных, делая контрольные точки;

  2. посчитать самовлияние для каждого примера;

  3. выбрать top-k, ранжируя по убыванию.

Результаты

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

  • Для алгоритма leitner использовалась однослойная LSTM со слоем self-attention.

  • Для алгоритма plainILI использовалась однослойная LSTM со слоем self-attention, а в качестве оценки неопределенности использовались выходы с softmax.

  • Для остальных алгоритмов использовались представления от bert-base-uncased.

  • Для TracIn использовалась LSTM со слоем self-attention.

  • Алгоритмы прогонялись по три раза.

В качестве данных использовался датасет SNLI, так как в нем, помимо основной разметки, доступна исходная разметка от пяти разметчиков – натуральные шумные данные. Был выбран один из разметчиков, error rate которого относительно золотой разметки равен 0.11. Общий объем данных составил 17500 примеров.

Суть эксперимента – дать общую оценку способности алгоритма находить неверно размеченные примеры, а также оценить, как найденные примеры влияют на точность модели. В качестве такой модели использовался BERT-base-uncased.

acc

 

k

 

founded

 

Algorithm

mean

std

mean

std

mean

std

Averaged

0.792970

0.007059

50.0

0.0

9.0

0.000000

Hybrid

0.799898

0.000000

50.0

0.0

10.0

0.000000

Leitner

0.800781

0.001224

50.0

0.0

4.3

0.577350

NBSVM

0.799558

0.000817

50.0

0.0

5.6

2.309401

plainILI

0.801155

0.000588

32.0

6.244998

6.6

2.309401

TracIn

0.801189

0.001257

50.0

0.0

22.6

5.686241

Random

0.797147

0.005187

50.0

0.0

7.0

1.414214

Gold

0.805230

0.001529

-

-

-

-

Noised

0.800917

0.000000

-

-

-

-

Acc – точность, k – топ кандидатов, которые алгоритм посчитал ошибочными, founded – количество найденных ошибочных примеров, mean – среднее значение, std – стандартное отклонение. В столбце Algorithm Gold – модель, обученная на конечной разметке SNLI, Noised – модель, обученная на шумных данных, Random – случайный выбор.

Результат эксперимента показал, что по количеству найденных некорректно размеченных примеров лидирует TracIn, когда остальные едва ли превышают порог случайного отбора. То же самое – с точностью итоговой модели, хотя из-за разброса нельзя говорить о ее однозначном превосходстве.

Отдельно стоит выделить алгоритм plainILI. Поскольку в реализации эксперимента нельзя контролировать выдачу, была введена колонка с топом k. Так как алгоритм в среднем выдал 32 примера, в процентном соотношении он эффективнее, чем случайный выбор, при этом точность модели лишь немногим хуже модели TracIn, а отклонение меньше.

Результат сравнения показывает, что в точности прирост незначительный. Этому есть объяснение: модель BERT очень мощная, а количество шума в данных составляет всего 10%. Если прогнать BERT по шумным данным без чистки, с большой вероятностью мы получим истинные метки. Однако другого набора данных с большим количеством натурального шума для проверки эксперимента найти не удалось.

Ниже представлен график Precision@K, с помощью которого можно оценить динамику алгоритмов.

График Precision@K
График Precision@K
  1. Stefan Larson et al. «Outlier Detection for Improved Data Quality and Diversity in Dialog Systems» Proceedings of NAACL-HLT, 2019

  2. Dmitriy Dligach and Martha Palmer «Reducing the Need for Double Annotation», Proceedings of the Fifth Law Workshop, 2011

  3. Christian Haase-Sch ̈utz et al. «Iterative Label Improvement: Robust Training by Confidence Based Filtering and Dataset Partitioning», Arxiv, 2020

  4. Fumiya Fukumoto and Yoshimi Suzuki «Correcting Category Errors in Text Classification», COLING, 2004

  5. Hadi Amiri et al. «Spotting Spurious Data with Neural Networks», Proceedings of NAACL-HLT, 2018

  6. Garima et al. «Estimating Training Data Influence by Tracing Gradient Descent», NeurIPS, 2020

Комментарии (4)


  1. piva
    07.08.2021 00:18

    Если я правильно понимаю, что эти алгоритмы применимы не только к обработке языка, а к данным в целом.

    Нет ли где-то примеров использования этих алгоритмов на языках программирования (чтобы глянуть и понять как можно использовать в работе) ?


    1. aarmaageedoon Автор
      07.08.2021 09:18
      +1

      Да, вы правы.

      Вы можете посмотреть оригинальную работу по TracIn, авторы изначально используют его для изображений. Они, также, поделились исходным кодом. https://github.com/frederick0329/TracIn


  1. enrupt
    16.09.2021 13:11

    Есть ли разница, идут ли 10% ошибок в начале обучения или разбросаны по датасету? Как определяется граница, при которой модель уже не может игнорировать ошибку?


    1. aarmaageedoon Автор
      16.09.2021 13:45

      1. Это хороший вопрос. Изначально делалось предположение, что ошибка равномерно распределена по датасету. Можно сказать, что это предположение выполняется, учитывая что довольно часто перед обучением датасеты перемешиваются случайным образом. Однако, предположим, что мы в первую очередь обучаемся на ошибочных данных. Сразу встает вопрос о характере ошибки:

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

        2. Если же ошибочные представляют собой "перевертыши", где связь есть, только отрицательная, то подозреваю, что модель, увидев "правильные" данные будет долго переучиваться. Причем всплеск функции ошибок будет еще больше, чем в первом случае.

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

      2. Этот вопрос еще лучше и заслуживает отдельного исследования. Мы знаем об этом эмпирически: если вы посмотрите на таблицу, приведенную в статье, то можете видеть, что разница в точности моделей между полностью зашумленным случаем и золотым случаем, наблюдается только в третьем знаке. Поэтому можно говорить о том, что BERT довольно устойчив к шуму около 10 процентов (на задачах, аналогичных этой). Конечно, делать такое для каждой модели дороговато, но другого способа я не знаю. Если подумать, то подобная граница зависит от типа ошибки, от сложности данных, от сложности моделей и еще чего, что мне неизвестно. То, что перечислено уже ставит задачу в разряд "не легко")