Эта часть является началом Data Science с использованием EDA для очистки и структурирования видимости набора данных с последующей визуализацией и проверкой гипотез.

Перед тем как погрузиться в подробности, оставьте несколько заявлений об отказе от ответственности:

1. Этот проект входит в серию проектов, созданных и разработанных с целью улучшения моих навыков в области Data Science в долгосрочной перспективе, как технических, так и аналитических.
2. Однако я не имею формального образования и не имею более высокой степени. в науке о данных. Это все для самообучения, начиная от онлайн-курсов, среднего чтения и заканчивая повседневной практикой.

Поэтому мы очень ценим ваши отзывы!

Таблица содержания

Давайте начнем! Это сквозной проект, разделенный на 3 части и включающий следующие разделы:

  1. Часть 1: пояснительный анализ данных (EDA) и визуализация данных (бонус: проверка гипотез)
  2. Часть 2: Машинное обучение с 4 моделями регрессии
  3. Часть 3: Машинное обучение (продолжение) с ARIMA

В начале эта статья будет охватывать первую часть проекта, так что следите за двумя другими в ближайшие дни! Если вы хотите увидеть весь репозиторий, прокрутите вниз, чтобы увидеть мою ссылку на Github;)

Введение

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

A. Анализ пояснительных данных (EDA)

Во-первых, давайте импортируем две фундаментальные библиотеки Python, Pandas и Numpy, и прочитаем данные:

import pandas as pd
import numpy as np
df = pd.read_csv("Foreign_Exchange_Rates.csv")

Чтобы вкратце разобраться в нашем наборе данных, используйте df.head () для просмотра первых 5 строк, df.columns для просмотра переменных:

df.head()
print(df.columns)

На первый взгляд, я вижу необычную переменную «Безымянный: 0», которую следует удалить.

df = df.drop(columns=df.columns[0])

Далее, названия столбцов кажутся слишком запутанными и их трудно назвать позже, поэтому я стандартизирую их как «Валюта страны / доллар США» (например, AUD / USD).

new_col_names = ['Time Series', 'aud', 'eur', 'nzd', 'gbp', 'brl', 'cnd', 'cny', 'hkd', 'idr', 'krw', 'mxn', 'zar', 'sgd', 'dkk', 'jpy', 'myr', 'nok', 'sek', 'lkr', 'chf', 'twd', 'thb']
df.columns = new_col_names
df.columns = map(str.upper, df.columns)
df.rename(columns=lambda x:x+'_USD', inplace=True)
df.rename(columns={'TIME SERIES_USD':'Time Series'}, inplace=True)

Как видите, я создал новый список с новыми кодами валют страны, перевел их с заглавной буквы и добавил «_USD» к имени каждого столбца. Итак, свежий набор данных, на который стоит взглянуть!

Просматривая весь набор данных еще раз, есть несколько необычных значений с названием «ND». Поэтому я заменил их значениями «NaN» на np.nan, а затем отбросил все значения «NaN» за один раз. Если значение «NaN» не найдено с помощью df.isna (). Sum (), все готово!

df = df.replace('ND', np.nan)
df = df.dropna().reset_index(drop=True)
df.isna().sum()

Б. Визуализация данных

Давайте посмотрим на набор данных в более наглядном формате!

Во-первых, нам нужно убедиться, что значения являются числовыми, а не объектами, вызывая df.dtypes и pd.to_numeric для преобразования типа.

df.dtypes
for col in df.columns[1:]:
    df[col] = pd.to_numeric(df[col], errors='coerce')

Используйте цикл for, чтобы применить изменение сразу ко всем столбцам, а не повторять процесс заново. Параметр Errors в функции может иметь значение «ignore» (возвращать недопустимые значения как есть) или «coerce» (возвращать недопустимые значения как NaN).

Поскольку в настоящее время формат даты - ГГГГ-ММ-ДД, который относительно упакован, когда дело доходит до диаграмм, я добавлю еще один столбец, отформатированный как ГГГГ-ММ, и использую его вместо него.

df['Time Series'] = pd.to_datetime(df['Time Series'])
df['month'] = df['Time Series'].dt.month
df['year'] = df['Time Series'].dt.year
df['month_year'] = df['Time Series'].dt.to_period('M')

