В этой статье я собираюсь проанализировать объем торговли криптовалютой (Биткойн и Эфириум) с помощью Python и сравнить каждый объем торговли каждой монетой соответственно с 2017 года, поскольку в наборе данных собраны данные о биткойнах с 2014 года и Эфириуме с 2017 года.

1. Набор данных

Цены на биткойны и эфириум (с начала до 2023 года) | Kaggle

Я использовал набор данных из Kaggle, как указано выше, и файлы данных состоят из «цены на биткойн.csv» и «цены на эфириум.csv» в формате csv (Excel). Каждый набор данных имеет значения Open, High, Low, Close Adj Close (цена закрытия с поправкой на рынок) и объем. В этом случае «Объем» в качестве последнего столбца будет нашей целевой переменной.

2. Импортировать библиотеку (пакеты)

  • numpy используется для математических функций массива в python и panda используется для структуры данных, такой как «Dataframe».
  • seaborn и matplotlib, используемые для визуализации данных
  • последние 3 библиотеки для разделения набора данных, обучения модели как линейной регрессии и оценки r2 как измерения прогноза из «sklearn»
import numpy as np
import pandas as pd

import seaborn as sn
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score

3. Исследуйте набор данных

  • Загрузить набор данных с помощью панды

Я импортирую 2 набора данных и сохраню их как Bdata для цен на биткойны и Edata для Ethereum.

Bdata = pd.read_csv('Bitcoin prices.csv')
Edata = pd.read_csv('Ethereum prices.csv')
  • Исследуйте данные с помощью head() и describe() и shape()
Bdata.head()
Bdata.describe()
Edata.head()
Edata.describe()

Bdata.shape
# (3125, 7)
Edata.shape
# (1978, 7)

4. Визуализируйте данные

  • Используйте гистограммы из библиотеки matplotlib. непрозрачность полос
    - ширина линии: установите ширину краев или границ б
Bdata.hist(bins=20, figsize=(25,20), color='green', 
           alpha=0.7, edgecolor='black', linewidth=1.2)
Edata.hist(bins=20, figsize=(25,20), color='blue', 
           alpha=0.8, edgecolor='black', linewidth=1.2)

Построив гистограммы, мы можем получить следующую информацию:

  • 5 столбцов (Open, High, Low, Clos, Adj Close), которые являются нашими переменными признаков, имеют сходство, и 1 столбец (объем, который является нашей целью) также имеет сходство.
  • По сравнению с объемом Edata, объем Bdata имеет чрезвычайно сильно наклоненное первое значение диапазона больше, чем объем Edata, который показывает менее экстремальное распределение.

5. Корреляционная матрица

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

Bcorr_matrix = Bdata.corr(method='pearson')
Bcorr_matrix
Ecorr_matrix = Edata.corr(method='pearson')
Ecorr_matrix

  • Коэффициент корреляции 0,53 указывает на умеренную положительную корреляцию между двумя переменными. Диапазон коэффициентов корреляции находится в диапазоне от -1 до 1, где -1 указывает на полную отрицательную корреляцию, 0 указывает на отсутствие корреляции и 1 указывает на полную положительную корреляцию.
  • Как правило, коэффициент корреляции между -0,3 и 0,3 считается слабой корреляцией, коэффициент корреляции между -0,5 и -0,3 или между 0,3 и 0,5 считается умеренной корреляцией, а коэффициент корреляции между -1 и -0,5 или между 0,5 и 1 считается сильной корреляцией. Однако интерпретация силы корреляции также может зависеть от контекста и конкретной области исследования.

С помощью библиотеки «seaborn» мы можем визуализировать корреляционные матрицы, как показано ниже.

sn.heatmap(Bcorr_matrix)

С помощью настраиваемых параметров мы можем визуализировать матрицу более интуитивно и удобно для пользователя.

# Customize the heatmap
sn.set(font_scale=1.2)
sn.heatmap(Bcorr_matrix, cmap='Greens', annot=True, linewidths=.5, linecolor='gray')

# Display the plot
plt.show()

6. Предварительная обработка данных

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

