Получение качественных данных — это первый и наиболее важный шаг в любом проекте по машинному обучению. Специалисты Data Science часто применяют различные методы получения датасетов. Они могут использовать общедоступные данные, а также данные, доступные по API или получаемые из различных баз данных, но чаще всего комбинируют перечисленные методы.
Цель этой статьи — представить краткий обзор трех разных методов извлечения данных с использованием языка Python. Я расскажу, как делать это с помощью Jupyter Notebook. В своей предыдущей статье я писала о применении некоторых команд, запускаемых в терминале.
SQL
Если вам нужно получить данные из реляционной базы данных, скорее всего, вы будете работать с языком SQL. Библиотека SQLAlchemy позволит связать ваш код в ноутбуке с наиболее распространенными типами баз данных. По ссылке вы найдете информацию о том, какие базы данных поддерживаются и как осуществить привязку к каждому типу.
Вы можете использовать библиотеку SQLAlchemy, чтобы просматривать таблицы и запрашивать данные, или писать необработанные запросы. Для привязки к базе данных понадобится адрес URL с вашими идентификационными данными. Далее нужно инициализировать метод create_engine
для создания подключения.
from sqlalchemy import create_engine
engine = create_engine('dialect+driver://username:password@host:port/database')
Теперь вы можете писать запросы к базе данных и получать результаты.
connection = engine.connect()
result = connection.execute("select * from my_table")
Скрапинг
Веб-скрапинг используется для загрузки данных с веб-сайтов и извлечения необходимой информации с их страниц. Существует множество библиотек Python, применимых для этого, но самой простой является Beautiful Soup.
Вы можете установить пакет через pip.
pip install BeautifulSoup4
Давайте на простом примере разберемся, как этим пользоваться. Мы собираемся применить Beautiful Soup и библиотеку urllib, чтобы соскрапить названия отелей и цены на них с веб-сайта TripAdvisor.
Сначала импортируем все библиотеки, с которыми собираемся работать.
from bs4 import BeautifulSoup
import urllib.request
Теперь загружаем контент страницы, которую будем скрапить. Я хочу собрать данные о ценах на отели на греческом острове Крит и беру адрес URL, содержащий перечень отелей в этом месте.
Код внизу определяет адрес URL как переменную и использует библиотеку urllib для открытия страницы, а библиотеку Beautiful Soup — для ее чтения и возвращения результатов в простом формате. Часть данных на выходе показана под кодом.
URL = 'https://www.tripadvisor.co.uk/Hotels-g189413-Crete-Hotels.html'
page = urllib.request.urlopen(URL)
soup = BeautifulSoup(page, 'html.parser')
print(soup.prettify())
Теперь давайте получим список с названиями отелей на странице. Мы введем функцию find_all
, которая позволит извлечь части интересующего нас документа. Можно по-разному фильтровать его, используя функцию find_all
, чтобы передать одну строку, регулярное выражение или список. Также можно отфильтровать один из атрибутов тега — это как раз тот метод, который мы применим. Если вы не знакомы с тегами и атрибутами языка HTML, обратитесь за кратким обзором к этой статье.
Чтобы понять, как наилучшим образом обеспечить доступ к данным в теге, нам нужно проверить код для этого элемента на странице. Находим код к названию отеля, кликая правой кнопкой мыши по названию в списке, как показано на рисунке ниже.
После клика на inspect
появится код элемента, а раздел с названием отеля будет выделен цветом.
Мы видим, что название отеля — единственный кусочек текста в классе (class) с наименованием listing_title
. После класса идет код и название этого атрибута к функции find_all
, а также тег div
.
content_name = soup.find_all('div', attrs={'class': 'listing_title'})
print(content_name)
Каждый раздел кода с названием отеля возвращается в виде списка.
Чтобы извлечь названия отелей из кода, воспользуемся функцией getText
библиотеки Beautiful Soup.
content_name_list = []
for div in content_name:
content_name_list.append(div.getText().split('\n')[0])
print(content_name_list)
Названия отелей возвращаются в виде списка.
Тем же способом получаем данные о цене. Структура кода для цены показана ниже.
Как видите, мы можем работать с кодом, очень похожим на тот, что использовали для отелей.
content_price = soup.find_all('div', attrs={'class': 'price-wrap'})
print(content_price)
В случае с ценой есть небольшая сложность. Ее можно увидеть, запустив следующий код:
content_price_list = []
for div in content_price:
content_price_list.append(div.getText().split('\n')[0])
print(content_price_list)
Результат продемонстрирован ниже. Если в списке отелей указано уменьшение цены, в дополнение к некоторому тексту возвращается как исходная цена, так и итоговая. Чтобы устранить эту проблему, мы просто возвращаем цену, актуальную на сегодняшний день.
Можем воспользоваться простой логикой, чтобы получить последнюю цену, указанную в тексте.
content_price_list = []
for a in content_price:
a_split = a.getText().split('\n')[0]
if len(a_split) > 5:
content_price_list.append(a_split[-4:])
else:
content_price_list.append(a_split)
print(content_price_list)
Это даст нам следующий результат:
API
API — программный интерфейс приложения (от англ. application programming interface). С позиции извлечения данных это веб-система, обеспечивающая конечную точку данных, с которой вы можете связаться посредством программирования. Обычно данные возвращаются в формате JSON или XML.
Этот метод, вероятно, пригодится вам в машинном обучении. Я приведу простой пример извлечения данных о погоде с общедоступного API Dark Sky. Чтобы подключиться к нему, нужно зарегистрироваться, и у вас будет 1000 бесплатных вызовов в день. Этого должно быть достаточно для пробы.
Для доступа к данным из Dark Sky я воспользуюсь библиотекой requests
. Первым делом мне нужно получить корректный URL для запроса. Помимо прогноза, Dark Sky предоставляет исторические данные о погоде. В этом примере я возьму их, а корректный URL получу из документации.
Структура этого URL:
https://api.darksky.net/forecast/[key]/[latitude],[longitude],[time]
Мы будем использовать библиотеку
requests
, чтобы получитьрезультаты для конкретной широты и долготы, а также дату и время. Представим, что после извлечения ежедневных данных о ценах на отели Крита мы решили выяснить, связана ли ценовая политика с погодой.
Для примера давайте возьмем координаты одного из отелей в списке — Mitsis Laguna Resort & Spa.
Сначала создадим URL с корректными координатами, а также запрашиваемыми временем и датой. Используя библиотеку requests
, получим доступ к данным в формате JSON.
import requests
request_url = 'https://api.darksky.net/forecast/fd82a22de40c6dca7d1ae392ad83eeb3/35.3378,-25.3741,2019-07-01T12:00:00'
result = requests.get(request_url).json()
result
Чтобы результаты было легче читать и анализировать, мы можем преобразовать данные в датафрейм.
import pandas as pd
df = pd.DataFrame.from_dict(json_normalize(result), orient='columns')
df.head()
Есть еще много вариантов для автоматизации извлечения данных с помощью этих методов. В случае с веб-скрапингом можно написать разные функции, чтобы автоматизировать процесс и облегчить извлечение данных для большего количества дней и/или мест. В этой статье я хотела сделать обзор и привести достаточно примеров с кодом. Следующие материалы будут более подробными: я расскажу, как создавать большие датасеты и анализировать их, применяя описанные выше методы.
Благодарю за внимание!
Комментариев нет:
Отправить комментарий