pd.to_datetime для преобразования значений из объекта в datetime, затем мы извлекаем месяц и год с помощью .dt.month и .dt.year. . Наконец, мы создали новый столбец под названием месяц_год, используя .dt.to_period (M). Вы можете обратиться к этой документации для получения более подробной информации.

Давайте сначала визуализируем обменный курс AUD / USD для простоты.

df['AUD_USD'].count()

Используя .count (), мы знаем, что для каждого столбца существует 5k + значений. Это огромное количество! Поэтому вместо этого мы возьмем среднюю скорость каждого месяца, предполагая, что среднее значение представляет собой весь месяц. Groupby спешит на помощь!

df_groupby_aud = df.groupby('month_year').AUD_USD.mean().reset_index()

Давайте импортируем библиотеку Matplotlib для нашей первой визуальной диаграммы!

from matplotlib import pyplot as plt
x = df_groupby_aud['month_year'].astype(str)
y = df_groupby_aud['AUD_USD']
plt.figure(figsize=(8,4))
plt.plot(x, y)
plt.title("Exchange Rate: AUD/USD")
plt.xlabel("Month")
plt.ylabel("Exchange Rate")
plt.show()

Хорошо, теперь мы можем видеть модель для AUD / USD. Давайте добавим в нашу диаграмму более одного обменного курса.

groupby_all = df.groupby('month_year').apply(lambda x: pd.Series
           ({
              'AUD_mean': x['AUD_USD'].mean(),
              'EUR_mean': x['EUR_USD'].mean(),
              'NZD_mean': x['NZD_USD'].mean(),
              'SGD_mean': x['SGD_USD'].mean(),
              'GBP_mean': x['GBP_USD'].mean(),
              'JPY_mean': x['JPY_USD'].mean(),
              'CHF_mean': x['CHF_USD'].mean()
                                             })).reset_index()
groupby_all = pd.DataFrame(groupby_all)
groupby_all['USD_mean'] = [1 for i in range(240)]
groupby_all.head()

Чтобы выполнить группировку для нескольких столбцов, мы используем лямбда для применения функции к серии столбцов (в данном случае .mean ()), а затем конвертируем обратно в DataFrame для упрощения использования.

Причина, по которой я создал столбец USD_mean и добавил значение 1, состоит в том, чтобы визуально проиллюстрировать разницу всех обменных курсов по сравнению с базовым уровнем. Понимание списка - самый простой способ создать такой список.

y_all = groupby_all[['AUD_mean', 'EUR_mean', 'NZD_mean', 'SGD_mean', 'GBP_mean', 'CHF_mean','USD_mean']]
labels = ["AUD_mean", "EUR_mean", "NZD_mean", "SGD_mean", "GBP_mean", "CHF_mean", "USD_mean"]
x_ticks = list(range(1, 240, 12))
x_ticklabels = [x for x in range(2000, 2021)]
plt.figure(figsize=(20,10))
ax = plt.subplot()
plt.plot(x, y_all)
ax.set_xticks(x_ticks)
ax.set_xticklabels(x_ticklabels)
plt.legend(labels)
plt.title("Exchange Rate: Top Countries/USD")
plt.xlabel("Year")
plt.ylabel("Exchange Rate")
plt.show()

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

Помимо Matplotlib, существует несколько других библиотек для визуализации, таких как Plotly или Bokeh, которые предоставляют больше возможностей для взаимодействия. Если вам интересно, посмотрите мой Github в конце, чтобы увидеть полный код. Вот краткая диаграмма с использованием боке:

C. Проверка гипотез

Честно говоря, я все еще борюсь с множеством различных элементов, теорий и функций, стоящих за проверкой гипотез.

Вот почему я решил немного попрактиковаться в этом проекте, задав себе вопрос, эти переменные в наборе данных отличаются друг от друга или нет.

Давайте использовать для этого примера AUD_mean и SGD_mean. Причина, по которой я использовал эти две переменные, заключается в том, что я вижу относительную разницу в диаграмме выше. Итак, этот тест предназначен для подтверждения или опровержения моего предположения.

H0 (нулевая гипотеза): среднее значение AUD такое же, как и SGD.
H1 (альтернативная гипотеза): среднее значение AUD значительно отличается от что из SGD.

Однако перед тем, как проводить проверку гипотез, нам необходимо знать о некоторых предпосылках и процессе:

  1. Возьмите образец набора данных из каждой генеральной совокупности.
  2. Проверьте нормальность каждого набора образцов и корреляцию двух
  3. Выберите правильный тест гипотезы для использования

