www.machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Первый шаг в науке данных с Python - NumPy

Дата публикации Aug 6, 2018

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

Теперь в сети есть много блестящих ресурсов, из которых можно поучиться. Но когда вы только начинаете, это может немного ошеломить количеством доступных ресурсов. В частности, в области науки о данных вы можете найти все эти модные слова, такие как Data Science, AI, машинное обучение, глубокое обучение и многое другое. Это сбивает с толку - с чего начать?

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

Самое главное, чтобы начать; вторая самая важная вещь - продолжать идти.

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

Подождите, но что такое NumPy?

NumPy расшифровывается как Numeric Python. Какдокументыутверждает, что NumPy является фундаментальным пакетом для научных вычислений с Python. Используется для выполнения числовых операций над массивами. NumPy лучше, чем список python, с точки зрения размера, скорости и функциональности. Подробное описание для сравнения между списком Python и массивами NumPy можно найти вэта ссылка,

Перед началом использования NumPy его необходимо установить в вашей системе. Вы можете установить его, используя pip или anaconda. Код в этом посте использует Python3 и NumPy, установленные с Anaconda. Я не буду вдаваться в подробности установки. Видетьэта ссылкакак установить NumPy.

Хватит разговоров. Давайте перейдем к хорошим вещам.

Вы можете найти полный код в этом посте по ссылке ниже.

Баджрачарии-Kshitij / NumPy

numpy - Изучение основ NumPy при решении задач

github.com

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

import numpy as np

Здесь мы даем более короткое имя NumPy - np. Это называется псевдонимами. Впредь, когда нам понадобится доступ к каким-либо методам из пакета NumPy, мы будем делать это с помощью «np». Видетьэта ссылкадля получения дополнительной информации о псевдонимах.

Разве мы не собираемся решать проблемы?

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

Проблема 1

Вам предоставляется 5 цилиндрических контейнеров с различным радиусом и высотой от 5 до 25 см. Узнать
а) объем воды, который может содержать каждый контейнер,
б) общий объем воды, который могут содержать все контейнеры,
в) какой контейнер может вместить самый большой объем и сколько,
г) какой контейнер может вместить наименьший объем и сколько,
e) каково среднее, срединное и стандартное отклонение объемов воды, которые могут содержаться в контейнерах?

Это основная арифметика. Мне не нужен NumPy, чтобы решить это.

Конечно, нет. А пакеты Python были созданы и способны решать гораздо более сложные проблемы. Но цель здесь состоит в том, чтобы дать только базовое представление о том, как работает NumPy, чтобы впоследствии эти методы могли быть применены к проблеме гораздо большей величины. Все, что я пытаюсь сделать, это не отпугнуть новичков.

Решение 1

Сначала нам нужны радиус и высота для 5 цилиндрических контейнеров. Значения радиуса и высоты определены в диапазоне от 5 до 25 см. Давайте сначала определим их в переменных.

no_of_items = 10
lower_limit = 5
upper_limit = 25

Количество элементов равно 10, потому что нам нужно 2 значения для каждого из пяти контейнеров - одно для радиуса, а другое для высоты.

Просто немного на голову; В отличие от других ресурсов в Интернете о NumPy, которые следуют определенному шаблону или порядку, в котором вводятся различные атрибуты или методы, эта публикация этого не сделает. Поскольку наша цель состоит в том, чтобы решить стоящую проблему, мы будем двигаться вперед, вводя понятия в том порядке, который поможет нам решить проблему. Итак, все будет случайно; Говоря об этом, давайте сгенерируем случайные числа.

np.random.seed(0)
values = np.random.randint(lower_limit, upper_limit, no_of_items)

np.random.randintвыше принимает три параметра - нижний предел 5, верхний предел 25 и количество предметов 10 Результатом этого выполнения будет то, чтоvaluesбудет назначен массив NumPy из 10 случайных чисел от 5 до 25. Это один из способов создания массива NumPy. Обратите внимание, что здесь нижний предел является включающим, а верхний - исключительным. Таким образом, 25 никогда не появляется в массиве.np.random.seedэто интересный метод. Он принимает один аргумент (0 выше), и он возвращает набор случайных чисел. Интересно то, что независимо от того, выполняете ли вы вышеуказанный блок кода - сейчас, после обеда или через год - вы всегда получаете один и тот же набор случайных чисел. В отличие от удаленияnp.random.seedиз приведенного выше блока кода вы получаете различную коллекцию случайных чисел при каждом выполнении. Я использовал 0 здесь для затравки, но вы можете использовать любое целое число; вы просто получите другой набор случайных чисел, чем мой.