# Copy the datasets and store them into Bdata_copy and Edata_copy

Bdata_copy = Bdata
Edata_copty = Edata

(1) Проверка нуля: isnull() и sum()

Если мы не поместим sum() в конце, программа отобразит таблицу с проверкой, является ли каждое значение нулевым или не состоящим из ИСТИНА или ЛОЖЬ (логический тип). Просто для проверки количества нулевых значений рекомендуется использовать sum().

Bdata_copy.isnull().sum()
Edata_copy.isnull().sum()

(2) Проверить дубликаты: дублируется() и сумма()

Bdata_copy.duplicated().sum()
# Output : 0
Edata_copy.duplicated().sum()
# Output : 0

К счастью, в наших наборах данных нет повторяющихся строк. Однако, если мы обнаружим повторяющиеся данные, мы можем просто удалить повторяющиеся данные для более точного анализа данных. В параметре «inplace = True» будут манипулировать или изменяться наборы данных, и именно по этой причине необходимо копирование наборов данных для предварительной обработки данных.

Bdata_copy.drop_duplicates(inplace=True)

(3) Проверка типа данных: dtypes

Используя «dtypes», мы можем исследовать, какой тип данных состоит из набора данных. С нашим набором данных мы видим, что все функции, кроме «Дата» и цели, являются числовыми значениями.

Bdata.dtypes

В этом случае предпочтительно преобразовать объект или категориальные значения (обычно строкового типа) в числовые значения, чтобы использовать функцию для обучения и тестирования модели в конце.

(4) При необходимости преобразовать категориальный тип данных (объект) в числовой тип

Существуют различные способы преобразования категориальных значений в числовые значения, как показано ниже:

  • Кодировка метки. Назначьте уникальную числовую метку каждой уникальной категории в категориальной переменной. Это подходит, когда категории имеют неотъемлемую порядковую связь.
    ›› from sklearn.preprocessing import LabelEncoder
  • Горячее кодирование: создает двоичные столбцы для каждой категории и присваивает 1 или 0, чтобы указать наличие или отсутствие категории в каждой строке. Это подходит, когда категории именные (без порядкового отношения).
    ›› импортировать pandas как pd
  • Преобразование типа данных в подходящий тип и создание нового столбца. В нашем наборе данных у нас есть столбец «Дата» в качестве объекта, что означает, что данные определены как строковый формат. Следовательно, я извлек столбец «Дата» в формате «datetime» и создал новый столбец, объединяющий год и месяц, отбрасывая значение даты.
# Convert the 'Date' column to the datetime data type:
Bdata['Date'] = pd.to_datetime(Bdata['Date'])

# Extract the year and month from the 'Date' column:
Bdata['Year'] = Bdata['Date'].dt.year
Bdata['Month'] = Bdata['Date'].dt.month

# Create a new column combining the year and month into the 'YYYYMM' format:
Bdata['YearMonth'] = Bdata['Year'] * 100 + Bdata['Month']

# Optionally, if you want to convert the 'YearMonth' column to an integer data type:
Bdata['YearMonth'] = Bdata['YearMonth'].astype(int)

# Overwrite 'Date' column into the created 'YearMonth'
Bdata_copy['Date'] = Bdata_copy['YearMonth']

# Drop unnecessary columns
Bdata_copy = Bdata_copy.drop(['Year', 'Month', 'YearMonth'], axis = 1)

После преобразования столбца «Дата» в целое число теперь мы можем видеть, что тип данных столбца «Дата» — int32 (целое число) и организован в формате «Год + месяц», как в таблице выше.

7. Переменная функции разделения и целевая переменная

Так как мы уже закончили предварительную обработку данных, давайте подготовим данные, которые будут использоваться для обучения и тестирования. Обычно «X» обозначает функции (независимые переменные), а «y» — целевую переменную. В этом случае объем будет y, а от Date до Adj Close будет X.

# Independent variables
X_Bitcoin = Bdata_copy.iloc[:,:-1]

# Dependent variable (Target column)
y_Bitcoin = Bdata_copy.iloc[:,-1]

