Как проверить, принадлежат ли два текстовых набора данных разным дистрибутивам?

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

Как определить, относятся ли оба набора данных к одному дистрибутиву?

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

Я планирую использовать тест хи-квадрат, но не уверен, поможет ли он для текстовых данных, учитывая высокие степени свободы.

update: Пример: Предположим, я хочу обучить модель классификации настроений. Я обучаю модель на наборе данных IMDb и оцениваю наборы данных IMDb и Yelp. Я обнаружил, что моя модель, обученная на IMDb, по-прежнему хорошо работает на Yelp. Но вопрос в том, насколько различаются эти наборы данных?

Набор данных поезда: https://www.kaggle.com/columbine/imdb-dataset-sentiment-analysis-in-csv-format?select=Train.csv

Оценка 1: https://www.kaggle.com/columbine/imdb-dataset-sentiment-analysis-in-csv-format?select=Valid.csv

Оценка 2: https://www.kaggle.com/omkarsabnis/sentiment-analysis-on-the-yelp-reviews-dataset

Теперь,

  1. Насколько отличаются train и eval 1?
  2. Чем отличаются train и eval 2?
  3. Случайно ли непохожесть между train и eval 2? Какова статистическая значимость и значение р?

person Krishan Subudhi    schedule 01.11.2020    source источник
comment
Я думаю, пример поможет понять вашу проблему. Но я думаю, это зависит от того, о каком дистрибутиве вы говорите. Если вы хотите оценить, могла ли последовательность быть сгенерирована из набора данных, вы можете обучить языковую модель для каждого набора данных и вычислить разницу между двумя распределениями. Вы также можете вычислить словарь каждого набора данных и сравнить их пересечение.   -  person ygorg    schedule 02.11.2020
comment
Не могли бы вы привести пример для большего контекста?   -  person 325    schedule 02.11.2020
comment
Добавлен пример использования со ссылками на наборы данных.   -  person Krishan Subudhi    schedule 03.11.2020


Ответы (2)


Вопрос приходят ли текст A и текст B из одного дистрибутива? как-то плохо определен. Например, эти два вопроса (1,2) можно рассматривать как сгенерированные из одной раздачи (раздача всех вопросов на StackExchange) или из разных раздач (раздача двух разных поддоменов StackExchange). Поэтому неясно, какое свойство вы хотите проверить.

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

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

import requests
from bs4 import BeautifulSoup
urls = [
    'https://en.wikipedia.org/wiki/Nanjing_(Liao_dynasty)', 
    'https://en.wikipedia.org/wiki/United_States_Passport_Card'
]
texts = [BeautifulSoup(requests.get(u).text).find('div', {'class': 'mw-parser-output'}).text for u in urls]

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

import re
from collections import Counter
from copy import deepcopy
TOKEN = re.compile(r'([^\W\d]+|\d+|[^\w\s])')
counters = [Counter(re.findall(TOKEN, t)) for t in texts]
print([sum(c.values()) for c in counters])  
# [5068, 4053]: texts are of approximately the same size

def word_freq_rmse(c1, c2):
    result = 0
    vocab = set(c1.keys()).union(set(c2.keys()))
    n1, n2 = sum(c1.values()), sum(c2.values())
    n = len(vocab)
    for word in vocab:
        result += (c1[word]/n1 - c2[word]/n2)**2 / n
    return result**0.5

print(word_freq_rmse(*counters))
# rmse is 0.001178, but is this a small or large difference?

Я получаю значение 0,001178, но не знаю, большая ли это разница. Поэтому мне нужно смоделировать распределение этой тестовой статистики при нулевой гипотезе: когда оба текста принадлежат одному и тому же распределению. Чтобы смоделировать это, я объединяю два текста в один, а затем разбиваю их случайным образом и вычисляю свою статистику при сравнении этих двух случайных частей.