НОТАЕсть и другие методы для генерации случайных чисел.np.random.randintгенерирует целые числа Если вам нужны числа с плавающей точкой, вы можете использоватьnp.random.randа такжеnp.random.randn, Вы можете исследовать это самостоятельно.

Если вы сейчас распечатываетеvaluesвы получите массив NumPy, подобный этому

array([17, 20,  5,  8,  8, 12, 14, 24, 23,  9])

Здесь мы видим, что есть одна открывающая и закрывающая квадратная скобка. Это показывает, чтоvaluesэто одномерный массив. Чтобы проверить это дальше, вы можете использоватьvalues.ndimкоторый возвращает значение1, обозначая, чтоvaluesэто 1D. Теперь, чтобы убедиться, что в массиве фактически 10 элементов, мы можем использоватьvalues.sizeкоторый возвращается10длина массива. Также, чтобы узнать, какой тип значений содержится в списке, вы можете использоватьvalues.dtype, который в этом случае вернетсяdtype('int64')обозначает, что массив содержит целые числа.

Далее, давайте посмотрим на форму этого массива, используяvalues.shape, который возвращает(10,), Здесь запятая разделяет количество элементов по каждому измерению. посколькуvalues1D, после запятой нет номера. Это всего лишь некоторые атрибуты, чтобы познакомиться с NumPy. Давайте вернемся к проблеме.

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

no_of_rows = 5
no_of_columns = 2
containers = values.reshape(no_of_rows, no_of_columns)

Метод reshape изменяет форму массива NumPy на любое указанное нами измерение; единственное требование состоит в том, чтобы произведение количества элементов по каждому измерению равнялось общему количеству элементов. Здесь мы конвертируемvaluesв двумерный массив с 5 строками (по одному для каждого контейнера) и 2 столбцами (по одному для радиуса, а по высоте для другого) и сохраните его вcontainers, Теперь, если вы распечатываетеcontainersвы увидите что-то вроде следующего.

array([[17, 20],
[ 5, 8],
[ 8, 12],
[14, 24],
[23, 9]])

Как мы видим, есть 2 открывающие и закрывающие квадратные скобки, так что это двумерный массив. Проверьте это используяcontainers.ndim, Форма также меняется сейчас. Пытатьсяcontainers.shapeи вы увидите, что он возвращается(5,2),

Теперь, когда у нас есть 2D-массив, давайте разделим массивы по радиусу и высоте. Для этого мы будем использовать нарезку. Здесь мы имеем дело только с двумя столбцами, поэтому нарезка будет довольно простой. Для более подробной информации о нарезке см.этот урок,

Допустим, первый столбец представляет радиус, а второй - высоту. Давайте нарезатьcontainers,

radius = containers[:,0]

Это определяет, что мы берем все строки (:) и только первый столбец (0). Аналогично, для высоты мы берем все строки (:) и только второй столбец (1).

height = containers[:,1]

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

volume = np.pi*(radius**2)*height

Если мы сейчас распечатаемvolume, он возвращает массив как

array([18158.40553775,   628.31853072,  2412.74315796, 14778.05184249,14957.12262374])

С помощью одной строки кода он вычислил объемы для всех 5 цилиндров. Здесь мы просто берем 1D массив с 5 элементами. NumPy способен выполнять вычисления многомерных массивов с сотнями и тысячами элементов по каждому измерению быстро и очень эффективно. Это сила NumPy.

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

total_volume = volume.sum()

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

radius_squared = np.square(radius)
dot_product = np.dot(radius_squared, height)
total_volume_by_dot_product = np.pi*dot_product

total_volumeа такжеtotal_volume_by_dot_productоба дают одинаковый результат. Точечный продукт работает здесь, потому что и radius_squared и height являются одномерными. Для двумерной матрицы она должна удовлетворять требованию, чтобы количество столбцов первой матрицы было равно количеству строк второй матрицы. Таким образом, если две двумерные матрицы имеют одинаковые размеры, перед выполнением точечного произведения необходимо найти транспонирование одной матрицы с помощьюnp.transpose()метод.