Метод «iloc» от pandas позволяет вам получать доступ к данным, используя индексацию на основе целых чисел вместо индексации на основе меток. Он принимает целые аргументы или срезы, чтобы указать позиции строк и столбцов, которые вы хотите выбрать.

В приведенном выше коде X_Bitcoin определяется как все строки из Bdata_copy в качестве индексатора строк и все столбцы, кроме последнего столбца (, : -1 ), в качестве индексатора столбцов.

# Selecting rows and columns using iloc
df.iloc[row_indexer, column_indexer]

8. Набор данных для обучения и тестирования

из sklearn.model_selection импорта train_test_split

С внутренней библиотекой sklearn мы можем разделить данные для обучения и тестирования набора данных. Размер теста будет 0,3 , что означает, что набор данных для обучения будет составлять 70% набора данных, а набор данных для тестирования будет составлять 30% набора данных.

BX_train, BX_test, By_train, By_test = train_test_split(
X_Bitcoin, y_Bitcoin, test_size = 0.3)

EX_train, EX_test, Ey_train, Ey_test = train_test_split(
X_Ethereum, y_Ethereum, test_size = 0.3)

9. Обучайте модель и прогнозируйте результат

Линейная регрессия

https://medium.com/@mikyung.jin.94/linear-regression-and-logistic-regression-what-is- Different-3f1d60c64b11

Линейная регрессия используется для прогнозирования непрерывных значений, установления линейной зависимости между входными признаками (независимыми переменными) и целевым значением числового типа (зависимой переменной).

(1) Создать объект линейной регрессии
(2) Сопоставить модель с данными
(3) Прогнозировать данные тестирования с помощью модели
(4) Оценить производительность модели

# Create a linear regression object
Bmodel = LinearRegression()

# Fit the model to the data
Bmodel.fit(BX_train, By_train)

# Predict the data with model
B_prediction = Bmodel.predict(BX_test)
print('Predicted y for Bitcoin:', B_prediction)

# Calculate R2 score
E_r2 = r2_score(Ey_test, E_prediction)
print('R2 Score for Bitcoin:', E_r2)

10. Визуализируйте результат предсказания

Построив график с точечной диаграммой и линейным графиком, я собираюсь сравнить фактическое целевое значение и прогнозируемое целевое значение. В идеале, если разбросанные точки точно перекрываются с диагональной линией, это означает, что предсказание с помощью предопределенной модели является точным. Этот процесс печати требует импорта и использования matplotlib.

# Scatter plot
plt.scatter(By_test, B_prediction, color='blue', label='Predicted vs Actual')

# Add labels and title
plt.xlabel('Actual Values')
plt.ylabel('Predicted Values')
plt.title('Comparison of Predicted and Actual Values')

# Add a diagonal line for reference
plt.plot([By_test.min(), By_test.max()], [By_test.min(), By_test.max()], color='red', linestyle='--', label='Ideal')

# Add legend
plt.legend()

# Show the plot
plt.show()

# Calculate the minimum and maximum target values
min_target = By_test.min()
max_target = By_test.max()


print("Min Target:", min_target)
print("Max Target:", max_target)

# Output
# Min Target: 7845880
# Max Target: 126358098747

С помощью функций numpy min() и max() мы можем найти наименьший и наибольший объем торговли биткойнами, как указано выше. Кроме того, мы можем найти строки с min_target и max_target, чтобы определить, когда был наименьший и наибольший объем торговли биткойнами, как показано ниже.

# Filter the rows for minimum and maximum target values
min_row = Bdata_copy[Bdata_copy['Volume'] == min_target]
max_row = Bdata_copy[Bdata_copy['Volume'] == max_target]

# Print the extracted information
print("Min Target:")
print(min_row)

print("\nMax Target:")
print(max_row)

# Output 
# Min Target:
Date        Open        High         Low       Close   Adj Close  
201410  353.214996  359.984009  352.678986  357.618011  357.618011   

# Volume  
7845880  

# Max Target:
Date          Open          High           Low         Close  
202105  42944.976563  43546.117188  30681.496094  37002.441406   

