302 KiB
302 KiB
- Выбор бизнес-цели и постановка задачи
Бизнес-цель: Проанализировать финансовые рынки и выявить группы схожих дней по поведению цен и объёмов торгов различных активов и индексов, чтобы помочь инвесторам находить типичные рыночные ситуации и принимать решения на основе паттернов.
Задача: На основе ежедневных значений цен и объёмов кластеризовать дни на группы с похожими характеристиками. Выявить и визуализировать эти группы.
In [2]:
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans, AgglomerativeClustering
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
- Загрузка и подготовка данных
In [3]:
data = pd.read_csv("data/FINAL_USO.csv")
data.head()
Out[3]:
In [4]:
data_num = data.drop(columns=['Date'])
print('Пропуски по столбцам:')
print(data_num.isnull().sum())
data_num = data_num.fillna(data_num.mean())
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data_num)
print(f'Размер данных после обработки: {data_scaled.shape}')
- Понижение размерности и визуализация
In [5]:
pca = PCA(n_components=2, random_state=42)
data_pca = pca.fit_transform(data_scaled)
plt.figure(figsize=(8,6))
plt.scatter(data_pca[:,0], data_pca[:,1], s=15, alpha=0.6)
plt.title('PCA - визуализация данных')
plt.xlabel('Главная компонента 1')
plt.ylabel('Главная компонента 2')
plt.show()
- Выбор количества кластеров (K)
In [6]:
inertias = []
silhouettes = []
K_range = range(2, 11)
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42)
labels = kmeans.fit_predict(data_scaled)
inertias.append(kmeans.inertia_)
silhouettes.append(silhouette_score(data_scaled, labels))
plt.figure(figsize=(14,5))
plt.subplot(1,2,1)
plt.plot(K_range, inertias, marker='o')
plt.title('Метод локтя')
plt.xlabel('Количество кластеров K')
plt.ylabel('Инерция')
plt.subplot(1,2,2)
plt.plot(K_range, silhouettes, marker='o', color='orange')
plt.title('Коэффициент силуэта')
plt.xlabel('Количество кластеров K')
plt.ylabel('Силуэт')
plt.show()
optimal_k = K_range[np.argmax(silhouettes)]
print(f'Оптимальное количество кластеров по коэффициенту силуэта: {optimal_k}')
- Кластеризация и оценка качества
In [7]:
kmeans_final = KMeans(n_clusters=optimal_k, random_state=42)
labels_kmeans = kmeans_final.fit_predict(data_scaled)
agglo = AgglomerativeClustering(n_clusters=optimal_k)
labels_agglo = agglo.fit_predict(data_scaled)
sil_kmeans = silhouette_score(data_scaled, labels_kmeans)
sil_agglo = silhouette_score(data_scaled, labels_agglo)
print(f'Силуэт KMeans: {sil_kmeans:.3f}')
print(f'Силуэт AgglomerativeClustering: {sil_agglo:.3f}')
- Визуализация кластеров
In [9]:
import matplotlib.pyplot as plt
colors = ['red', 'blue', 'green', 'purple', 'orange', 'cyan', 'magenta', 'brown', 'olive', 'pink']
plt.figure(figsize=(12,5))
plt.subplot(1,2,1)
for i in range(optimal_k):
cluster = data_pca[labels_kmeans == i]
plt.scatter(cluster[:, 0], cluster[:, 1], color=colors[i % len(colors)], label=f'Кластер {i}', s=40, alpha=0.7)
plt.title('KMeans кластеризация')
plt.xlabel('PC1')
plt.ylabel('PC2')
plt.legend()
plt.subplot(1,2,2)
for i in range(optimal_k):
cluster = data_pca[labels_agglo == i]
plt.scatter(cluster[:, 0], cluster[:, 1], color=colors[i % len(colors)], label=f'Кластер {i}', s=40, alpha=0.7)
plt.title('Иерархическая кластеризация')
plt.xlabel('PC1')
plt.ylabel('PC2')
plt.legend()
plt.tight_layout()
plt.show()