Теперь, чтобы определить, какой цилиндр может вместить максимальный объем воды, мы можем использоватьmaxметод и индекс этого цилиндра в массиве можно найти с помощьюargmaxметод.

max_volume = volume.max()
index_of_max_volume = volume.argmax()

Точно так же мы можем использоватьminметод, чтобы найти минимальный объем иargminнайти индекс цилиндра в массиве

min_volume = volume.min()
index_of_min_volume = volume.argmin()

Наконец, мы можем рассчитать среднее, срединное и стандартное отклонение объемов цилиндров.

volume_mean = np.mean(volume)
volume_median = np.median(volume)
volume_standard_deviation = np.std(volume)

Проблема 2

25 карточек с номерами от 1 до 25 случайным образом распределяются между 5 людьми. Найдите сумму карт для каждого человека так, чтобы для 1-го человека сумма была значением 1-й карты за вычетом суммы остальных карт; для 2-го лица сумма - это значение 2-й карты за вычетом суммы остальных карт и т. д. Человек, для которого сумма карт самая большая, будет победителем. Найди победителя.

Решение 2

На этот раз нам нужно 25 чисел от 1 до 25. В задаче 1 мы сгенерировали массив NumPy, используяnp.random.randintметод. Теперь давайте посмотрим на второй метод генерации массива NumPy. На этот раз мы будем использоватьarangeметод. Обратите внимание, что это странно, а не устраивает.

numbers = np.arange(1,26)

Какnp.random.randintВ методе нижний предел является включающим, а верхний - исключительным. Нижний предел, если он не определен, заставит массив NumPy начинаться с 0. У нас также естьstepпараметр дляarange, который, если он определен, будет генерировать кратныеstepмежду начальным и конечным пределами. На данный момент, если вы проверитеnumbersу вас будет следующий массив.

array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25])

Теперь, когда у нас есть карты с номерами от 1 до 25, давайте перемешаем их перед раздачей. Для этого мы используемnp.random.shuffle,

np.random.shuffle(numbers)

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

array([12, 22, 20, 19, 3, 23, 21, 17, 11, 1, 4, 5, 16, 9, 14, 10, 6, 18, 15, 8, 25, 2, 13, 7, 24])

Это только один из возможных способов. Это потому чтоshuffleметод меняет порядокnumbersна каждом пробеге. Ваш будет совсем другим.

Отлично. Мы перетасовали наши карты. Давайте теперь распределим их поровну среди 5 человек, поэтому по 5 карт для каждого человека.

reshaped_numbers = numbers.reshape(5,5)

reshaped_numbersвыглядит примерно так.

array([[12, 22, 20, 19,  3],
[23, 21, 17, 11, 1],
[ 4, 5, 16, 9, 14],
[10, 6, 18, 15, 8],
[25, 2, 13, 7, 24]])

5 карточек по 5 человек в двухмерной матрице. Отлично. Теперь все, что нам нужно сделать, это найти сумму для каждого человека. Для этого добавьте диагональный элемент и вычтите остальные. Итак, сумма за 1-го человека будет12-22-20-19-3, сумма за 2-го человека будет-23+21-17-11-1, и так далее. Чтобы сделать это, нам нужна матрица, которая имеет диагональные элементы, такие же, как и выше, но остальные элементы отменяются. Во-первых, давайте получим эту диагональ, используя матрицу идентичности.

Глаз за Я делает весь мир слепым. Ну кроме диагоналей.

Чтобы сгенерировать матрицу идентичностиI, мы используемeyeметод. посколькуIквадратная матрица, нам нужен только один аргумент. В этом случае нам нужна матрица 5х5.

I = np.eye(5)

Это создаст следующую Матрицу идентичности.

array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])

Теперь, если мы умножим,reshaped_numbersсIпоэлементное умножение сохранит только диагональные элементы и удалит все остальные.

diagonal_matrix = np.multiply(reshaped_numbers,I)

Так,diagonal_matrixбудет выглядеть примерно так

array([[12.,  0.,  0.,  0.,  0.],
[ 0., 21., 0., 0., 0.],
[ 0., 0., 16., 0., 0.],
[ 0., 0., 0., 15., 0.],
[ 0., 0., 0., 0., 24.]])

