Быстрая загрузка большого количества данных в Google Colab
Доброго времени суток, Хабр. Решил поделиться своим знанием, как можно быстро загрузить большое количество файлов в Google Colab с Google Drive.
Всем известно, что Google Colab отличная бесплатная платформа для обучения и экспериментов над Нейронными Сетями.
На платформе Google Colab Вам бесплатно предоставят мощную видеокарту на которой вы сможете поэкспериментировать с обучением своей нейросети на протяжении примерно 12 часов.
Затем сеанс прервется, но на следующий день от Google можно опять будет получить видеокарту и продолжить свои эксперименты.
Нейронным сетям требуется очень много данных для обучения, особенно если речь идет о нейросетях работающих с изображениями.
Для обучения таких нейросетей необходимо загрузить в обучающую и валидационную выборки тысячи и сотни изображений. К сожалению, если эти изображения загружать непосредственно из вашего Google Drive, это занимает неприлично долгое время — десятки минут или даже часы. Ведь каждое обращение за файлом в Google Drive и получение от него ответа с содержимым файла происходит последовательно и не быстро.
Обидно тратить время доступа к бесплатной видеокарте на загрузку данных, да и не разумно это.
А мы люди разумные, поэтому мы один раз обратимся к Google Drive считаем наши данные запакованные заранее в zip архив, распакуем полученный zip архив в память Google Colab и считаем свои данные со скоростью в сотни раз большей чем с Google Drive последовательно по одному файлу.
Для эксперимента со скорость загрузки данных в Colab я взял имеющуюся у меня базу «Airplanes» для сегментационной нейросети.
В этой базе есть папка с изображениями «самолеты» и папка «сегментация», где хранятся маски изображений самолетов из вышеназванной папки.
В каждой папке по 1005 изображений 1920*1080.
В общей сложности нам предстоит загрузить 2010 файлов.
Я заранее загрузил к себе на Google Drive как саму базу с изображениями, так и ее zip архив.
Структура Обучающей Базы:
Итак, приступим к скоростной загрузке данных с Google Drive:
-
Запускаем Google Colab и импортируем необходимые нам для этого библиотеки и модули
Выполняем команду на подключение к Google Drive
Переходим по ссылке для выбора свое аккаунта Google
Выбираем свой аккаунт в Google
Подтверждаем доступ Colab к Google Drive
Копируем авторизационный код для доступа к Google Drive
Вставляем авторизационный код в строку и получаем доступ к своему Google Drive
Прописываем путь к архиву с обучающей базой данных и разархивируем ее память Colab
Для тестирования скорости чтения файлов я написал функцию, которая пройдется по всем подкаталогам обучающей базы и в каждом подкаталоге прочитает все файлы которые в нем хранятся.
Тестируем скорость чтения всех файлов
Как видно, время за которое мы загрузили 2010 файлов c размером изображения 1920*1080 составило всего 0,96 сек.
То есть, менее чем за секунду, мы загрузили весь наш объем информации.
Как мы видим для загрузки из каталога 2010 файлов хранящихся на Google Drive нам потребовалось уже 1500 секунд, а ведь это 25 минут.
Это 25 минут простоя вашего экспериментов с нейросетью.
Надеюсь, статья была для вас полезной и теперь загрузка большого количества файлов с Google Drive в Colab больше уже не проблема.
Загружайте свои обучающие данные в сотни раз быстрее чем делали до этого ранее.
Всего четыре простых шага.
- Запаковать Обучающую Базу в zip архив.
- Загрузить zip файл с Обучающей Базой к себе на Google Drive
- Распаковать zip файл с Обучающей базой в память Colab
- Прочитать все файлы памяти Colab в вашу программу
Для тех, кому нужен код, описанный в статье, добро пожаловать ко мне на GitHub.
Get Started: 3 Ways to Load CSV files into Colab
Data science is nothing without data. Yes, that’s obvious. What is not so obvious is the series of steps involved in getting the data into a format which allows you to explore the data. You may be in possession of a dataset in CSV format (short for comma-separated values) but no idea what to do next. This post will help you get started in data science by allowing you to load your CSV file into Colab.
Colab (short for Colaboratory) is a free platform from Google that allows users to code in Python. Colab is essentially the Google Suite version of a Jupyter Notebook. Some of the advantages of Colab over Jupyter include an easier installation of packages and sharing of documents. Yet, when loading files like CSV files, it requires some extra coding. I will show you three ways to load a CSV file into Colab and insert it into a Pandas dataframe.
(Note: there are Python packages that carry common datasets in them. I will not discuss loading those datasets in this article.)
To start, log into your Google Account and go to Google Drive. Click on the New button on the left and select Colaboratory if it is installed (if not click on Connect more apps, search for Colaboratory and install it). From there, import Pandas as shown below (Colab has it installed already).
import pandas as pd
1) From Github (Files < 25MB)
The easiest way to upload a CSV file is from your GitHub repository. Click on the dataset in your repository, then click on View Raw. Copy the link to the raw dataset and store it as a string variable called url in Colab as shown below (a cleaner method but it’s not necessary). The last step is to load the url into Pandas read_csv to get the dataframe.
url = 'copied_raw_GH_link'df1 = pd.read_csv(url)# Dataset is now stored in a Pandas Dataframe
2) From a local drive
To upload from your local drive, start with the following code:
from google.colab import files
uploaded = files.upload()
It will prompt you to select a file. Click on “Choose Files” then select and upload the file. Wait for the file to be 100% uploaded. You should see the name of the file once Colab has uploaded it.
Finally, type in the following code to import it into a dataframe (make sure the filename matches the name of the uploaded file).
import iodf2 = pd.read_csv(io.BytesIO(uploaded['Filename.csv']))# Dataset is now stored in a Pandas Dataframe
3) From Google Drive via PyDrive
This is the most complicated of the three methods. I’ll show it for those that have uploaded CSV files into their Google Drive for workflow control. First, type in the following code:
# Code to read csv file into Colaboratory:!pip install -U -q PyDrive
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials# Authenticate and create the PyDrive client.
auth.authenticate_user()
gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
drive = GoogleDrive(gauth)
When prompted, click on the link to get authentication to allow Google to access your Drive. You should see a screen with “Google Cloud SDK wants to access your Google Account” at the top. After you allow permission, copy the given verification code and paste it in the box in Colab.
Once you have completed verification, go to the CSV file in Google Drive, right-click on it and select “Get shareable link”. The link will be copied into your clipboard. Paste this link into a string variable in Colab.
link = 'https://drive.google.com/open?id=1DPZZQ43w8brRhbEMolgLqOWKbZbE-IQu' # The shareable link
What you want is the id portion after the equal sign. To get that portion, type in the following code:
fluff, >print (id) # Verify that you have everything after '='
Finally, type in the following code to get this file into a dataframe
downloaded = drive.CreateFile()
downloaded.GetContentFile('Filename.csv')
df3 = pd.read_csv('Filename.csv')# Dataset is now stored in a Pandas Dataframe
Final Thoughts
These are three approaches to uploading CSV files into Colab. Each has its benefits depending on the size of the file and how one wants to organize the workflow. Once the data is in a nicer format like a Pandas Dataframe, you are ready to go to work.
Bonus Method — My Drive
Thank you so much for your support. In honor of this article reaching 50k Views and 25k Reads, I’m offering a bonus method for getting CSV files into Colab. This one is quite simple and clean. In your Google Drive (“My Drive”), create a folder called data in the location of your choosing. This is where you will upload your data.
From a Colab notebook, type the following:
from google.colab import drive
drive.mount('/content/drive')
Just like with the third method, the commands will bring you to a Google Authentication step. You should see a screen with Google Drive File Stream wants to access your Google Account. After you allow permission, copy the given verification code and paste it in the box in Colab.
In the notebook, click on the charcoal > on the top left of the notebook and click on Files. Locate the data folder you created earlier and find your data. Right-click on your data and select Copy Path. Store this copied path into a variable and you are ready to go.
path = "copied path"
df_bonus = pd.read_csv(path)# Dataset is now stored in a Pandas Dataframe
What is great about this method is that you can access a dataset from a separate dataset folder you created in your own Google Drive without the extra steps involved in the third method.
Работа с файлами в Google Colab
Для построения модели нам нужны данные. И очень часто эти данные содержатся во внешних файлах. Мы уже столкнулись с этим, когда работали с рекомендательными системами и временными рядами. Предлагаю сегодня рассмотреть этот вопрос более детально.
Содержание занятия
- Общее описание процесса
- Датасет «Титаник»
- Способ 1. Вручную через вкладку «Файлы»
- Способ 2. Через объект files библиотеки google.colab
- Просмотр содержимого в папке /content/
- Модуль os и метод .walk()
- Команда !ls
- Шаг 1. Обработка и анализ данных
- Исследовательский анализ данных (EDA)
- Пропущенные значения
- Категориальные переменные
- Отбор признаков
- Нормализация данных
- Соревнование «Титаник»
- Вопросы для закрепления
Общее описание процесса
В целом работа с файлами в Google Colab состоит из следующих этапов.
- Этап 1. Подгрузка файлов с локального компьютера на сервер Google
- Этап 2. Чтение файла
- Этап 3. Построение модели и прогноз
- Этап 4. Сохранение результата в новом файле на сервере Google
- Этап 5. Скачивание обратно на жесткий диск
Пройдемся по каждому из них. Но прежде поговорим про данные.
Датасет «Титаник»
На этом занятии предлагаю взять датасет о пассажирах корабля «Титаник», который, как известно, затонул в 1912 году при столкновении с айсбергом. Часть пассажиров выжила, но многие, к сожалению, погибли. В предложенном датасете собрана информация о самих пассажирах (признаки), а также о том, выжили они или нет (целевая переменная).
Данные уже разделены на обучающую и тестовую выборки. Скачаем их.
Этап 1. Подгрузка файлов в Google Colab
Если внешние файлы хранятся на локальном компьютере, то нам нужно подгрузить их в так называемое «Сессионное хранилище» (session storage, по сути, сервер Google).
Слово «сессионное» указывает на то, что данные, как я уже говорил, хранятся временно и после завершения очередной сессии стираются.
Подгрузить данные с локального компьютера можно двумя способами.
Способ 1. Вручную через вкладку «Файлы»
Этот способ мы использовали до сих пор. В качестве напоминания приведу скриншоты подгрузки файла train.csv.
Способ 2. Через объект files библиотеки google.colab
К объекту files мы применяем метод .upload(), который передает нам словарь. Ключами этого словаря будут названия файлов, а значениями — сами подгруженные данные. Приведем пример с файлом test.csv.
# из библиотеки google.colab импортируем класс files
from google . colab import files
# создаем объект этого класса, применяем метод .upload()
uploaded = files . upload ( )Нам будет предложено выбрать файл на жестком диске.
# посмотрим на содержимое переменной uploaded
Все что идет после двоеточия ( : ) и есть наш файл. Он содержится в формате bytes, о чем свидетельствует буква b перед строкой файла (подробнее об этом ниже).
Этап 2. Чтение файлов
После загрузки оба файла (train.csv и test.csv) оказываются в сессионном хранилище в папке под названием /content/.
Просмотр содержимого в папке /content/
Модуль os и метод .walk()
Для того чтобы просмотреть ее содержимое внутри ноутбука, мы можем воспользоваться модулем os (отвечает за взаимодействие Питона с операционной системой) и, в частности, методом .walk() (позволяет «пройтись» по содержимому конкретной папки).
# импортируем модуль os
# выводим пути к папкам (dirpath) и наименования файлов (filenames) и после этого
for dirpath , _ , filenames in os . walk ( ‘/content/’ ) :
# во вложенном цикле проходимся по названиям файлов
for filename in filenames :
# и соединяем путь до папок и входящие в эти папки файлы
# с помощью метода path.join()
print ( os.path . join ( dirpath , filename ) )
/content/test.csv
/content/train.csv
/content/.config/gce
/content/.config/.last_update_check.json
/content/.config/config_sentinel
/content/.config/.last_opt_in_prompt.yaml
/content/.config/active_config
/content/.config/.last_survey_prompt.yaml
/content/.config/logs/2021.11.01/13.34.55.836922.log
/content/.config/logs/2021.11.01/13.34.28.082269.log
/content/.config/logs/2021.11.01/13.34.08.637862.log
/content/.config/logs/2021.11.01/13.34.55.017895.log
/content/.config/logs/2021.11.01/13.33.47.856572.log
/content/.config/logs/2021.11.01/13.34.35.080342.log
/content/.config/configurations/config_default
/content/sample_data/anscombe.json
/content/sample_data/README.md
/content/sample_data/california_housing_test.csv
/content/sample_data/mnist_train_small.csv
/content/sample_data/california_housing_train.csv
/content/sample_data/mnist_test.csvПервые два файла и есть наши данные. В скрытой подпапке /.config/ содержатся служебные файлы, а в подпапке /sample_data/ — примеры датасетов, хранящиеся в Google Colab по умолчанию.
Команда !ls
Кроме того, если нас интересуют только видимые файлы и папки, мы можем воспользоваться командой !ls (ls означает to list, т.е. «перечислить»).
sample_data test.csv train.csv
Подобным образом мы можем заглянуть внутрь папки sample_data.
! ls / content / sample_data /
anscombe.json mnist_test.csv
california_housing_test.csv mnist_train_small.csv
california_housing_train.csv README.mdТеперь прочитаем файл сначала из переменной uploaded, а затем напрямую из папки /content/.
Чтение из переменной uploaded
Как мы уже сказали выше, в словаре uploaded файл содержится в формате bytes.
# посмотрим на тип значений словаря uploaded
type ( uploaded [ ‘test.csv’ ] )Основная особенность: информация в объекте bytes представляет собой последовательность байтов (byte string), в то время как обычная строка — это последовательность символов (character string). Компьютер понимает первый тип, мы (люди) — второй.
Для того чтобы прочитать информацию из объекта bytes, ее нужно декодировать (decode). Если мы захотим вернуть ее обратно в объект bytes, соответственно, закодировать (encode).
Таким образом, чтобы прочитать данные напрямую из словаря uploaded, вначале нам нужно преобразовать эти данные в обычную строку.
# обратимся к ключу словаря uploaded и применим метод .decode()
uploaded_str = uploaded [ ‘test.csv’ ] . decode ( )
# на выходе получаем обычную строку
print ( type ( uploaded_str ) )Выведем первые 35 значений.
print ( uploaded_str [ : 35 ] )
PassengerId,Pclass,Name,Sex,Age,SibЕсли разбить строку методом .split() по символам \r (возврат к началу строки) и \n (новая строка), то на выходе мы получим список.
uploaded_list = uploaded_str . split ( ‘\r\n’ )
type ( uploaded_list )Пройдемся по этому списку и выведем первые четыре значения.
# не забудем создать индекс с помощью функции enumerate()
for i , line in enumerate ( uploaded_list ) :
# начнем выводить записи
print ( line )
# когда дойдем до четвертой строки
PassengerId,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
892,3,»Kelly, Mr. James»,male,34.5,0,0,330911,7.8292,,Q
893,3,»Wilkes, Mrs. James (Ellen Needs)»,female,47,1,0,363272,7,,S
894,2,»Myles, Mr. Thomas Francis»,male,62,0,0,240276,9.6875,,QВот нам и пригодился оператор break. Как мы видим, первая строка — это заголовок (header), остальные — информация по каждому из пассажиров.
Использование функции open() и конструкции with open()
Такого же результата можно добиться с помощью базовой функции open().
Обратите внимание, здесь мы читаем файл непосредственно из папки /content/. Декодировать файл уже не нужно.
Функция open() возвращает объект, который используется для чтения и изменения файла. Откроем файл train.csv.
# передадим функции open() адрес файла
# параметр ‘r’ означает, что мы хотим прочитать (read) файл
f1 = open ( ‘/content/train.csv’ , ‘r’ )Вначале попробуем применить метод .read().
# метод .read() помещает весь файл в одну строку
# выведем первые 142 символа (если параметр не указывать, выведется все содержимое)
print ( f1 . read ( 142 ) )
# в конце файл необходимо закрыть
PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
1,0,3,»Braund, Mr. Owen Harris»,male,22,1,0,A/5 21171,7.25,,SДля наших целей метод .read() не очень удобен. Будет лучше пройтись по файлу в цикле for.
# снова откроем файл
f2 = open ( ‘/content/train.csv’ , ‘r’ )
# пройдемся по нашему объекту в цикле for и параллельно создадим индекс
for i , line in enumerate ( f2 ) :
# выведем строки без служебных символов по краям
print ( line . strip ( ) )
# дойдя до четвертой строки, прервемся
# не забудем закрыть файл
PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
1,0,3,»Braund, Mr. Owen Harris»,male,22,1,0,A/5 21171,7.25,,S
2,1,1,»Cumings, Mrs. John Bradley (Florence Briggs Thayer)»,female,38,1,0,PC 17599,71.2833,C85,C
3,1,3,»Heikkinen, Miss. Laina»,female,26,0,0,STON/O2. 3101282,7.925,,SЕще один способ — использовать конструкцию with open(). В этом случае специально закрывать файл не нужно.
# скажем Питону: «открой файл и назови его f3»
with open ( ‘/content/test.csv’ , ‘r’ ) as f3 :
# «пройдись по строкам без служебных символов»
for i , line in enumerate ( f3 ) :
print ( line . strip ( ) )
# и «прервись на четвертой строке»
PassengerId,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
892,3,»Kelly, Mr. James»,male,34.5,0,0,330911,7.8292,,Q
893,3,»Wilkes, Mrs. James (Ellen Needs)»,female,47,1,0,363272,7,,S
894,2,»Myles, Mr. Thomas Francis»,male,62,0,0,240276,9.6875,,QЧтение через библиотеку Pandas
Вероятно наиболее удобный и подходящий для наших целей способ чтения файлов — это преобразование напрямую в датафрейм библиотеки Pandas. С этим методом в целом мы уже знакомы.
# импортируем библиотеку
import pandas as pd
# применим функцию read_csv() и посмотрим на первые три записи файла train.csv
train = pd . read_csv ( ‘/content/train.csv’ )
train . head ( 3 )# сделаем то же самое с файлом test.csv
test = pd . read_csv ( ‘/content/test.csv’ )
test . head ( 3 )Примечание. На скриншотах приведена лишь часть датафреймов, полностью их можно посмотреть в ноутбуке⧉.
Этап 3. Построение модели и прогноз
Давайте ненедолго отвлечемся от работы с файлами и построим несложную модель, которая предскажет погиб пассажир (обозначим этот факт через 0) или выжил (1). Прежде всего, концептуально обсудим, что нам нужно сделать.
Для понимания дальнейшей работы очень советую пройти или повторить первые три раздела вводного курса. На этом занятии я предполагаю, что вы с ними уже знакомы.
- Шаг 1. Обработать и проанализировать данные
- Шаг 2. Разделить обучающую выборку (train) на признаки (X_train) и целевую переменную (y_train)
- Шаг 3. Обучить модель логистической регрессии
- Шаг 4. Подготовить тестовые данные (X_test) и построить прогноз
А теперь обо всем по порядку.
Шаг 1. Обработка и анализ данных
Исследовательский анализ данных (EDA)
Напомню, что основная задача EDA — выявить взаимосвязь между признаками и целевой переменной. Воспользуемся методом .info(), чтобы обобщенно посмотреть на наши данные.
train . info ( )
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KBКак мы видим, у нас 12 переменных. Одна из них (Survived) — зависимая (целевая), остальные — независимые (признаки). Всего в датасете 891 запись, при этом в нескольких переменных есть пропуски.
Ниже приведено короткое описание каждой из переменных:
- PassengerId — id пассажира
- Survived — погиб (0) или выжил (1)
- Pclass — класс билета (первый (1), второй (2) или третий (3))
- Name — имя пассажира
- Sex — пол
- Age — возраст
- SibSp — количество братьев и сестер или супругов на борту
- Parch — количество родителей и детей на борту
- Ticket — номер билета
- Fare — стоимость билета
- Cabin — номер каюты
- Embarked — порт посадки (C — Шербур; Q — Квинстаун; S — Саутгемптон)
Проведем несложный визуальный анализ данных.
# для построения графиков воспользуемся новой для нас библиотекой seaborn
import seaborn as snsУ нас есть несколько потенциально значимых категориальных переменных, целевая переменная — тоже категориальная. В этом случае удобно использовать столбчатую диаграмму (bar chart), где каждый столбец также разбит на категории. В библиотеке seaborn такую диаграмму можно построить с помощью функции countplot().
# посмотрим насколько значим класс билета для выживания пассажира
# с помощью x и hue мы можем уместить две категориальные переменные на одном графике
sns . countplot ( x = ‘Pclass’ , hue = ‘Survived’ , data = train )Мы видим, что погибших пассажиров в третьем классе гораздо больше, чем выживших. При этом в первом классе больше выживших, чем погибших. Очевидно класс билета имеет значение.
# кто выживал чаще, мужчины или женщины?
sns . countplot ( x = ‘Sex’ , hue = ‘Survived’ , data = train )Большинство мужчик погибло. Большая часть женщин выжила. Пол также значим для построения прогноза.
Пропущенные значения
Посмотрим, что можно сделать с пропущенными значениями (missing values).
# выявим пропущенные значения с помощью .isnull() и посчитаем их количество sum()
train . isnull ( ) . sum ( )
PassengerId 0
Survived 0
Embarked 2
dtype: int64Больше всего пропущенных значений в переменной Cabin. Они также есть в переменных Age и Embarked.
# переменная Cabin (номер каюты), скорее всего, не является самой важной
# избавимся от нее с помощью метода .drop()
# (параметр axis отвечает за столбцы, inplace = True сохраняет изменения)
train . drop ( columns = ‘Cabin’ , axis = 1 , inplace = True )
# а вот Age (возраст) точно важен, заменим пустые значения средним арифметическим
train [ ‘Age’ ] . fillna ( train [ ‘Age’ ] . mean ( ) , inplace = True )В данном случае мы применили метод .fillna(), то есть «заполнить пропуски», к столбцу Age (через train [ ‘Age’ ] ) и заполнили пропуски средним значением этого же столбца через train [ ‘Age’ ] . mean ( ) .
Более подробно с преобразованием датафреймов мы познакомимся на курсе анализа и обработки данных. На данном этапе важно просто понимать логику нашей работы.
# у нас остаются две пустые строки в Embarked, удалим их
train . dropna ( inplace = True )Посмотрим на результат.
train . isnull ( ) . sum ( )
PassengerId 0
Survived 0
Embarked 0
dtype: int64Категориальные переменные
Теперь нужно поработать с категориальными переменными (categorical variable). Как мы помним, модель не сможет подобрать веса, если значения выражены словами (например, male и female в переменной Sex или C, Q, S в переменной Embarked).
Кроме того, когда категория выражена не 0 и 1, мы все равно не можем оставить ее без изменения. Например, если не трогать переменную Pclass, то модель воспримет классы 1, 2 и 3 как количественную переменную (проще говоря, число), а не как категорию.
И в первом, и во втором случае к переменным нужно применить one-hot encoding. Мы уже познакомились с этим методом, когда разбирали нейронные сети. В библиотеке Pandas есть метод .get_dummies(), который как раз и выполнит необходимые преобразования.
В статистике, dummy variable или вспомогательная переменная — это переменная, которая принимает значения 0 или 1 в зависимости от наличия определенного признака.
Применим этот метод на практике.
# применим one-hot encoding к переменной Sex (пол) с помощью метода .get_dummies()
pd . get_dummies ( train [ ‘Sex’ ] ) . head ( 3 )Первый пассажир — мужчина (в колонке male стоит 1), второй и третий — женщина. Помимо этого, если присмотреться, то станет очевидно, что мы можем обойтись только одним столбцом. В частности, в столбце male уже содержится достаточно информации о поле (если 1 — мужчина, если 0 — женщина). Это значит, что первый столбец можно удалить.
# удалим первый столбец, он избыточен
sex = pd . get_dummies ( train [ ‘Sex’ ] , drop_first = True )
sex . head ( 3 )Сделаем то же самое для переменных Pclass и Embarked.
embarked = pd . get_dummies ( train [ ‘Embarked’ ] , drop_first = True )
pclass = pd . get_dummies ( train [ ‘Pclass’ ] , drop_first = True )Еще раз замечу, что переменную Survived трогать не надо. Она уже выражена через 0 и 1.
Присоединим новые (закодированные) переменные к исходному датафрейму train. Для этого используем функцию .concat().
train = pd . concat ( [ train , pclass , sex , embarked ] , axis = 1 )
Отбор признаков
Теперь давайте отберем те переменные (feature selection), которые мы будем использовать в модели.
- В первую очередь, удалим исходные (до применения one-hot encoding) переменные Sex, Pclass и Embarked
- Кроме того, переменные PassengerId, Name и Ticket вряд ли скажут что-то определенное о шансах на выживание пассажира, удалим и их
# применим функцию drop() к соответствующим столбцам
train . drop ( [ ‘PassengerId’ , ‘Pclass’ , ‘Name’ , ‘Sex’ , ‘Ticket’ , ‘Embarked’ ] , axis = 1 , inplace = True )
train . head ( 3 )
Как вы видите, теперь все переменные либо количественные (Age, SibSp, Parch, Fare), либо категориальные и выражены через 0 и 1.
Нормализация данных
На занятиях по классификации и кластеризации мы уже говорили о важности приведения количественных переменных к одному масштабу. В противном случае модель может неоправданно придать большее значение признаку с большим масштабом.
# импортируем класс StandardScaler
from sklearn . preprocessing import StandardScaler
# создадим объект этого класса
scaler = StandardScaler ( )
# выберем те столбцы, которые мы хотим масштабировать
cols_to_scale = [ ‘Age’ , ‘Fare’ ]
# рассчитаем среднее арифметическое и СКО для масштабирования данных
scaler . fit ( train [ cols_to_scale ] )
# применим их
train [ cols_to_scale ] = scaler . transform ( train [ cols_to_scale ] )
# посмотрим на результат
train . head ( 3 )Остается небольшой технический момент. Переменные 2 и 3 (второй и третий класс) выражены числами, а не строками (их выдает отсутствие кавычек в коде ниже). Так быть не должно.
train . columns
Index([‘Survived’, ‘Age’, ‘SibSp’, ‘Parch’, ‘Fare’, 2, 3, ‘male’, ‘Q’, ‘S’], dtype=’object’)Преобразуем эти переменные в тип str через функцию map().
train . columns = train . columns . map ( str )
Шаг 2. Разделение обучающей выборки на признаки и целевую переменную
# поместим в X_train все кроме столбца Survived
X_train = train . drop ( ‘Survived’ , axis = 1 )
# столбец ‘Survived’ станет нашей целевой переменной (y_train)
y_train = train [ ‘Survived’ ]
X_train . head ( 3 )Шаг 3. Обучение модели логистической регрессии
Воспользуемся моделью логистической регрессии из библиотеки sklearn и передадим ей обучающую выборку.
# импортируем логистическую регрессию из модуля linear_model библиотеки sklearn
from sklearn . linear_model import LogisticRegression
# создадим объект этого класса и запишем его в переменную model
model = LogisticRegression ( )
# обучим нашу модель
model . fit ( X_train , y_train )
LogisticRegression()Остается сделать прогноз и оценить качество модели. При этом обратите внимание, что в тестовых данных отсутствует целевая переменная (почему это так, расскажу ниже), поэтому чтобы иметь хоть какое-то представление о качестве модели, нам необходимо вначале использовать обучающую выборку для построения прогноза.
# сделаем предсказание класса на обучающей выборке
y_pred_train = model . predict ( X_train )Теперь мы можем сравнить прогнозные значения с фактическими. Построим матрицу ошибок (confusion matrix).
# построим матрицу ошибок
from sklearn . metrics import confusion _ matrix
# передадим ей фактические и прогнозные значения
conf_matrix = confusion_matrix ( y_train , y_pred_train )
# преобразуем в датафрейм
conf_matrix_df = pd . DataFrame ( conf_matrix )
conf_matrix_dfДля удобства интерпретации добавим подписи.
conf_matrix_labels = pd . DataFrame ( conf_matrix , columns = [ ‘Прогноз погиб’ , ‘Прогноз выжил’ ] , index = [ ‘Факт погиб’ , ‘Факт выжил’ ] )
conf_matrix_labels
Также давайте посмотрим на метрику accuracy. Она показывает долю правильно предсказанных значений. То есть мы берем тех, кого верно предсказали как погибших (true negative, TN, таких было 478), и тех, кого верно предсказали как выживших (true positive, TP, 237), и делим на общее число прогнозов.
# рассчитаем метрику accuracy вручную
round ( ( 478 + 237 ) / ( 478 + 237 + 71 + 103 ) , 3 )
# импортируем метрику accuracy из sklearn
from sklearn . metrics import accuracy _ score
# так же передадим ей фактические и прогнозные значения
model_accuracy = accuracy_score ( y_train , y_pred_train )
# округлим до трех знаков после запятой
round ( model_accuracy , 3 )На обучающей выборке наша модель показала результат в 80,4%. При этом только на тестовой выборке мы можем объективно оценить качество нашего алгоритма.
Шаг 4. Построение прогноза на тестовых данных
Посмотрим на тестовые данные.
test . info ( )
RangeIndex: 418 entries, 0 to 417
Data columns (total 11 columns):
# Column Non-Null Count Dtype
0 PassengerId 418 non-null int64
1 Pclass 418 non-null int64
2 Name 418 non-null object
3 Sex 418 non-null object
4 Age 332 non-null float64
5 SibSp 418 non-null int64
6 Parch 418 non-null int64
7 Ticket 418 non-null object
8 Fare 417 non-null float64
9 Cabin 91 non-null object
10 Embarked 418 non-null object
dtypes: float64(2), int64(4), object(5)
memory usage: 36.0+ KBВзглянув на сводку по тестовым данным, становится заметна одна сложность. Мы обучили модель на обработанных данных. В частности, мы заполнили пропуски, закодировали категориальные переменные и убрали лишние признаки. Кроме того, мы масштабировали количественные переменные и превратили названия столбцов в строки.
Для того чтобы наша модель смогла работать с тестовой выборкой нам нужно таким же образом обработать и эти данные.
При этом обратите внимание, мы не нарушаем принципа разделения данных, поскольку меняем тестовую выборку так же, как мы меняли обучающую.
# для начала дадим датасету привычное название X_test
X_test = test
# заполним пропуски в переменных Age и Fare средним арифметическим
X_test [ ‘Age’ ] . fillna ( test [ ‘Age’ ] . mean ( ) , inplace = True )
X_test [ ‘Fare’ ] . fillna ( test [ ‘Fare’ ] . mean ( ) , inplace = True )
# выполним one-hot encoding категориальных переменных
sex = pd . get_dummies ( X_test [ ‘Sex’ ] , drop_first = True )
embarked = pd . get_dummies ( X_test [ ‘Embarked’ ] , drop_first = True )
pclass = pd . get_dummies ( X_test [ ‘Pclass’ ] , drop_first = True )
# присоединим новые столбцы к исходному датафрейму
X_test = pd . concat ( [ test , pclass , sex , embarked ] , axis = 1 )
# и удалим данные, которые теперь не нужныX_test . drop ( [ ‘PassengerId’ , ‘Pclass’ , ‘Name’ , ‘Sex’ , ‘Cabin’ , ‘Ticket’ , ‘Embarked’ ] , axis = 1 , inplace = True )
# посмотрим на результат
X_test . head ( 3 )Теперь нужно масштабировать количественные переменные. Для этого мы будем использовать те параметры (среднее арифметическое и СКО), которые мы получили при обработке обучающей выборки. Так мы сохраним единообразие изменений и избежим утечки данных (data leakage).
# применим среднее арифметическое и СКО обучающей выборки для масштабирования тестовых данных
X_test [ cols_to_scale ] = scaler . transform ( X_test [ cols_to_scale ] )
X_test . head ( 3 )Остается превратить название столбцов в строки.
X_test . columns = X_test . columns . map ( str )
И сделать прогноз на тестовой выборке.
y_pred_test = model . predict ( X_test )
На выходе мы получаем массив с прогнозами.
# посмотрим на первые 10 прогнозных значений
y_pred_test [ : 10 ]
array([0, 0, 0, 0, 1, 0, 1, 0, 1, 0])Этап 4. Сохранение результата в новом файле на сервере
Теперь, когда прогноз готов, мы можем сформировать новый файл, назовем его result.csv, в котором будет содержаться id пассажира и результат, погиб или нет. Приведу пример того, что мы хотим получить.
# файл с примером можно загрузить не с локального компьютера, а из Интернета
url = ‘https://www.dmitrymakarov.ru/wp-content/uploads/2021/11/titanic_example.csv’
# просто поместим его url в функцию read_csv()
example = pd . read_csv ( url )
example . head ( 3 )Перед созданием нужного нам файла (1) соберем данные в новый датафрейм.
# возьмем индекс пассажиров из столбца PassengerId тестовой выборки
ids = test [ ‘PassengerId’ ]
# создадим датафрейм из словаря, в котором
# первая пара ключа и значения — это id пассажира, вторая — прогноз «на тесте»
result = pd . DataFrame ( < 'PassengerId' : ids , 'Survived' : y_pred_test >)
# посмотрим, что получилось
result . head ( )И (2) создадим новый файл.
# создадим новый файл result.csv с помощью функции to_csv(), удалив при этом индекс
result . to_csv ( ‘result.csv’ , index = False )
# файл будет сохранен в ‘Сессионном хранилище’ и, если все пройдет успешно, выведем следующий текст:
print ( ‘Файл успешно сохранился в сессионное хранилище!’ )
Файл успешно сохранился в сессионное хранилище!Новый файл появится в «Сессионном хранилище».
Этап 5. Скачивание обратно на жесткий диск
После этого мы можем скачать файл на жесткий диск.
# применим метод .download() объекта files
files . download ( ‘/content/result.csv’ )Вот что у нас получилось.
Про соревнования на Kaggle
Вы вероятно заметили, что мы так и не узнали насколько хорош наш алгоритм на тестовой выборке. У нас просто нет тестовой целевой переменной (y_test).
Дело в том, что эти данные взяты с платформы, которая называется Kaggle⧉.
На этой платформе проводятся соревнования по машинному обучению. Участники получают данные, строят модели и затем подгружают свой результат. Kaggle его оценивает и тот или те, чья модель наиболее точна — выигрывают.
Соревнование «Титаник»
«Титаник» — одно из стартовых соревнований Kaggle для новичков. Предлагаю прямо сейчас в нем поучавствовать. На странице соревнования⧉, после того как вы зарегистрировались на сайте и присоединились к самому соревнованию, у вас появится возможность подгрузить файл с результатом.
Для этого зайдите на вкладку Submit Predictions⧉, (1) подгрузите файл result.csv с локального компьютера и (2) нажмите кнопку Make Submission.
Платформа сама рассчитает accuracy вашего прогноза «на тесте» (Score). В нашем случае accuracy составляет 0,77033 или 77,03%. Чуть хуже, чем показатель «на трейне» (напомню, там было 80,4%).
Нажав на Jump to your position on the leaderboard, система сообщит вам ваше место в рейтинге участников (лидерборде).
Мы с вами оказались на 9512 месте из примерно 14500 участников. Для первого раза это хороший результат.
Подведем итог
Первая часть занятия была посвящена работе с внешними файлами. Мы научились:
- Подгружать внешний файл в сессионное хранилище
- Читать этот файл внутри ноутбука
- Обучать модель «на трейне» и делать прогноз на тестовых данных
- Подгружать прогноз в сессионное хранилище
- Скачивать его на жесткий диск
Во второй части мы приняли участие в соревновании «Титаник» на платформе Kaggle. Подгрузив прогноз, платформа сообщила нам accuracy нашей модели «на тесте» и наше место в лидерборде.
Вопросы для закрепления
Как вы считаете, что предпочтительнее использовать, функцию open() или конструкцию with open()?
Посмотреть правильный ответ
Ответ: конструкция with open() является более предпочтительной, в частности, потому что после отработки блока with Питон сам закрывает файл.
Какие данные мы подгрузили на платформу Kaggle?
Посмотреть правильный ответ
Ответ: мы подгрузили прогноз на тестовой выборке (y_pred_test). Платформа сравнила прогноз с фактическими данными y_test (то есть целевой переменной), которых у нас изначально не было, и рассчитала accuracy. На основе этой метрики нам было присвоено место в рейтинге участников.
В следующий раз мы подробнее изучим возможности Питона по работе с датой и временем.
Data Science, доступный каждому: работаем с данными в облаке Google Colab
Арендуем лабораторию без регистрации и SMS — потребуются только браузер и адрес Gmail.
Цокто Жигмытов
Кандидат философских наук, специалист по математическому моделированию. Пишет про Data Science, AI и программирование на Python.
Чтобы обрабатывать и визуализировать данные, не обязательно устанавливать специальные программы и тратить время на их настройку. Можно совершенно бесплатно взять в аренду у Google виртуальный компьютер и решать ваши задачи Data Science в облаке. Рассказываем, как это сделать.
Anaconda и Jupyter Notebook
Дата-сайентисты чаще всего работают с так называемым Jupyter Notebook — инструментом, который позволяет запускать и отлаживать ваши алгоритмы небольшими фрагментами. Это хорошо для работы с данными: запустил фрагмент кода в ячейке — посмотрел результат — изменил код — снова запустил и так далее.
Один из популярных дистрибутивов, в составе которого есть Jupyter Notebook, — Anaconda. Кроме собственно Jupyter, на ваш компьютер будут установлены языки Python и R, а также более 250 различных программ и библиотек для исследования данных и разработки моделей машинного обучения.
Такое изобилие нужно не всегда, особенно начинающим, да и не всегда можно установить всё локально. Для тех, кому это неудобно, есть специальные онлайн-сервисы, один из которых — Google Colaboratory (сокращённо Colab).
Как начать работать с Colab
Сервис абсолютно бесплатен — для работы понадобится только почтовый адрес Gmail. На своей странице Gmail зайдите в меню приложений: решётка возле вашей аватарки справа вверху. Найдите и кликните «Диск», далее «Создать», а затем в открывшемся меню — «Ещё».
Если кликнуть на «Подключить другие приложения», откроется окно с выбором приложений для установки на Диск.
Через строку поиска найдите приложение Colaboratory и добавьте к себе на Диск, нажав значок с плюсиком справа внизу под логотипом.
После этого создайте на своём Диске папку — например, Data_Science, а уже в ней ноутбук колаба: Диск — Создать — Ещё — Google Colaboratory.
Вот как он выглядит:
Вашему колаб-ноутбуку нужен сервер для вычислений. Чтобы соединиться с ним, нажмите в меню кнопку «Подключиться» и выберите «Подключиться к удалённой среде выполнения». Google несколько секунд подумает и выдаст вам в пользование виртуальный компьютер.
Существуют и другие подобные сервисы: IBM Cloud, Kaggle, AWS от Amazon, а также отечественные платформы от Яндекса и Mail.Ru Group. Они более специализированы и, как правило, сложнее в освоении.
Как ввести и запустить код
В ячейках Colab можно запускать код на языке Python:
Новые ячейки добавляются кнопкой «+ Код». Теперь вся мощь Python к вашим услугам — без установки интерпретатора и настройки окружения.
Как добавить текст
Кроме кода, в проектах часто необходим сопровождающий текст: введение, оглавление, комментарии к модулям, заголовки смысловых частей. Для этого есть второй тип ячеек — текстовые.
Нажмите на кнопку добавления текстовой ячейки «+ Текст» слева вверху. Появится ячейка, разделённая на две половины: слева поле редактора, где вы правите текст, а справа предпросмотр того, что получается.
В текстовых ячейках поддерживается популярный язык разметки Markdown. Например, заголовок в нём выделяется с помощью символов # и пробела, как видно на картинке. Здесь можно посмотреть подробную шпаргалку на русском языке.
Как работать с файлами
Данные, которые нужно обработать, загружаются в ноутбуки Colab в виде файлов самых разных форматов: текстовые, табличные и даже картинки. Скачаем, например, этот текстовый файл себе на компьютер и выгрузим его в раздел «Файлы» (пиктограмма папки слева) с помощью кнопки «Выбрать файл». Среда предупредит нас, что после перезапуска файл исчезнет.
Добавим ячейку кода с помощью кнопки «+ Код» и введём туда:
Для считывания файлов других форматов (Excel, CSV и так далее) и работы с ними используются дополнительные библиотеки, например Pandas. Большинство нужных библиотек уже предустановлены в Colab и загружаются в ноутбук стандартной командой import.
Как поделиться готовым кодом с коллегами
Ноутбук можно расшарить с помощью кнопки «Поделиться» справа вверху. В появившемся окне выберите «Скопировать ссылку» и пришлите её, например, вашему коллеге.
Имейте в виду, что делитесь вы только кодом в ноутбуке, а не файлами из раздела «Файлы» в боковой панели. Ведь у адресата будет уже свой виртуальный компьютер и эти файлы ему нужно получать и загружать отдельно. Иначе при запуске ячеек Python выдаст ошибку «Нет такого файла или папки»:
Что дальше
Облачная Google Colaboratory — пожалуй, наиболее дружелюбная к новичкам среда разработки. Виртуальный компьютер, который Google выдаёт пользователю, не слишком мощный по меркам современного Machine Learning и особенно Deep Learning. Зато он доступен всем и каждому.
Хотите большего? На наших бесплатных интенсивах и на курсе «Профессия Data Scientist» под руководством опытных наставников вы освоите не только Colab, но и множество других необходимых дата-сайентисту инструментов.
Читайте также:
- Что такое Data Science и кто такой Data Scientist
- «Я боялась рутинных задач, но в Data Science всё иначе»
- «Я удивился, когда написал код, а он заработал»: как живёт начинающий Python-разработчик
Произносится «джУпитер». Название Jupyter происходит от языков программирования Julia, Python и R.