В этой статье я собираюсь проанализировать объем торговли криптовалютой (Биткойн и Эфириум) с помощью 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. Обучайте модель и прогнозируйте результат
Линейная регрессия
Линейная регрессия используется для прогнозирования непрерывных значений, установления линейной зависимости между входными признаками (независимыми переменными) и целевым значением числового типа (зависимой переменной).
(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.