Далее нам понадобятся отрицательные недиагональные элементы. Для этого нам просто нужна матрица с 0 по диагонали и -1 везде. Это можно получить, если вычесть единичную матрицуUиз матрицы идентичностиI,Uэто матрица со всеми единицами.Uне обязательно должна быть квадратной матрицей, поэтому нам нужно определить как количество строк, так и количество столбцов.

U = np.ones((5,5))

Так,Uтеперь выглядит

array([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])

Обратите внимание, что аргументonesэто кортеж (5,5) вместо 5,5, как в случаеreshapeи другие методы, которые мы видели до сих пор. Там также похожийzerosметод, который генерирует матрицу заданной формы со всеми нулями. А пока давайте сгенерируем матрицу, которая нам нужна.

I_minus_U = I - U

Когда мы вычитаем матрицу единиц из матрицы идентичности, мы получаем следующую матрицу.

array([[ 0., -1., -1., -1., -1.],
[-1., 0., -1., -1., -1.],
[-1., -1., 0., -1., -1.],
[-1., -1., -1., 0., -1.],
[-1., -1., -1., -1., 0.]])

Диагонали 0, а остальные -1. Мы снова выполняем поэлементное умножениеreshaped_numbersсI_minus_Uчтобы получить нашу требуемую матрицу.

negative_diagonal_matrix = np.multiply(reshaped_numbers,I_minus_U)

negative_diagonal_matrixсейчас выглядит примерно так.

array([[  0., -22., -20., -19.,  -3.],
[-23., 0., -17., -11., -1.],
[ -4., -5., 0., -9., -14.],
[-10., -6., -18., 0., -8.],
[-25., -2., -13., -7., 0.]])

Теперь все, что нам нужно сделать, это объединитьdiagonal_matrixа такжеnegative_diagonal_matrixс помощьюaddметод.

combined_matrix = np.add(diagonal_matrix, negative_diagonal_matrix)

Поэлементное сложение приводит кcombined_matrixчтобы выглядеть примерно так.

array([[ 12., -22., -20., -19.,  -3.],
[-23., 21., -17., -11., -1.],
[ -4., -5., 16., -9., -14.],
[-10., -6., -18., 15., -8.],
[-25., -2., -13., -7., 24.]])

Наконец, все, что осталось сделать, это выполнить построчное сложение наcombined_matrix,

sum_matrix = combined_matrix.sum(axis=1)

Вот,axis=1выполняет построчное сложение. Если вам нужно добавить столбец, используйтеaxis=0,

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

array([-52., -31., -16., -27., -23.])

Тот, у кого наибольшее число, считается победителем. Чтобы найти индекс победителя, мы используемargmax,

winner = np.argmax(sum_matrix)

Обновить:

Как @Паял Бхатияупомянутое в ее ответе,добавление по столбцами нетпострочно, На первый взгляд может показаться, что мы делаем сложение по строкам, и именно это мы и хотели. Но способ работы суммы NumPy немного сложнее, чем этот. Перейдите по ссылке ниже, чтобы лучше понять, как работает сумма NumPy.

Понимание суммы NumPy

Если вы не знаете, что такое NumPy или как он работает, сначала прочтите этот пост.

towardsdatascience.com

Проблема 3

Вам дают веревку длиной 5 метров. Разрежьте веревку на 9 частей так, чтобы каждая часть была одинаковой длины.

Решение 3

Нам нужно разрезать веревку в равноудаленных точках, чтобы было 9 частей. Итак, помимоstartа такжеendочки, нам нужно еще 8 очков; всего 10 баллов.

start = 0
end = 5
no_of_points = 10

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

np.linspace(start, end, no_of_points)

Это даст нам следующий массив

array([0.        , 0.55555556, 1.11111111, 1.66666667, 2.22222222,
2.77777778, 3.33333333, 3.88888889, 4.44444444, 5. ])

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

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

Я хочу создавать классные вещи, а не это.

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

В следующем посте мы рассмотрим еще один фундаментальный пакет в науке о данных - панды.

Начало пути к науке о данных (часть 1): серия «Панды»

Теперь, когда мы сделали наш первый шаг в науке о данных,

towardsdatascience.com

Оригинальная статья

Footer decor

© www.machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map