# Adj Close        Volume  
37002.441406  126358098747  

С помощью столбца даты и целевой переменной (объема) мы можем получить представление об изменениях объема торговли биткойнами с течением времени, как показано ниже:

plt.figure(figsize=(12, 6))  # Adjust the figure size as needed
plt.plot(Bdata['Date'], Bdata['Volume'])
plt.xlabel('Date')
plt.ylabel('Volume')
plt.title('Volume over Time')

plt.xticks(rotation=45)  # Rotate the x-axis tick labels for better readability

plt.tight_layout()  # Adjust the spacing of the plot elements

plt.show()

Тот же код применяется к Ethereum:

# Scatter plot
plt.scatter(Ey_test, E_prediction, color='blue', label='Predicted vs Actual')

# Add labels and title
plt.xlabel('Actual Values')
plt.ylabel('Predicted Values')
plt.title('Comparison of Predicted and Actual Values')

# Add a diagonal line for reference
plt.plot([Ey_test.min(), Ey_test.max()], [Ey_test.min(), Ey_test.max()], color='red', linestyle='--', label='Ideal')

# Add legend
plt.legend()

# Show the plot
plt.show()

# Calculate the minimum and maximum target values
min_target = Ey_test.min()
max_target = Ey_test.max()


print("Min Target:", min_target)
print("Max Target:", max_target)

# Filter the rows for minimum and maximum target values
min_row = Edata_copy[Edata_copy['Volume'] == min_target]
max_row = Edata_copy[Edata_copy['Volume'] == max_target]

# Print the extracted information
print("Min Target:")
print(min_row)

print("\nMax Target:")
print(max_row)

plt.figure(figsize=(12, 6))  # Adjust the figure size as needed
plt.plot(Edata['Date'], Edata['Volume'])
plt.xlabel('Date')
plt.ylabel('Volume')
plt.title('Volume over Time')

plt.xticks(rotation=45)  # Rotate the x-axis tick labels for better readability

plt.tight_layout()  # Adjust the spacing of the plot elements

plt.show()

11. Заключение

В нашем случае показатель R2 0,5842 по модели Биткойн предполагает, что модель объясняет примерно 58,42% дисперсии данных Биткойн, а показатель R2 0,6494 по модели Ethereum предполагает, что модель объясняет примерно 64,94% дисперсии данных по Биткойну. данные. Хотя это указывает на умеренный уровень объяснительной способности, это также предполагает, что в данных все еще существует значительная необъяснимая изменчивость.

Чтобы определить, является ли модель точной или нет, важно учитывать контекст и ожидания для конкретной проблемы. Оценка R2, равная 0,65, может считаться приемлемой в некоторых доменах или для определенных приложений, в то время как в других она может быть недостаточной. Кроме того, сравнение показателя R2 с показателями других моделей или рассмотрение дополнительных показателей оценки может обеспечить более полную оценку точности модели.

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

# Cut Bitcoin data starting from 201711
B_copy_cut = Bdata_copy[Bdata_copy['Date'] >= 201711]
B_copy_cut = B_copy_cut[7:]
B_copy_cut.head()
import matplotlib.pyplot as plt

# Plotting B_copy_cut dataframe
plt.plot(B_copy_cut['Date'], B_copy_cut['Volume'], label='B_copy_cut')

# Plotting Edata_copy dataframe
plt.plot(Edata_copy['Date'], Edata_copy['Volume'], label='Edata_copy')

# Set the title and labels for the graph
plt.title('Volume Comparison')
plt.xlabel('Date')
plt.ylabel('Volume')

# Show the legend
plt.legend()

# Display the line graph
plt.show()

С помощью этого визуализированного графика мы можем получить представление, как показано ниже:

  • Биткойн и Эфириум имеют почти одинаковую тенденцию торговли.
  • Объем торговли биткойнами более чем в два раза превышает объем торговли эфириумом.
  • В 2021 году аналогичная тенденция двух криптовалют не подтвердилась, показывая, что спрос на торговлю биткойнами был чрезвычайно высоким с почти 10-кратной разницей с объемом торговли Ethereum.