Как транспонировать матрицу в питоне
Линейная алгебра на Python. [Урок 2]. Транспонирование Матрицы
В этом уроке мы рассмотрим операцию “транспонирование матрицы” и как она выполняется на Python. Также разберем на примерах свойства этой операции.
Транспонирование матрицы
Для исходной матрицы:
Транспонированная будет выглядеть так:
Транспонируем матрицу с помощью метода transpose():
Существует сокращенный вариант получения транспонированной матрицы, он очень удобен в практическом применении:
Рассмотрим на примерах свойства транспонированных матриц. Операции сложения и умножение матриц, а также расчет определителя более подробно будут рассмотрены в последующих уроках.
В данном примере, для умножения матриц, использовалась функция dot() из библиотеки Numpy.
Ввиду особенностей Python при работе с числами с плавающей точкой, в данном примере вычисления определителя рассматриваются только первые девять значащих цифр после запятой (за это отвечает параметр ‘.9g’ ).
P.S.
Как транспонировать матрицу в Python
Сегодня мы хотим разобрать, как транспонировать матрицу в Python. Однако сначала давайте рассмотрим, что представляет из себя матрица сама по себе и в чём заключается процесс транспонирования.
Итак, матрица состоит из строк и столбцов. Создать матрицу можно по-разному, но самый простой способ – использовать вложенные списки, как показано ниже:
Внутренние списки представляют собой строки, а каждый элемент внутри списка называется столбцом. Итак, в приведенном выше примере у нас есть две строки и три столбца, т.е. мы имеем дело с матрицей 2 на 3. Стоит помнить, что индексация Python начинается с нуля.
Транспонирование матрицы означает, что мы меняем строки на столбцы или столбцы на строки. Теперь давайте обсудим различные методы транспонирования матрицы.
Метод 1. Транспонирование матрицы с помощью NumPy transpose()
Метод 2. Использование метода numpy.transpose()
Метод 3. Транспонирование матрицы с использованием библиотеки SymPy
Применение библиотеки SymPy – это еще один подход к транспонированию матрицы. Эта библиотека использует символьную математику для решения алгебраических задач.
Сначала нам, конечно же, нужно импортировать библиотеку SymPy. Она не поставляется вместе с Python по умолчанию, поэтому вы должны установить её в своей системе, иначе код не будет работать.
В ячейке номер [34] мы создаем матрицу с помощью библиотеки sympy.
Метод 4. Транспонирование матрицы с использованием вложенного цикла
В Python матрицу можно транспонировать и без применения каких-либо библиотек. Для этого нам придется использовать вложенные циклы.
Мы создаем одну матрицу, а затем вторую (того же размера, что и первая) — для сохранения результатов после транспонирования. При этом важно отметить, что мы далеко не всегда знаем размерность исходной матрицы. Поэтому матрицу для результата мы создаем не напрямую, а используя размер исходной.
В ячейке номер [38] мы создаем матрицу и выводим ее на экран.
Метод 5. Использование генератора списка
Следующий метод, который мы разберем, — это использование генератора списка. Этот метод похож на предыдущий с использованием вложенных циклов, но он более «питонический». Можно сказать, что это более продвинутый способ транспонирования матрицы в одной строке кода без использования библиотек.
Затем в ячейке номер [44] мы используем вложенные циклы, как и в предыдущем примере. Однако здесь мы делаем это в одну строчку, используя генератор списков. Более того, тут нет никакой необходимости менять индексы [j] [i] местами, как мы это делали в предыдущий раз.
Метод 6. Транспонирование матрицы с помощью pymatrix
Pymatrix – ещё одна облегченная библиотека для матричных операций в Python. Мы можем выполнить транспонирование и с её помощью.
В ячейке номер [43] мы импортируем библиотеку pymatrix. Она не поставляется вместе с Python по умолчанию, поэтому, чтобы код работал корректно, нужно установить ее в своей системе перед использованием.
Затем при помощи библиотеки pymatrix мы создаем матрицу (в ячейке [44]).
В ячейке номер [45] вызываем метод trans() для нашей матрицы и сохраняем результаты в новую переменную pymatrix_transpose.
Метод 7. Использование метода zip
Zip – еще один метод транспонирования матрицы.
В ячейке номер [63] мы создаем новую матрицу, используя вложенные списки.
Заключение
Итак, сегодня мы рассмотрели, как транспонировать матрицу в Python. Мы разобрали различные методы, которые могут помочь нам в транспонировании матрицы (с использованием библиотек и без них).
Мы также познакомились с несколькими новыми библиотеками, такими как pymatrix и sympy.
Надеемся, теперь у вас не осталось вопросов о том, как транспонировать матрицу. Более того, вы можете выбрать наиболее подходящий способ для решения этой задачи.
Матрица в Python – основы работы
В этой статье мы познакомим вас с матрицей Python. Каждую операцию матрицы мы будем реализовывать с помощью кода.
Что такое матрица в Python?
Матрица в Python – это прямоугольный двумерный массив, в котором данные хранятся в строках и столбцах. Матрица может хранить данные любого типа, такие как числа, строки, выражения и т. д. Мы должны ознакомиться с основными концепциями матрицы перед ее использованием.
Данные расположены по горизонтали, называемые строками, а по вертикали – столбцами. Количество элементов внутри матрицы равно (R) X (C), где R – строки, а C – столбцы. Python не имеет встроенного типа для матриц, поэтому мы будем использовать несколько списков в качестве матриц.
Мы изучим следующие операции, которые применяются к матрицам:
Работа матриц
Приведенная ниже матрица имеет размер 2×2, что означает, что у нее две строки и два столбца.
Создание матрицы в Python
Мы можем создать матрицу на Python, используя вложенный список. Все элементы заключаются в квадратные скобки ([]) и разделяются запятой. Посмотрим на следующие примеры:
Чтение матричных данных
Прочитаем каждую строку определенной матрицы.
В следующем примере мы прочитаем последний элемент каждой строки с помощью программы Python.
В приведенном выше коде мы создали матрицу и получили длину матрицы. Мы повторили каждую строку, используя цикл for, и напечатали результат. Можно прочитать любую строку или столбец, используя вышеуказанный метод.
Давайте разберемся со следующей работой матрицы.
Добавление двух матриц
Мы добавим две матрицы и, используя вложенный цикл for, пройдемся по заданным матрицам.
Умножение двух матриц
Умножение двух матриц такое же, как в приведенном выше коде, только нужно изменить оператор + на *.
Транспонирование матрицы
Транспонирование – это операция, при которой строка данной матрицы преобразуется в столбец и наоборот. Рассмотрим на примере.
В приведенном выше коде у нас есть два цикла for для перебора каждой строки и каждого столбца. Как мы видим, в приведенном выше выводе мы присвоили mat1 [i] [j] и res [j] [k].
Транспонирование с помощью списка
Мы можем использовать значение списка, чтобы транспонировать матрицу с одной строкой кода.
Результат такой же, как и выше. Значение списка сократило количество строк кода и транспонировало матрицу.
Получение матричного ввода от пользователя
До сих пор мы обсуждали предварительно определенные матрицы. Но что, если пользователь хочет ввести свои данные. Итак, разберем следующий пример пользовательской матрицы.
В приведенном выше коде мы взяли данные пользователя, чтобы ввести количество строк и столбцов. Мы ввели 3 строки и 3 столбца; это означает, что в матрице будет 9 элементов. В цикле for элементы вставляются в пустую матрицу с помощью функции append(). Второй цикл for используется для печати входных данных в матричном формате.
Использование функции NumPy и map()
Python предоставляет внешнюю библиотеку NumPy. Она используется для научных вычислений; мы изучим NumPy с матрицей в разделе ниже и используем ее для матрицы пользовательского ввода.
Пример: Создание матрицы с использованием библиотеки NumPy
Библиотека NumPy помогает нам работать с массивом. Чтобы работать с NumPy, нам нужно установить ее, используя следующую команду.
После успешной установки мы должны импортировать ее в нашу программу.
Давайте разберемся в следующем примере.
Работа с матрицей с помощью NumPy
Мы можем выполнять все операции с матрицей, используя numpy.array(), такие как сложение, вычитание, транспонирование, нарезание матрицы и т. д.
Добавление матрицы
Мы создадим две матрицы с помощью функции numpy.array() и добавим их с помощью оператора +. Давайте разберемся в следующем примере.
Умножение
Мы будем использовать метод numpy.dot() для умножения обеих матриц. Это точечное умножение матриц mat1 и mat2, обрабатывает 2D-массив и выполняет умножение.
Нарезка элементов
Мы можем разрезать элемент матрицы, как в стандартном списке Python. Нарезка возвращает элемент на основе индекса начала / конца. Мы также можем сделать отрицательную нарезку. Синтаксис приведен ниже.
Arr представляет имя матрицы. По умолчанию начальный индекс равен 0, например – [: 3], это означает, что начальный индекс равен 0. Если мы не предоставим конечное значение, он будет учитывать длину массива. Мы можем передавать отрицательные значения индекса как в начало, так и в конец. В следующем примере мы применим нарезку в обычном массиве, чтобы понять, как она работает.
Теперь мы реализуем нарезку по матрице. Для выполнения следуйте синтаксису ниже.
Mat1 [row_start: row_end, col_start: col_end]
В приведенном выше синтаксисе:
Мы будем выполнять нарезку в приведенной ниже матрице.
В приведенном выше примере мы напечатали первую и вторую строки и нарезали первый, второй и третий столбцы. Согласно синтаксису нарезки мы можем получить любые строки и столбцы.
Пример – печать первой строки и всех столбцов:
Пример – печать строк матрицы:
Заключение
До сих пор мы обсуждали базовую матрицу с использованием Python. Матрица Python – это специализированный двумерный прямоугольный список данных. Она может состоять из чисел, строк, выражения, символов и т. д. Python не предоставляет прямого способа реализации матричного типа данных. Мы можем создать матрицу, используя вложенный список и библиотеку NumPy.
Как работать с матрицами в Python
Матрица — это двумерный массив, состоящий из M строк и N столбцов. Матрицы часто используются в математических вычислениях. Программисты работают с матрицами в основном в научной области, однако их можно использовать и для других вещей, например, для быстрой генерации уровней в видео-игре.
Матрицы и библиотека NumPy
Программист может самостоятельно реализовать все функции для работы с матрицами: умножение, сложение, транспонирование и т. д. На Python это сделать гораздо проще, чем на более низкоуровневых языках, таких как C.
Но каждый раз писать одни и те же алгоритмы не имеет смысла, поэтому была разработана библиотека NumPy. Она используется для сложных научных вычислений и предоставляет программисту функции для работы с двумерными массивами.
Вместо того чтобы писать десятки строк кода для выполнения простых операций над матрицами, программист может использовать одну функцию из NumPy. Библиотека написана на Python, C и Фортране, поэтому функции работают даже быстрее, чем на чистом Python.
Подключение библиотеки NumPy
NumPy не встроена в интерпретатор Python, поэтому перед импортом её необходимо установить. Для этого в можно воспользоваться утилитой pip. Введите в консоле команду:
Создание
Для создании матрицы используется функция array(). В функцию передаётся список. Вот пример создания, мы подаём в качестве аргумента функции двумерный список:
Вторым параметром можно задать тип элементов матрицы:
Тогда в консоль выведется:
Обратите внимание, что если изменить int на str, то тип элементов изменился на строковый. Кроме того, при выводе в консоль NumPy автоматически отформатировал вывод, чтобы он выглядел как матрица, а элементы располагались друг под другом.
В качестве типов элементов можно использовать int, float, bool, complex, bytes, str, buffers. Также можно использовать и другие типы NumPy: логические, целочисленные, беззнаковые целочисленные, вещественные, комплексные. Вот несколько примеров:
Вы также можете узнать размер матрицы, для этого используйте атрибут shape:
Первое число (2) — количество строк, второе число (3) — количество столбцов.
Нулевая матрица
Если необходимо создать матрицу, состоящую только из нулей, используйте функцию zeros():
Результат этого кода будет следующий:
Получение строки, столбца и элемента
Чтобы получить строку двухмерной матрицы, нужно просто обратиться к ней по индексу следующим образом:
Получить столбец уже не так просто. Используем срезы, в качестве первого элемента среза мы ничего не указываем, а второй элемент — это номер искомого столбца. Пример:
Чтобы получить элемент, нужно указать номер столбца и строки, в которых он находится. Например, элемент во 2 строке и 3 столбце — это 5, проверяем (помним, что нумерация начинается с 0):
Умножение и сложение
Чтобы сложить матрицы, нужно сложить все их соответствующие элементы. В Python для их сложения используется обычный оператор «+».
Пример сложения:
Результирующая матрица будет равна:
Важно помнить, что складывать можно только матрицы с одинаковым количеством строк и столбцов, иначе программа на Python завершится с исключением ValueError.
Умножение матриц сильно отличается от сложения. Не получится просто перемножить соответствующие элементы двух матриц. Во-первых, матрицы должны быть согласованными, то есть количество столбцов одной должно быть равно количеству строк другой и наоборот, иначе программа вызовет ошибку.
Умножение в NumPy выполняется с помощью метода dot().
Пример умножения:
Результат выполнения этого кода будет следующий:
Транспонированная и обратная
Транспонированная матрица — это матрица, у которой строки и столбцы поменялись местами. В библиотеки NumPy для транспонирования двумерных матриц используется метод transpose(). Пример:
В результате получится матрица:
Чтобы получить обратную матрицу, необходимо использовать модуль linalg (линейная алгебра). Используем функцию inv():
Результирующая матрица будет равна:
Получение максимального и минимального элемента
NumPy позволяет найти максимальный и минимальный элемент с помощью функций amax() и amin(). В качестве аргумента в функции нужно передать саму матрицу. Пример:
Как видим, результаты реализации на чистом Python и реализации с использованием библиотеки NumPy совпадают.
Заключение
На Python можно реализовать все необходимые функции для работы с матрицами. Чтобы упростить работу программистов, была создана библиотека NumPy. Она позволяет производить сложные математические вычисления легко и без ошибок, избавляя программиста от необходимости каждый раз писать один и тот же код.
Python, корреляция и регрессия: часть 3
Предыдущий пост см. здесь.
Прежде чем перейти к изучению нормального уравнения, давайте рассмотрим основы матричного и векторного умножения.
Матрицы
Матрица, — это двумерный массив чисел. Размерность матрицы выражается числом строк и столбцов.
Например, A — это матрица с четырьмя строками и двумя столбцами:
В математической записи матрица обычно закрепляется за переменной, которая обозначается прописной буквой, чтобы в уравнении отличать ее от других.
Массив numpy можно сконструировать из набора данных при помощи функции pandas df.values :
В результате выполнения этого примера получим следующий одномерный массив:
В результате получим следующий одномерный массив:
Матрицы часто могут вырастать до больших размеров, поэтому, чтобы не переполнять информацией окно интерпретатора, можно ограничить число выводимых элементов, воспользовавшись функциями pandas head и tail либо функционалом индексации библиотеки numpy ( result_array[:5] ); в обоих случаях будет выведено заданное число элементов.
Библиотека pandas взаимодействует с функциями библиотеки numpy напрямую, получая выгоду от векторизованных операций, таких как log, exp, sqrt и др., на массивах/матрицах. С другой стороны, различные функции numpy могут без проблем использоваться с кадрами данных DataFrame (и рядами Series) библиотеки pandas при условии, что содержащиеся внутри данные являются числовыми. Например, np.exp(df), np.asarray(df), df.T.dot(df)).
Размерность
Элемент в i-ой строке и j-ом столбце обозначается как Aij. И поэтому в приведенном выше примере индексация будет такой:
Векторы
Векторы — это частный случай матрицы, которая содержит всего один столбец. Число строк в векторе называется его размерностью:
Здесь y — это 4-мерный вектор; его i-й элемент обозначается как yi. Векторы в математической литературе индексируются, начиная с единицы, если не указано иное.
Так, обозначает первый элемент, не второй. В уравнениях векторы в основном закрепляются за переменными, обозначаемыми строчными буквами.
Программный интерфейс библиотеки numpy в отличие от библиотеки pandas (где Series и DataFrame могут служить соответственно для представления векторов и матриц) не делает различие между векторами и одностолбцовыми матрицами, и мы можем создать вектор, передав в функцию np.array единственную последовательность.
Сборка
Как мы уже убедились, матрицы можно собирать из последовательностей Python и наборов данных pandas. Кроме того, матрицы можно собирать из более мелких конструктивных составляющих, при условии совпадения размерностей, надстраивая столбцы бок о бок и добавляя строки. В простейшем случае мы можем добавить столбец единиц в начало или конец таблицы и затем преобразовать в матрицу следующим образом:
На самом деле, нам потребуется это делать для члена смещения. Напомним, что β1 выражает константное значение, поэтому мы должны обеспечить, чтобы соответствующий x1 тоже был константой. Без смещения переменная y равнялось бы нулю, в случае когда значения x равны нулю.
Сложение и скалярное произведение
Скаляр — это название для обыкновенного числа. Когда мы прибавляем скаляр в матрицу, мы на самом деле прибавляем это число отдельно в каждый элемент матрицы.
Матрично-матричное сложение работает путем сложения элементов в каждой соответствующей позиции. Складывать матрицы между собой можно только с одинаковыми размерностями. Если матрицы имеют одинаковые размерности, то о них говорят, что они совместимые.
Имплементация на Python с использованием pandas:
Помимо скаляров и матриц, в pandas можно складывать совместимые матрицы, например, из матрицы можно вычитать скаляры либо совместимые матрицы. Умножение матриц на скаляр в результате дает матрицу, в которой каждый элемент умножен на скаляр.
Имплементация на Python с использованием pandas:
Матрично-векторное умножение
В функции dot с применением сложного алгоритма матричного умножения имплементирован стандартный способ умножения матриц. Например, результатом умножения матрицы размера 3 × 2 на матрицу размера 2 × 1 является матрица размера 3 × 1, при этом число столбцов слева должно совпадать с числом строк справа:
Для получения Ax надо помножить каждую строку A поэлементно с соответствующим элементом матрицы x и сложить результаты. Например, первая строка матрицы A содержит элементы 1 и 3. Они попарно умножаются на элементы в векторе x: 1 и 5. Затем, произведения чисел складываются и в результате получаем 16. Эта операция называется точечным произведением, или скалярным произведением, для чего, собственно, и предназначено матричное умножение.
Имплементация на Python с использованием pandas:
Матрично-матричное умножение
Выполнение матрично-матричного умножения матриц очень походит на матрично-векторное умножение. Из соответствующих элементов матриц A и B попарно, строка за строкой и столбец за столбцом, берется сумма произведений.
Как и ранее, мы можем умножать матрицы между собой, только когда число столбцов в первой матрице равно числу строк во второй. Если первая матрица A имеет размерность mA × nA, а вторая матрица B — размерность mB × nB, то для того чтобы их перемножить, nA и mB должны быть эквивалентными.
В приведенном выше наглядном примере:
К счастью, нам не нужно запоминать эту процедуру. В библиотеках pandas и numpy используются очень эффективные алгоритмы, которые выполняют матричную алгебру за нас.
Или то же самое в библиотеке numpy:
Транспонирование
Транспонировать матрицу означает перевернуть матрицу по главной диагонали, проходящей из верхнего левого угла в нижний правый угол. Транспонирование матрицы A обозначается как A T :
Столбцы и строки изменились таким образом, что:
Имплементация на Python с использованием pandas:
Подробнее об операциях с матрицами и векторами см. в моем репо на Gitgub для этой серии постов.
Нейтральная матрица
Некоторые матрицы имеют особые свойства и регулярно используются в матричной алгебре. Одной из самых важных таких матриц является нейтральная матрица, или единичная матрица. Это квадратная матрица с единицами вдоль главной диагонали и нулями в остальных позициях:
Единичная матрица — это нейтральная по умножению матрица (или нейтральный элемент для умножения). Как и при скалярном умножении на число 1, матричное умножение на нейтральную матрицу не имеет никакого эффекта.
Имплементация на Python с использованием pandas:
Обратная матрица
Нейтральная матрица является обратной самой себе. Не все матрицы обратимы. Необратимые матрицы также называются сингулярными или вырожденными. Обратная матрица вычисляется посредством функции np.linalg.pinv из модуля линейной алгебры библиотеки numpy.
Имплементация на Python с использованием pandas:
Нормальное уравнение
Рассмотрев основы матричного и векторного умножения, теперь мы в том состоянии, когда можно приступать к изучению нормального уравнения. Это уравнение, в котором для вычисления коэффициентов линейной регрессионной модели методом обычных наименьших квадратов используется матричная алгебра:
Мы читаем «для отыскания β надо умножить инверсию произведения транспонированной X и X, на произведение транспонированной X и y», где X — это матрица независимых переменных (включая член пересечения) и y — вектор, содержащий зависимые переменные нашей выборки. Результат β содержит вычисленные коэффициенты. Нормальное уравнение относительно легко выводится из уравнения множественной регрессии, применяя правила матричного умножения, однако соответствующие математические выкладки лежат за пределами объема данного поста.
Указанное нормальное уравнение можно имплементировать на Python, используя для этого только те функции, с которыми мы только что познакомились:
Нормальное уравнение выражает математику регрессии методом обычных наименьших квадратов в очень сжатой форме. Его можно использовать следующим образом (помня о добавлении смещения):
В результате выполнения этого примера получим следующую матрицу:
Это значения представляют коэффициенты β1 и β2, которые соответствуют параметрам пересечения и наклона. К счастью, они согласуются со значениями, которые мы вычислили ранее.
Дополнительные признаки
Часть мощи нормального уравнения состоит в том, что мы теперь имплементировали все, что нам нужно для того, чтобы обеспечить имплементацию множественной линейной регрессии. К счастью, нам не нужно специально создавать функцию для конвертации интересующих нас признаков в матрицу. Библиотека pandas позволяет за один прием отобрать отдельные столбцы для матрицы.
В машинном усвоении закономерностей (Да-да, именно так. См. мои посты « Никто никого не обучает » и « Что такое machine learning? ») в качестве синонима для независимой переменной широко используется понятие «признак», англ. feature. Другими синонимами являются «предсказатель», «предиктор», «регрессор», «объяснительная переменная», либо просто «входная переменная».
Для начала в качестве наших двух признаков отберем рост и возраст:
В результате выполнения этого примера получим следующую ниже матрицу из трех столбцов:
Наша функция нормального уравнения примет эту новую матрицу без какого-либо дальнейшего изменения:
В результате получим нижеследующие коэффициенты:
Эти три числа соответствуют соответственно пересечению, наклону (угловому коэффициенту) для роста (0.013954) и наклону для возраста (0.002799). В целях установления факта улучшения нашей модели за счет этих новых данных можно рассчитать значение R 2 нашей новой модели и сравнить его с представленным ранее.
Множественный R-квадрат
При расчете R 2 в ранее рассмотренном случае мы увидели, каким образом он выражает объем дисперсии, объясненной моделью:
Учитывая, что дисперсия — это средневзвешенная квадратичная ошибка, мы можем умножить оба члена var(ε) и var(y) на размер выборки и прийти к приведенному ниже альтернативному уравнению для R 2 :
Это попросту сумма квадратичных остатков на сумме квадратичных отклонений от среднего. При помощи функций библиотеки pandas dot функция суммы квадратов имплементируется элементарно, что во многом упрощает имплементацию матричного R-квадрата в исходном коде:
Переменная rss обозначает остаточную сумму квадратов, от англ. residual sum of squares (RSS), переменная ess — объясненную сумму квадратов, от англ. explained sum of squares (ESS). Мы можем вычислить матричный R 2 для нашей новой модели следующим образом:
В результате выполнения этого примера получим значение 0.757. Значение R 2 увеличилось на небольшую величину за счет включения возраста. Учитывая, что мы использовали несколько независимых переменных, R 2 теперь называется коэффициентом множественной детерминации.
Скорректированный матричный R-квадрат
Мотивом для добавления в регрессию больше независимых переменных может быть то, что наше значение R 2 всегда растет. Добавление новых независимых переменных не сделает предсказание зависимой переменной сложнее — если новая объяснительная переменная не имеет объяснительной силы, то ее коэффициент просто будет равен 0, и R 2 останется таким же, каким он был без этой независимой переменной.
Скорректированный R̅ 2 зависит от двух дополнительных параметров, n и p, которые относятся соответственно к размеру выборки и числу модельных параметров:
Этот пример возвращает значение 0.756. Оно по-прежнему крупнее изначальной модели, поэтому возраст определенно несет некую объяснительную силу.
Линейная модель в numpy и scipy
F-тест значимости модели
Как мы выяснили в предыдущей серии постов о тестировании гипотез, проверка на основе F-теста применима, когда выполняется сразу несколько тестов статистической значимости. В случае с множественной линейной регрессией, мы проверяем статистическую неотличимость от нуля каких-либо коэффициентов модели, за исключением пересечения.
Поэтому наши нулевая и альтернативная гипотезы будут следующими:
Здесь j — это некий индекс в векторе параметров за исключением пересечения, т.е. свободного члена. Вычисляемая нами F-статистика представляет собой отношение объясненной дисперсии на необъясненной (остаточной) дисперсии. Она может быть выражена через отношение средневзвешенного квадрата регрессионной модели, от англ. mean squared model (MSM) на средневзвешенной квадратичной ошибке, от англ. mean square error (MSE):
Средневзвешенный квадрат регрессионной модели (MSM) равен объясненной сумме квадратов (ESS) деленной на модельную степень свободы, где модельная степень свободы — это число параметров в модели за исключением свободного члена. Средневзвешенная квадратичная ошибка (MSE) равна остаточной сумме квадратов (RSS) деленной на остаточную степень свободы, где остаточная степень свободы — это размер выборки минус число модельных параметров.
После расчета F-статистики мы отыскиваем ее в F-распределении, параметризованном теми же двумя степенями свободы:
В результате проверки будет получено число 1.11x10e-16. Это ничтожно малое число, и, как следствие, можно быть уверенными в том, что модель значима.
Отметим, что при малых выборках F-тест количественно измеряет увеличивающуюся неопределенность, что линейная модель допустима. В условиях случайной выборки из пяти элементов, например, данные иногда едва показывают какую-либо линейную связь вообще, и F-тест трактует данные, как незначимые даже при 50%-ом интервале уверенности.
Категориальные и фиктивные переменные
Теперь мы могли бы попытаться включить в регрессионный анализ «Пол» в качестве признака, однако мы столкнемся с проблемой. Входные данные выражены не числом, а как «М» или «Ж». Это пример категориальной переменной: переменной, которая может принимать одно из конечного множества неупорядоченных и (обычно) нечисловых значений. Другими примерами категориальных переменных является вид спорта, в котором спортсмен специализируется, или отдельно взятое состязание, в котором он наиболее квалифицирован.
Обычные наименьшие квадраты опираются на числовое значение минимизируемого остаточного расстояния. Каким может быть расстояние между плаванием и легкой атлетикой в числовом выражении? Из этого может следовать, что включить категориальные переменные в наше уравнение регрессии невозможно.
Категориальные или номинальные переменные стоят в отдельном ряду по сравнению с непрерывными переменными, т.к. они не лежат на числовой оси. Иногда категории представлены цифрами, как например, почтовые индексы, при этом мы не должны исходить из того, что числовые категории с неизбежностью упорядочены либо что интервал между категориями равный.
К счастью, многие категориальные переменные могут рассматриваться как дихотомические и, в действительности, наши выборочные данные содержат две категории половой принадлежности. Их можно внести в нашу регрессионную модель при условии, что мы преобразуем их в два числа, например, 0 и 1.
Когда такая категория, как вид спорта, принимает более двух значений, для каждого вида спорта можно внести независимую переменную. При этом создают переменную для плавания и еще одну для тяжелой атлетики и т.д. Значение для плавания будет равно 1 для пловцов и 0 — для остальных.
Поскольку половая принадлежность может оказаться для нашей регрессионной модели полезной объяснительной переменной, давайте преобразуем женский пол в 0 и мужской — в 1 и добавим производный столбец, который будет содержать фиктивную переменную.
В результате выполнения этого примера получим 0.809. С участием таких признаков, как рост, возраст и пол, мы успешно объяснили более 80% дисперсии в весе наших олимпийских пловцов.
Относительная мощность
На этом этапе, возможно, было бы целесообразным поинтересоваться, какой признак играет самую важную роль в объяснении наблюдавшегося веса: возраст, пол или рост? Мы могли бы воспользоваться нашим скорректированным R 2 и взглянуть, насколько его значение изменяется, но это потребовало бы от нас повторно рассчитывать регрессию для каждой переменной, которую мы хотим проверить.
Мы не сможем обратиться к величине коэффициентов, потому что диапазоны данных, к которым они применяются, существенно различаются: высота в сантиметрах, возраст в годах и пол в виде фиктивной переменной, в диапазоне от 0 до 1.
Для того чтобы сравнить относительный вклад коэффициентов, можно вычислить стандартизированный коэффициент регрессии, или бета-коэффициент.
В целях вычисления бета-коэффициента мы умножаем каждый коэффициент на отношение стандартных отклонений для связанной независимой переменной к модельной независимой переменной. Это можно имплементировать при помощи следующего ниже исходного кода на Python:
В результате мы получим (округлено до трех десятичных знаков):
Данный результат показывает, что рост является самой важной объяснительной переменной, за которым идут пол и возраст. Преобразование результата в стандартизированные коэффициенты говорит о том, что с увеличением одного стандартного отклонения в росте средний вес увеличивается на 0.65 стандартных отклонений.
Коллинеарность
На данном этапе мы могли бы попытаться продолжить добавлять признаки в модель, стараясь увеличить объяснительную силу.
Например, в нашем распоряжении также имеется столбец «Дата рождения», и может возникнуть соблазн попытаться внести и его. Это дата, но мы легко могли бы конвертировать ее в число, подходящее для использования в регрессии. Это можно сделать, попросту взяв год из даты рождения, воспользовавшись для этого библиотечной функцией pandas pd.to_datetime :
Новый признак «Год рождения» имеет бета-коэффициент всего 0.038, меньше веса признака «Возраст», который мы вычислили ранее. Однако, вес признака «Возраст» теперь показывает значение 0.096. Его относительная важность увеличилась более чем на 65%, поскольку мы добавили признак «Год рождения». Тот факт, что добавление нового признака изменило важность существующего признака, указывает на то, что имеется проблема.
Включив дополнительный параметр «Год рождения», мы непреднамеренно нарушили правило регрессионного оценивания. Посмотрим почему:
Приведенный ниже точечный график возраста пловцов (с джиттером) построен в сопоставлении с их годом рождения. Как вы и ожидали, две переменные очень близко коррелируют:
Мультиколлинеарность
В целях генерирования наилучших оценок коэффициентов множественной регрессии, базовые данные должны подчиняться тем же допущениям, что и простая регрессия плюс одному дополнительному — отсутствию полной мультиколлинеарности. Это означает, что независимые переменные не должны строго линейно коррелировать друг с другом.
На практике независимые переменные часто в определенной мере коллинеарны. Обратите внимание, например, что возраст и рост или пол и рост сами коррелируют друг с другом. Серьезные ошибки в коэффициентах могут возникать, только когда это условие принимает крайние значения.
Если независимые переменные, на самом деле, не являются независимыми, то линейная регрессия не сможет определить относительный вклад каждой независимой переменной. Если два признака так сильно коррелированы, что они всегда изменяются вместе, то каким образом алгоритм сможет различить их относительную важность? Как следствие, в оценках коэффициентов может проявиться высокая дисперсия и высокая стандартная ошибка.
Мы уже видели один симптом высокой мультиколлинеарности: коэффициенты регрессии, которые значительно изменяются, когда независимые переменные добавляются либо удаляются из уравнения. Еще один симптом проявляется, когда во множественной регрессии имеется незначительный коэффициент для отдельно взятой независимой переменной, но значительный R 2 для простой регрессионной модели с использованием этой же независимой переменной.
Хотя эти симптомы служат индикаторами мультиколлинеарности, в целях подтверждения, мы должны напрямую обратиться к взаимной корреляции независимых переменных. Хороший способ определить взаимную корреляцию состоит в проверке корреляции между каждой из независимых переменных, отыскивая коэффициенты в размере 0.8 или больше. Хотя этот простой подход часто срабатывает, нередко ему не удается учитывать ситуации, в которых независимая переменная имеет линейную связь с другими переменными, взятыми вместе.
Самый верный метод оценить степень мультиколлинеарности состоит в оценке регрессии каждой независимой переменной на всех других независимых переменных. Если любой R 2 из этих уравнений близок к 1.0, то имеется высокая мультиколлинеарность. На деле самый крупный из этих R 2 служит в качестве индикатора степени существующей мультиколлинеарности.
После выявления мультиколлинеарности имеется несколько способов решить эту проблему:
Увеличить размер выборки. Больше данных могут дать более точные оценки параметров с меньшими стандартными ошибками.
Совместить признаки в один признак. Если у вас несколько признаков, которые в сущности измеряют тот же атрибут, то следует найти способ их унификации в один признак.
Отбросить проблемную переменную (или переменные).
Ограничить уравнение предсказания. Коллинеарность влияет на коэффициенты модели, но результат может по-прежнему хорошо вписываться в данные.
Учитывая, что возраст и год рождения в сущности несут одинаковую информацию, мы вполне можем отбросить один из этих признаков. Можно легко увидеть, какой из двух содержит больше объяснительной силы, рассчитав двухфакторную регрессию для каждого признака и зависимой переменной.
«Возраст» R 2 = 0.1049, тогда как «Год рождения» R 2 = 0.1050.
Как и ожидалось, между двумя переменными практически нет разницы, и каждая из них объясняет порядка 10% дисперсии в весе. Поскольку год рождения объясняет чуть больше дисперсии, мы его оставим и отбросим признак «Возраст».
Примеры исходного кода для этого поста находятся в моем репо на Github. Все исходные данные взяты в репозитории автора книги.
В следующем коротком посте, посте №4, будет рассмотрен процесс предсказания.


















