Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
2108 views

Пример работы с номинальными данными

Построение таблицы сопряжённости

Таблица сопряжённости представляет собой таблицу перекрёстных частот двух или более признаков. Они используются для анализа номинальных (категориальных) данных. Далее рассмотрим пример построения такой таблицы в случае двух признаков.

В качестве примера возьмём известный набор данных --- статистику о пассажирах "Титаника", в которой указаны возраст и пол пассажира, класс билета, а также метка выжил/не выжил. Пол, класс билета и сведения о выживаемости являются номинальными признаками (почему?). Исследуем, существует ли взаимосвязь между классом билета и выживанием (или по-другому: верно ли, что существуют значимые различия в выживаемости между пассажирами, имевшими билеты разных классов).

Чтобы показать, как строится таблица сопряжённости, возьмём несколько мысленных данных:

Номер наблюденияКласс билетаВыживаемость
1Первый классДа
2Второй классДа
3Первый классДа
4Третий классНет
5Третий классНет
6Третий классДа
7Второй классНет
8Первый классДа
9Первый классНет
10Второй классДа

Признак "Класс билета" имеет m1=3m_1=3 градации: первый, второй и третий классы. Признак "Выживаемость" бинарный, т. е. имеет m2=2m_2=2 градации --- "Да", "Нет". Следовательно, таблица сопряжённости будет иметь размерность 3×23\times 2. Строки таблицы соответствуют градациям первого признака, столбцы --- градациям второго.

На пересечении строки ii и столбца jj мы должны поставить число --- количество объектов в выборке, для которых имеет место комбинация (i,j)(i, j) значений признаков. Например, в ячейке (1,1)(1, 1) (она соответствует числу пассажиров первого класса, которые выжили) будет находиться число 33, в ячейке (1,2)(1, 2) (число пассажиров первого класса, которые не выжили) --- число 11. Далее рассуждаем аналогично. Приведём конечный результат:

ДаНетСумма
Первый класс314
Второй класс213
Третий класс123
Сумма6410

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

def contingency_table2d(data, i, j) : ''' Построение таблицы сопряжённости по двум признакам. data - таблица исходных данных с заголовком i, j - номера признаков ''' two_cols = [[row[i], row[j]] for row in data[1:]] # матрица из двух столбцов first = set([x[0] for x in two_cols]) # множество значений признака first second = set([x[1] for x in two_cols]) # множество значений признака second first = sorted(list(first)) # сортируем значения first second = sorted(list(second)) # сортируем значения second # Строим таблицу сопряжённости head = [''] + second + [''] cont_table = [head] for f in first : row = [f] for s in second : row.append(two_cols.count([f, s])) row.append(sum(row[1:])) cont_table.append(row) last = [''] for j in range(1, len(second)+2) : last.append(sum([x[j] for x in cont_table[1:]])) cont_table.append(last) return cont_table
# Считываем данные из файла titanic.csv f = open('titanic.csv', 'r') data = [] for line in f : row = line[:-1].split(',') data.append(row) f.close() # Строим таблицу для двух признаков: class (столбец 2) и survived (столбец 5) cont_table = contingency_table2d(data, 1, 4) for row in cont_table : print row
['', '"no"', '"yes"', ''] ['"1st class"', 122, 203, 325] ['"2nd class"', 167, 118, 285] ['"3rd class"', 528, 178, 706] ['', 817, 499, 1316]

Вычисление статистики хи-квадрат по формуле

χСТ2=n(i=1m1j=1m2nij2ninj1).\chi _{\text{СТ}}^{2} =n\left(\sum\limits _{i=1}^{m_{1} }\sum\limits _{j=1}^{m_{2} }\dfrac{n_{ij}^{2} }{n_{i\bullet } \cdot n_{\bullet j} } -1\right).
m1 = len(cont_table) - 2 m2 = len(cont_table[0]) - 2 n = cont_table[m1+1][m2+1] s = 0 for i in range(1, m1+1) : for j in range(1, m2+1) : s = s + cont_table[i][j]^2/(cont_table[i][m2+1]*cont_table[m1+1][j]) chi2_stat = float(n*(s-1)) chi2_crit = 4.605 # нашли по таблице chi2(0.1; 2) print 'chi2_stat:', chi2_stat if chi2_stat > chi2_crit : print 'Связь подтверждена' else : print 'Связи нет'
chi2_stat: 133.052035986 Связь подтверждена

Использование встроенных функций Sage (via scipy.stats)

# Оставляем в cont_table только нужные значения ctable = [x[1:-1] for x in cont_table[1:-1]] from scipy.stats import chi2_contingency result = chi2_contingency(ctable) chi2_stat = result[0] print 'chi2_stat:', chi2_stat p_value = result[1] if p_value < 0.05 : print 'Связь подтверждена' else : print 'Связи нет'
chi2_stat: 133.052035986 Связь подтверждена

Использование R

%r titanic <- read.csv("titanic.csv") table(titanic$class, titanic$survived) class.by.survived <- xtabs(~ class + survived, titanic) mosaicplot(class.by.survived, color=c("red","green"), main="Class vs Survival, Titanic Passengers") chisq.test(titanic$class, titanic$survived, correct = FALSE)
no yes 1st class 122 203 2nd class 167 118 3rd class 528 178 Pearson's Chi-squared test data: titanic$class and titanic$survived X-squared = 133.05, df = 2, p-value < 2.2e-16