import random
tokens = [tok for t in texts for tok in re.findall(TOKEN, t)]
split = sum(counters[0].values())
distribution = []
for i in range(1000):
    random.shuffle(tokens)
    c1 = Counter(tokens[:split])
    c2 = Counter(tokens[split:])
    distribution.append(word_freq_rmse(c1, c2))

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

observed = word_freq_rmse(*counters)
p_value = sum(x >= observed for x in distribution) / len(distribution)
print(p_value)  # it is 0.0
print(observed, max(distribution), sum(distribution) / len(distribution)) # 0.0011  0.0006 0.0004

Мы видим, что когда тексты из одного дистрибутива, моя тестовая статистика в среднем равна 0,0004 и почти никогда не превышает 0,0006, поэтому значение 0,0011 очень необычно, и нулевая гипотеза о том, что два моих текста происходят из одного дистрибутива, должна быть отвергнута.

person David Dale    schedule 05.11.2020
comment
Спасибо, Дэвид. У меня есть несколько дополнительных вопросов, если вы не возражаете. Какой вопрос нужно было задать в данном случае? У упомянутого вами алгоритма есть имя? Я хотел бы узнать больше об этом. Могу ли я использовать относительную энтропию вместо среднеквадратичного значения? Откуда мне знать, какой из них лучше? Как насчет теста хи-квадрат? Будет ли это работать здесь? - person Krishan Subudhi; 07.11.2020
comment
1) Я не знаю, какой вопрос правильный. Я просто упоминаю, что ваша формулировка проблемы несколько двусмысленна. - person David Dale; 07.11.2020
comment
2) у этого алгоритма нет названия, я просто придумал его по общей схеме статистических тестов: придумать тестовую статистику, вычислить ее и сравнить ее наблюдаемое значение с ее распределением в случае, когда нулевая гипотеза верна. Я использовал среднеквадратичную разницу частоты слов только потому, что среднеквадратическая ошибка отлично работает во многих других случаях. Кстати, тест Хи-2 тоже вычисляет что-то вроде MSE, но с другой нормализацией. - person David Dale; 07.11.2020
comment
3) Я не знаю, как доказать, какой тест в целом лучше. Я знаю только, как оценить такой тест на конкретном наборе пар корпусов, где одни пары взяты из одного дистрибутива, а другие пары из других дистрибутивов. Если у вас есть такой набор данных для сравнительного анализа, вы можете использовать его для сравнения тестов, оценивая их показатели ложного принятия и ложного отклонения. - person David Dale; 07.11.2020

Я написал статью, которая похожа на вашу проблему, но не совсем то же самое. https://towardsdatascience.com/a-new-way-to-bow-analysis-feature-engineering-part1-e012eba90ef

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

Между вашей проблемой и той, о которой я упоминал выше, есть некоторое сходство.

  • Вы хотите сравнить два источника наборов данных, которые можно рассматривать как две разные категории.
  • Кроме того, чтобы сравнить источники данных, вам придется сравнивать слова, поскольку предложения нельзя сравнивать напрямую.

Итак, мое предлагаемое решение для этого будет следующим:

  • Создавайте признаки слов в двух наборах данных, используя count-vectorizer, и получайте первые X слов из каждого
  • Допустим, у вас есть общее количество различных слов как N, теперь инициализируйте count=0 и начните сравнивать распределение для каждого слова, и если различия значительны, увеличьте счетчик. Кроме того, могут быть случаи, когда слово существует только в одном из наборов данных, и это хорошая новость, под этим я подразумеваю, что оно показывает, что оно является отличительной чертой, поэтому для этого также увеличьте количество
  • Допустим, общее количество равно n. Чем меньше отношение n/N, тем два текста похожи, и наоборот.

Кроме того, чтобы проверить эту методологию, разделите данные из одного источника на два (случайная выборка) и запустите вышеуказанный анализ, если отношение n/N ближе к 0, что указывает на то, что два источника данных похожи, что также имеет место. .

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

person Prateek Jain    schedule 05.11.2020