- •Об авторе
- •О научном редакторе
- •От издательства
- •Введение
- •Использование Python для data science
- •Для кого эта книга?
- •О чем эта книга?
- •Глава 1. Базовые знания о данных
- •Категории данных
- •Неструктурированные данные
- •Структурированные данные
- •Слабоструктурированные данные
- •Данные временных рядов
- •Источники данных
- •Веб-страницы
- •Базы данных
- •Файлы
- •Получение
- •Очистка
- •Преобразование
- •Анализ
- •Хранение
- •Питонический стиль
- •Выводы
- •Глава 2. Структуры данных Python
- •Списки
- •Создание списка
- •Использование общих методов списков
- •Использование срезов
- •Использование списка в качестве очереди
- •Использование списка в качестве стека
- •Использование списков и стеков для обработки естественного языка
- •Расширение функциональности с помощью списковых включений
- •Кортежи
- •Список кортежей
- •Неизменяемость
- •Словари
- •Список словарей
- •Добавление элементов в словарь с помощью setdefault()
- •Преобразование JSON в словарь
- •Множества
- •Удаление дубликатов из последовательности
- •Общие операции с множеством
- •Упражнение № 1: продвинутый анализ тегов фотографий
- •Выводы
- •NumPy
- •Установка NumPy
- •Создание массива NumPy
- •Выполнение поэлементных операций
- •Использование статистических функций NumPy
- •Упражнение № 2: использование статистических функций numpy
- •pandas
- •Установка pandas
- •pandas Series
- •Упражнение № 3: объединение трех серий
- •pandas DataFrame
- •Упражнение № 4: использование разных типов join
- •scikit-learn
- •Установка scikit-learn
- •Получение набора образцов
- •Преобразование загруженного датасета в pandas DataFrame
- •Разделение набора данных на обучающий и тестовый
- •Преобразование текста в числовые векторы признаков
- •Обучение и оценка модели
- •Создание прогнозов на новых данных
- •Выводы
- •Глава 4. Доступ к данным из файлов и API
- •Импортирование данных с помощью функции open()
- •Текстовые файлы
- •Файлы с табличными данными
- •Упражнение № 5: открытие json-файлов
- •Двоичные файлы
- •Экспортирование данных в файл
- •Доступ к удаленным файлам и API
- •Как работают HTTP-запросы
- •Библиотека urllib3
- •Библиотека Requests
- •Упражнение № 6: доступ к api с помощью requests
- •Перемещение данных в DataFrame и из него
- •Импортирование вложенных структур JSON
- •Конвертирование DataFrame в JSON
- •Выводы
- •Глава 5. Работа с базами данных
- •Реляционные базы данных
- •Понимание инструкций SQL
- •Начало работы с MySQL
- •Определение структуры базы данных
- •Вставка данных в БД
- •Запрос к базе данных
- •Упражнение № 8: объединение «один-ко-многим»
- •Использование инструментов аналитики баз данных
- •Базы данных NoSQL
- •Документоориентированные базы данных
- •Упражнение № 9: вставка и запрос нескольких документов
- •Выводы
- •Глава 6. Агрегирование данных
- •Данные для агрегирования
- •Объединение датафреймов
- •Группировка и агрегирование данных
- •Просмотр конкретных агрегированных показателей по MultiIndex
- •Срез диапазона агрегированных значений
- •Срезы на разных уровнях агрегирования
- •Добавление общего итога
- •Добавление промежуточных итогов
- •Выбор всех строк в группе
- •Выводы
- •Глава 7. Объединение датасетов
- •Объединение встроенных структур данных
- •Объединение списков и кортежей с помощью оператора +
- •Объединение словарей с помощью оператора **
- •Объединение строк из двух структур
- •Реализация join-объединений списков
- •Конкатенация массивов NumPy
- •Объединение структур данных pandas
- •Конкатенация датафреймов
- •Удаление столбцов/строк из датафрейма
- •Join-объединение двух датафреймов
- •Выводы
- •Глава 8. Визуализация
- •Распространенные способы визуализации
- •Линейные диаграммы
- •Столбчатые диаграммы
- •Круговые диаграммы
- •Гистограммы
- •Построение графиков с помощью Matplotlib
- •Установка Matplotlib
- •Использование matplotlib.pyplot
- •Работа с объектами Figure и Axes
- •Создание гистограммы с помощью subplots()
- •Совместимость Matplotlib с другими библиотеками
- •Построение графиков для данных pandas
- •Отображение данных геолокации с помощью Cartopy
- •Выводы
- •Глава 9. Анализ данных о местоположении
- •Получение данных о местоположении
- •Преобразование стандартного вида адреса в геокоординаты
- •Получение геокоординат движущегося объекта
- •Анализ пространственных данных с помощью geopy и Shapely
- •Поиск ближайшего объекта
- •Поиск объектов в определенной области
- •Объединение двух подходов
- •Упражнение № 15: совершенствование алгоритма подбора машины
- •Получение непространственных характеристик
- •Объединение датасетов с пространственными и непространственными данными
- •Выводы
- •Глава 10. Анализ данных временных рядов
- •Регулярные и нерегулярные временные ряды
- •Общие методы анализа временных рядов
- •Вычисление процентных изменений
- •Вычисление скользящего окна
- •Вычисление процентного изменения скользящего среднего
- •Многомерные временные ряды
- •Обработка многомерных временных рядов
- •Анализ зависимости между переменными
- •Выводы
- •Глава 11. Получение инсайтов из данных
- •Ассоциативные правила
- •Поддержка
- •Доверие
- •Лифт
- •Алгоритм Apriori
- •Создание датасета с транзакциями
- •Определение часто встречающихся наборов
- •Генерирование ассоциативных правил
- •Визуализация ассоциативных правил
- •Получение полезных инсайтов из ассоциативных правил
- •Генерирование рекомендаций
- •Планирование скидок на основе ассоциативных правил
- •Выводы
- •Глава 12. Машинное обучение для анализа данных
- •Почему машинное обучение?
- •Типы машинного обучения
- •Обучение с учителем
- •Обучение без учителя
- •Как работает машинное обучение
- •Данные для обучения
- •Статистическая модель
- •Неизвестные данные
- •Пример анализа тональности: классификация отзывов о товарах
- •Получение отзывов о товарах
- •Очистка данных
- •Разделение и преобразование данных
- •Обучение модели
- •Оценка модели
- •Упражнение № 19: расширение набора примеров
- •Прогнозирование тенденций фондового рынка
- •Получение данных
- •Извлечение признаков из непрерывных данных
- •Генерирование выходной переменной
- •Обучение и оценка модели
- •Выводы
204 Глава 9. Анализ данных о местоположении
В скрипте используется как Shapely, так и geopy. Сначала задаем объект Shapely Polygon, включающий местоположение пассажира, как мы делали ранее . Аналогично задаем объекты Point для автомобиля, места подачи и пункта проезда . Затем вычисляем расстояние в метрах с помощью функции geopy distance(). Если такси находится внутри многоугольника, находим расстояние непосредственно между такси и местом подачи . А если нет, то сначала вычисляем расстояние между машиной и пунктом проезда, а затем расстояние между этим пунктом и местом подачи. Складывая их, получаем общее расстояние :
1544
УПРАЖНЕНИЕ № 15: СОВЕРШЕНСТВОВАНИЕ АЛГОРИТМА ПОДБОРА МАШИНЫ
В скрипте выше мы обработали данные о местоположении лишь одного автомобиля, определив расстояние между ним и местом подачи. Измените скрипт таким образом, чтобы он вычислял расстояния между местом посадки и каждой машиной. Для этого объедините точки, представляющие такси, в список, а затем пройдите по этому списку в цикле, используя в теле блоки if/else из предыдущего скрипта. Затем определите ближайший к месту подачи автомобиль.
Объединение пространственных
и непространственных данных
До сих пор в этой главе мы работали исключительно с пространственными данными, но важно понимать, что пространственный анализ часто требует учета и непространственных данных. Например, какой смысл от информации о том, что магазин находится в 16 километрах от текущего местоположения, если мы не уверены, что в нем есть нужный товар? Или, возвращаясь к примеру с такси, что нам даст возможность определить ближайшую машину к месту посадки, если мы не знаем, доступна она или же водитель выполняет другой заказ? В этом разделе мы рассмотрим, как учитывать непространственные данные в рамках пространственного анализа.
Получение непространственных характеристик
Информацию о доступности такси можно получить из датасета, содержащего заказы поездок. Как только на автомобиль будет назначен заказ, можно поместить
Объединение пространственных и непространственных данных 205
эту информацию в структуру данных orders, где будет указываться заказ и его статус: открытый (open) — в процессе либо закрытый (closed) — завершенный. Согласно этой схеме, отфильтровав открытые заказы, мы поймем, какие автомобили недоступны для выполнения нового заказа. Вот как реализовать эту логику в Python:
import pandas as pd orders = [
('order_039', 'open', 'cab_14'), ('order_034', 'open', 'cab_79'), ('order_032', 'open', 'cab_104'), ('order_026', 'closed', 'cab_79'), ('order_021', 'open', 'cab_45'), ('order_018', 'closed', 'cab_26'), ('order_008', 'closed', 'cab_112')
]
df_orders = pd.DataFrame(orders, columns =['order','status','cab']) df_orders_open = df_orders[df_orders['status']=='open'] unavailable_list = df_orders_open['cab'].values.tolist() print(unavailable_list)
Список кортежей orders, используемый в этом примере, можно получить из более полного датасета, например коллекции всех заказов, открытых за последние два часа, которая включает дополнительную информацию о каждом заказе (место подачи, место высадки, время начала, время окончания и т. д.). Для простоты здесь датасет уже сокращен до полей, необходимых для текущей задачи. Мы преобразуем список в объект DataFrame, затем фильтруем его, чтобы включить только заказы со статусом open. Наконец, преобразуем DataFrame в список, содержащий только значения из столбца cab. Список недоступных такси выглядит следующим образом:
['cab_14', 'cab_79', 'cab_104', 'cab_45']
Вооружившись этим списком, проверим другие автомобили и определим, какой из них находится ближе всего к месту подачи. Добавим этот код к предыдущему скрипту:
from geopy.distance import distance pick_up = 46.083822, 38.967845 cab_26 = 46.073852, 38.991890 cab_112 = 46.078228, 39.003949 cab_104 = 46.071226, 39.004947
206 Глава 9. Анализ данных о местоположении
cab_14 = 46.004859, 38.095825 cab_79 = 46.088621, 39.033929 cab_45 = 46.141225, 39.124934
cabs = {'cab_26': cab_26, 'cab_112': cab_112, 'cab_14': cab_14, 'cab_104': cab_104, 'cab_79': cab_79, 'cab_45': cab_45}
dist_list = []
for cab_name, cab_loc in cabs.items(): if cab_name not in unavailable_list: dist = distance(pick_up, cab_loc).m
dist_list.append((cab_name, round(dist)))
print(dist_list)
print(min(dist_list, key=lambda x: x[1]))
Для демонстрации вручную определяем геокоординаты места подачи и всех машин в виде кортежей и передаем их в словарь, где ключами являются названия такси. Затем проходим по словарю и для каждого автомобиля, не входящего в unavailable_list, используем geopy для вычисления расстояния до места подачи. Наконец, выводим на экран весь список доступных такси с указанием расстояния до места подачи, а также ближайший автомобиль:
[('cab_26', 2165), ('cab_112', 2861)] ('cab_26', 2165)
В данном примере cab_26 — ближайший доступный автомобиль.
УПРАЖНЕНИЕ № 16:
ФИЛЬТРАЦИЯ ДАННЫХ С ПОМОЩЬЮ СПИСКОВОГО ВКЛЮЧЕНИЯ
В предыдущем разделе мы отфильтровали список orders так, чтобы остались лишь недоступные машины, предварительно преобразовав orders в DataFrame. Теперь попробуйте сгенерировать список unavailable_list, не используя pandas; вместо этого примените списковые включения. При таком подходе вы сможете получать список такси, назначенных на открытые заказы, одной строкой кода:
unavailable_list = [x[2] for x in orders if x[1] == 'open']
Вам не придется ничего менять в остальной части скрипта.
Объединение пространственных и непространственных данных 207
Объединение датасетов с пространственными и непространственными данными
В предыдущем примере мы хранили пространственные данные (местоположение каждого такси) и непространственные данные (доступные такси) в отдельных структурах данных. Однако иногда выгодно объединить пространственные и непространственные данные в одну структуру.
Учитывайте, что для назначения автомобиля на заказ кроме доступности может потребоваться проверка некоторых других условий. Например, клиенту может понадобиться такси с детским креслом. Чтобы найти нужную машину, необходимо использовать датасет, который включает непространственную информацию о машине, а также расстояние от каждого автомобиля до места подачи. Для вышеупомянутого случая можно использовать датасет, содержащий всего два столбца: название такси и наличие детского кресла. Вот как его создать:
cabs_list = [ ('cab_14',1), ('cab_79',0), ('cab_104',0), ('cab_45',1), ('cab_26',0), ('cab_112',1)
]
В машинах, для которых указано значение 1 во второй колонке, есть детское кресло. Затем мы преобразуем список в датафрейм. Мы также создаем второй датафрейм из dist_list, списка доступных такси и их расстояния до места подачи, который мы сформировали в предыдущем разделе:
df_cabs = pd.DataFrame(cabs_list, columns =['cab', 'seat']) df_dist = pd.DataFrame(dist_list, columns =['cab', 'dist'])
Теперь объединяем эти датафреймы по столбцу cab:
df = pd.merge(df_cabs, df_dist, on='cab', how='inner')
Используем inner join, то есть объединяем только такси, которые есть и в df_cabs, и в df_dist. На практике, поскольку df_distсодержит только доступные на текущий момент автомобили, недоступные машины будут исключены из итогового датасета. Теперь объединенный датафрейм включает как пространственные