Для 1. задачи возникает вопрос: «Сколько данных мы должны извлечь из каждой популяции?». Если вы помните, у нас есть более 5k + значений (совокупность) каждой переменной. Чтобы определить размер образца, мы можем полагаться на Анализ мощности.

Но сначала давайте подготовим наборы данных для этого раздела:

aud_sgd = df.loc[:,['AUD_USD', 'SGD_USD']]
aud = np.array(aud_sgd.iloc[:,0])
sgd = np.array(aud_sgd.iloc[:,1])

Затем мы импортируем библиотеку statsmodels для проведения анализа мощности:

import statsmodels.stats.power as sms
n = sms.TTestPower().solve_power(effect_size=0.3, power=0.9, alpha=0.05)
print(n)

Для получения полной информации обратитесь к этой документации здесь. Короче говоря, TTestPower - это статистический расчет мощности для парного выборочного t-критерия. Мы знаем, что эти переменные являются парными (или в некоторой степени связаны), поскольку они делятся на обменный курс доллара США. .solve_power () - это функция, которая включает в себя 3 основных параметра: размер эффекта, мощность и альфа (также известный как уровень значимости):

  1. Размер эффекта: в терминологии непрофессионала он относится к разнице между двумя группами (например, средняя разница двух групп), деленная на стандартное отклонение одной из групп. В случае, если данных для расчета недостаточно, мы можем использовать размер эффекта из диапазона от 0,3 до 0,8 при последующем тестировании нормальности, чтобы найти наилучший размер эффекта.
  2. Мощность: вероятность того, что мы отвергнем нулевую гипотезу, когда должны. Принято считать, что мощность должна составлять 0,8 или 0,9, в зависимости от того, насколько велик ваш шанс найти значительную разницу.
  3. Альфа - это допустимая частота ошибок, часто принимаемая равной 0,05 или 0,01. Короче говоря, альфа 0f 0,05 означает, что мы готовы согласиться с тем, что существует 5% -ная вероятность того, что наши результаты являются результатом случайности / случайности.

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

После выполнения анализа мощности мы обнаружили, что размер выборки для каждой переменной равен 118. Затем мы используем это число для случайного создания набора выборок из каждой генеральной совокупности:

aud_sample = np.random.choice(aud, size=118)
sgd_sample = np.random.choice(sgd, size=118)

Шаг 1 готов!

Переходим к шагу 2, нам нужно проверить нормальность каждого набора образцов и их корреляцию. Вкратце, требуется, чтобы два набора образцов были нормально распределены и не коррелировали друг с другом.

from scipy.stats import shapiro, pearsonr
stat, p1 = shapiro(aud_sample)
stat, p2 = shapiro(sgd_sample)
print(p1)
print(p2)
stat, p3 = pearsonr(aud_sample, sgd_sample)
print(p3)

Подробнее о H0 и H1 каждого теста см. В этой быстрой шпаргалке.

Вернемся к нашему примеру, если мы используем размер эффекта 0,3, результат будет «не нормально распределен». Когда я увеличил размер эффекта и, наконец, достиг 0,8 (размер выборки 18), наборы выборок обычно распределяются для использования для проверки гипотез. Для теста Пирсона они независимы друг от друга.

from scipy.stats import ttest_ind
tstat, pval = ttest_ind(aud_sample, sgd_sample)
print(pval)

Наконец, давайте импортируем scipy-библиотеку для проверки гипотез. Ответ, который мы ищем, заключается в том, равны ли средние значения наборов выборок AUD и SGD. Если pval

Однако оказалось, что мое предположение из диаграммы о том, что их средние различаются, было отвергнуто, так как pval ›0,05!

Ну вот и завершаем первую часть этого проекта! Фух, действительно долгое чтение ?!

Надеюсь, вам понравилась моя первая статья о Medium, и вы можете оставлять комментарии здесь или на моем Github! Обратите внимание на следующие две части в отношении машинного обучения, чтобы узнать, как я рассчитал прогнозируемые обменные курсы на 2020 год!

Давайте подключимся!

Github: https://github.com/andrewnguyen07
LinkedIn: www.linkedin.com/in/andrewnguyen07

Спасибо!