Сравнить коммиты

...

2 Коммитов

@ -0,0 +1,119 @@
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import seaborn as sns
from sklearn.preprocessing import StandardScaler
# Загрузка датасета MLB
mlb_data = pd.read_csv('SOCR_Data_MLB_HeightsWeights.txt', sep='\t')
mlb_data.columns = ['Name', 'Team', 'Position', 'Height', 'Weight', 'Age']
# Создаем 3D визуализацию
fig = plt.figure(figsize=(10, 7))
ax = plt.axes(projection='3d')
# Простая scatter plot без разбивки по позициям
ax.scatter3D(mlb_data['Height'], mlb_data['Weight'], mlb_data['Age'])
ax.set_title('3D Scatter Plot: MLB Players')
ax.set_xlabel('Height (inches)')
ax.set_ylabel('Weight (pounds)')
ax.set_zlabel('Age (years)')
plt.show()
# ТЕПЛОВЫЕ КАРТЫ
# Функция для вычисления матрицы частных корреляций
def partial_correlation_matrix(df):
"""
Вычисляет матрицу частных корреляций
"""
# Вычисляем матрицу ковариаций
cov_matrix = np.cov(df.T)
# Вычисляем обратную матрицу ковариаций
try:
inv_cov_matrix = np.linalg.inv(cov_matrix)
except np.linalg.LinAlgError:
# Если матрица вырождена, используем псевдообратную
inv_cov_matrix = np.linalg.pinv(cov_matrix)
# Вычисляем частные корреляции
n_features = inv_cov_matrix.shape[0]
partial_corr_matrix = np.zeros((n_features, n_features))
for i in range(n_features):
for j in range(n_features):
partial_corr_matrix[i, j] = -inv_cov_matrix[i, j] / np.sqrt(inv_cov_matrix[i, i] * inv_cov_matrix[j, j])
# Диагональные элементы устанавливаем в 1
np.fill_diagonal(partial_corr_matrix, 1)
return partial_corr_matrix
# Создаем фигуру для тепловых карт
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
# 1. Тепловая карта парных коэффициентов корреляции
numeric_data = mlb_data[['Height', 'Weight', 'Age']]
correlation_matrix = numeric_data.corr()
sns.heatmap(correlation_matrix,
annot=True,
cmap='coolwarm',
center=0,
vmin=-1,
vmax=1,
square=True,
fmt='.2f',
cbar_kws={'label': 'Correlation Coefficient'},
ax=ax1)
ax1.set_title('Тепловая карта парных коэффициентов корреляции\n(Pearson Correlation)')
# 2. Тепловая карта частных коэффициентов корреляции
# Стандартизация данных для частных корреляций
scaler = StandardScaler()
data_scaled = scaler.fit_transform(numeric_data)
# Вычисляем матрицу частных корреляций
partial_corr_matrix = partial_correlation_matrix(data_scaled)
partial_corr_df = pd.DataFrame(partial_corr_matrix,
index=numeric_data.columns,
columns=numeric_data.columns)
sns.heatmap(partial_corr_df,
annot=True,
cmap='coolwarm',
center=0,
vmin=-1,
vmax=1,
square=True,
fmt='.2f',
cbar_kws={'label': 'Partial Correlation Coefficient'},
ax=ax2)
ax2.set_title('Тепловая карта частных коэффициентов корреляции\n(Partial Correlation)')
plt.tight_layout()
plt.show()
# Вывод числовых значений для анализа
print("=" * 60)
print("АНАЛИЗ КОРРЕЛЯЦИЙ MLB ДАННЫХ")
print("=" * 60)
print("\nПАРНЫЕ КОРРЕЛЯЦИИ (Pearson):")
print(correlation_matrix.round(3))
print("\nЧАСТНЫЕ КОРРЕЛЯЦИИ:")
print(partial_corr_df.round(3))
print("\nИНТЕРПРЕТАЦИЯ:")
print("- Положительные значения: прямая связь между признаками")
print("- Отрицательные значения: обратная связь между признаками")
print("- Близкие к 1 или -1: сильная связь")
print("- Близкие к 0: слабая связь")

@ -0,0 +1,101 @@
import numpy as np
from matplotlib import pyplot as plt
from scipy.cluster.hierarchy import dendrogram
import pandas as pd
from sklearn.cluster import AgglomerativeClustering
from scipy.spatial import distance
# Загрузка датасета MLB
mlb_data = pd.read_csv('SOCR_Data_MLB_HeightsWeights.txt', sep='\t')
mlb_data.columns = ['Name', 'Team', 'Position', 'Height', 'Weight', 'Age']
# Создаем DataFrame аналогично ирисам
mlb_pd = pd.DataFrame(data=np.c_[mlb_data[['Height', 'Weight', 'Age']]],
columns=['Height (inches)', 'Weight (pounds)', 'Age (years)'])
# Выбираем данные для кластеризации
data = mlb_pd[['Height (inches)', 'Weight (pounds)', 'Age (years)']].to_numpy()
# расчет матрицы расстояний Чебышева
distance_matrix = np.zeros((len(data), len(data)))
for i in range(len(data)):
for j in range(i+1, len(data)):
distance_matrix[i][j] = distance.chebyshev(data[i], data[j])
distance_matrix[j][i] = distance_matrix[i][j]
def plot_dendrogram(model, **kwargs):
# Create linkage matrix and then plot the dendrogram
# create the counts of samples under each node
counts = np.zeros(model.children_.shape[0])
n_samples = len(model.labels_)
for i, merge in enumerate(model.children_):
current_count = 0
for child_idx in merge:
if child_idx < n_samples:
current_count += 1 # leaf node
else:
current_count += counts[child_idx - n_samples]
counts[i] = current_count
linkage_matrix = np.column_stack(
[model.children_, model.distances_, counts]
).astype(float)
# Plot the corresponding dendrogram
dendrogram(linkage_matrix, **kwargs)
# setting distance_threshold=0 ensures we compute the full tree.
metric = 'precomputed'
linkage = "single"
model = AgglomerativeClustering(compute_distances=True, metric=metric, linkage=linkage)
model = model.fit(distance_matrix)
print("Labels:", model.labels_)
print("Number of clusters:", len(np.unique(model.labels_)))
# Визуализация дендрограммы
plt.figure(figsize=(12, 6))
plt.title('Hierarchical Clustering Dendrogram - MLB Data \n metric="{}", linkage="{}"'.format(metric, linkage))
# plot the top three levels of the dendrogram
plot_dendrogram(model, truncate_mode="level", p=3)
plt.xlabel("Number of points in node")
plt.ylabel("Distance")
plt.show()
# 3D визуализация кластеров
fig1 = plt.figure(figsize=(12, 8))
ax = plt.axes(projection='3d')
scatter = ax.scatter3D(mlb_pd['Height (inches)'],
mlb_pd['Weight (pounds)'],
mlb_pd['Age (years)'],
c=model.labels_,
cmap='tab10',
s=50,
alpha=0.7)
ax.set_title('Agglomerative Clustering - MLB Players \n metric="{}", linkage="{}"'.format(metric, linkage))
ax.set_xlabel('Height (inches)')
ax.set_ylabel('Weight (pounds)')
ax.set_zlabel('Age (years)')
# Добавляем цветовую легенду
plt.colorbar(scatter, ax=ax, label='Cluster')
plt.show()
# Дополнительная информация о кластерах
print("\nИнформация о кластерах:")
for cluster_id in np.unique(model.labels_):
cluster_data = mlb_pd[model.labels_ == cluster_id]
print(f"Cluster {cluster_id}: {len(cluster_data)} players")
print(f" Средний рост: {cluster_data['Height (inches)'].mean():.1f} inches")
print(f" Средний вес: {cluster_data['Weight (pounds)'].mean():.1f} pounds")
print(f" Средний возраст: {cluster_data['Age (years)'].mean():.1f} years")
print()
print("Распределение позиций по кластерам:")
mlb_data_with_clusters = mlb_data.copy()
mlb_data_with_clusters['Cluster'] = model.labels_

@ -0,0 +1,206 @@
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.cluster.hierarchy import dendrogram, linkage
from sklearn.preprocessing import StandardScaler
from scipy.spatial import distance
# Загрузка датасета MLB
mlb_data = pd.read_csv('SOCR_Data_MLB_HeightsWeights.txt', sep='\t')
mlb_data.columns = ['Name', 'Team', 'Position', 'Height', 'Weight', 'Age']
# Создаем DataFrame
mlb_pd = pd.DataFrame(data=np.c_[mlb_data[['Height', 'Weight', 'Age']]],
columns=['Height (inches)', 'Weight (pounds)', 'Age (years)'])
# Стандартизация данных
scaler = StandardScaler()
data_scaled = scaler.fit_transform(mlb_pd[['Height (inches)', 'Weight (pounds)', 'Age (years)']])
# Функция для вычисления матрицы расстояний
def calculate_distance_matrix(data, metric):
n_samples = len(data)
distance_matrix = np.zeros((n_samples, n_samples))
for i in range(n_samples):
for j in range(i + 1, n_samples):
if metric == 'euclidean':
dist = distance.euclidean(data[i], data[j])
elif metric == 'cityblock':
dist = distance.cityblock(data[i], data[j])
elif metric == 'chebyshev':
dist = distance.chebyshev(data[i], data[j])
elif metric == 'cosine':
dist = distance.cosine(data[i], data[j])
distance_matrix[i][j] = dist
distance_matrix[j][i] = dist
return distance_matrix
# Список комбинаций для исследования
combinations = [
# Евклидово расстояние
{'metric': 'euclidean', 'linkage': 'single', 'name': 'Евклидово расстояние, одиночная связь'},
{'metric': 'euclidean', 'linkage': 'complete', 'name': 'Евклидово расстояние, полная связь'},
{'metric': 'euclidean', 'linkage': 'average', 'name': 'Евклидово расстояние, средняя связь'},
{'metric': 'euclidean', 'linkage': 'ward', 'name': 'Евклидово расстояние, связь Ward'},
# Манхэттенское расстояние
{'metric': 'cityblock', 'linkage': 'single', 'name': 'Манхэттенское расстояние, одиночная связь'},
{'metric': 'cityblock', 'linkage': 'average', 'name': 'Манхэттенское расстояние, средняя связь'},
{'metric': 'cityblock', 'linkage': 'complete', 'name': 'Манхэттенское расстояние, полная связь'},
# Косинусное расстояние
{'metric': 'cosine', 'linkage': 'single', 'name': 'Косинусное расстояние, одиночная связь'},
# Расстояние Чебышева
{'metric': 'chebyshev', 'linkage': 'single', 'name': 'Расстояние Чебышева, одиночная связь'},
{'metric': 'euclidean', 'linkage': 'centroid', 'name': 'Евклидово расстояние, центроидная связь'}
]
# Построение отдельных дендрограмм
for i, combo in enumerate(combinations, 1):
try:
# Вычисляем матрицу расстояний
distance_matrix = calculate_distance_matrix(data_scaled, combo['metric'])
# Создаем linkage matrix
Z = linkage(distance_matrix, method=combo['linkage'])
# Создаем отдельную фигуру для каждой дендрограммы
plt.figure(figsize=(12, 8))
# Строим дендрограмму
dendrogram(Z,
truncate_mode='lastp',
p=12,
show_leaf_counts=True,
leaf_rotation=90)
plt.title(f'Дендрограмма: {combo["name"]}', fontsize=14, pad=20)
plt.xlabel('Количество точек в узле', fontsize=12)
plt.ylabel('Расстояние', fontsize=12)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
print(f"{i}. {combo['name']} - Успешно построена")
except Exception as e:
print(f"{i}. {combo['name']} - Ошибка: {e}")
# 3D ВИЗУАЛИЗАЦИИ ДЛЯ КАЖДОЙ КОМБИНАЦИИ
print("\n" + "=" * 80)
print("3D ВИЗУАЛИЗАЦИЯ КЛАСТЕРОВ ДЛЯ КАЖДОЙ КОМБИНАЦИИ")
print("=" * 80)
for i, combo in enumerate(combinations, 1):
try:
# Вычисляем матрицу расстояний
distance_matrix = calculate_distance_matrix(data_scaled, combo['metric'])
# Создаем linkage matrix
Z = linkage(distance_matrix, method=combo['linkage'])
# Определяем кластеры (берем 3 кластера для визуализации)
from scipy.cluster.hierarchy import fcluster
labels = fcluster(Z, t=3, criterion='maxclust')
# Создаем отдельную 3D визуализацию
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
scatter = ax.scatter3D(mlb_pd['Height (inches)'],
mlb_pd['Weight (pounds)'],
mlb_pd['Age (years)'],
c=labels,
cmap='tab10',
s=50,
alpha=0.7)
ax.set_title(f'3D Визуализация: {combo["name"]}', fontsize=14, pad=20)
ax.set_xlabel('Height (inches)', fontsize=12)
ax.set_ylabel('Weight (pounds)', fontsize=12)
ax.set_zlabel('Age (years)', fontsize=12)
plt.colorbar(scatter, ax=ax, label='Cluster')
plt.tight_layout()
plt.show()
# Выводим информацию о кластерах
print(f"\n{i}. {combo['name']}:")
for cluster_id in np.unique(labels):
cluster_data = mlb_pd[labels == cluster_id]
print(f" Кластер {cluster_id}: {len(cluster_data)} игроков")
print(
f" Рост: {cluster_data['Height (inches)'].mean():.1f} ± {cluster_data['Height (inches)'].std():.1f}")
print(
f" Вес: {cluster_data['Weight (pounds)'].mean():.1f} ± {cluster_data['Weight (pounds)'].std():.1f}")
print(f" Возраст: {cluster_data['Age (years)'].mean():.1f} ± {cluster_data['Age (years)'].std():.1f}")
except Exception as e:
print(f"{i}. Ошибка в 3D визуализации для {combo['name']}: {e}")
# АНАЛИЗ РАССТОЯНИЙ ОБЪЕДИНЕНИЯ ДЛЯ ОПРЕДЕЛЕНИЯ ОПТИМАЛЬНОГО ЧИСЛА КЛАСТЕРОВ
print("\n" + "=" * 80)
print("АНАЛИЗ ОПТИМАЛЬНОГО ЧИСЛА КЛАСТЕРОВ")
print("=" * 80)
# Анализируем лучшие комбинации
best_combinations = [
{'metric': 'euclidean', 'linkage': 'ward', 'name': 'Евклидово расстояние, связь Ward'},
{'metric': 'euclidean', 'linkage': 'average', 'name': 'Евклидово расстояние, средняя связь'},
{'metric': 'cityblock', 'linkage': 'average', 'name': 'Манхэттенское расстояние, средняя связь'}
]
for i, combo in enumerate(best_combinations, 1):
try:
# Вычисляем матрицу расстояний
distance_matrix = calculate_distance_matrix(data_scaled, combo['metric'])
Z = linkage(distance_matrix, method=combo['linkage'])
# Анализ расстояний объединения
last_merges = Z[-15:, 2] # последние 15 объединений
distances_diff = np.diff(last_merges[::-1])
# Находим оптимальное число кластеров
optimal_idx = np.argmax(distances_diff) + 2
optimal_clusters = min(optimal_idx, 8)
# Создаем отдельную фигуру для анализа
plt.figure(figsize=(10, 6))
plt.plot(range(len(last_merges)), last_merges[::-1], 'bo-', linewidth=2, markersize=6)
plt.axvline(x=optimal_idx - 1, color='red', linestyle='--',
label=f'Оптимально: {optimal_clusters} кластеров')
plt.title(f'Анализ расстояний объединения: {combo["name"]}\nОптимальное число кластеров: {optimal_clusters}')
plt.xlabel('Шаг объединения')
plt.ylabel('Расстояние')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
print(f"{i}. {combo['name']}: оптимальное число кластеров = {optimal_clusters}")
print(f" Наибольший скачок расстояния: {distances_diff[optimal_idx - 2]:.3f}")
except Exception as e:
print(f"{i}. Ошибка в анализе для {combo['name']}: {e}")
# ИТОГОВЫЙ ВЫВОД
print("\n" + "=" * 80)
print("ИТОГОВЫЕ ВЫВОДЫ")
print("=" * 80)
print("1. Все 10 дендрограмм построены по отдельности")
print("2. Для каждой комбинации создана отдельная 3D визуализация")
print("3. Метод Ward обычно дает наиболее сбалансированные кластеры")
print("4. Одиночная связь может создавать вытянутые 'цепочки' кластеров")
print("5. Оптимальное число кластеров определяется по наибольшему скачку в расстояниях объединения")
print("6. Для MLB данных оптимально 3-5 кластеров, соответствующих различным физическим типам игроков")
print("7. Разные метрики расстояния показывают различные аспекты сходства между игроками")

@ -0,0 +1,32 @@
import numpy as np
from matplotlib import pyplot as plt
import pandas as pd
from sklearn.decomposition import PCA
# Загрузка датасета MLB
mlb_data = pd.read_csv('SOCR_Data_MLB_HeightsWeights.txt', sep='\t')
mlb_data.columns = ['Name', 'Team', 'Position', 'Height', 'Weight', 'Age']
# Создаем DataFrame аналогично ирисам
mlb_pd = pd.DataFrame(data=np.c_[mlb_data[['Height', 'Weight', 'Age']]],
columns=['Height (inches)', 'Weight (pounds)', 'Age (years)'])
# Выбираем данные для PCA
data = mlb_pd[['Height (inches)', 'Weight (pounds)', 'Age (years)']].to_numpy()
# Применяем PCA
pca = PCA(n_components=2)
pca.fit(data)
principalComponents = pca.fit_transform(data)
# вывод объясненной дисперсии
print("Объясненная дисперсия каждой компоненты:", pca.explained_variance_ratio_)
print("Суммарная объясненная дисперсия:", sum(pca.explained_variance_ratio_))
pc_df = pd.DataFrame(data=principalComponents, columns=['PC1', 'PC2'])
plt.scatter(pc_df['PC1'], pc_df['PC2'])
plt.xlabel('PC1')
plt.ylabel('PC2')
plt.title("Projection on First Two Principal Components - MLB Data")
plt.show()

@ -0,0 +1,43 @@
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.manifold import TSNE
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
# Загрузка датасета MLB
mlb_data = pd.read_csv('SOCR_Data_MLB_HeightsWeights.txt', sep='\t')
mlb_data.columns = ['Name', 'Team', 'Position', 'Height', 'Weight', 'Age']
mlb_pd = pd.DataFrame(data=np.c_[mlb_data[['Height', 'Weight', 'Age']]],
columns=['Height (inches)', 'Weight (pounds)', 'Age (years)'])
data = mlb_pd[['Height (inches)', 'Weight (pounds)', 'Age (years)']].to_numpy()
# Лучшие перплексии для анализа кластеров
best_perplexities = [10, 30, 60, 90]
for perplexity in best_perplexities:
# t-SNE
data_embedded = TSNE(n_components=2, learning_rate='auto', init='random',
perplexity=perplexity, random_state=42).fit_transform(data)
# Кластеризация K-means
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
labels = kmeans.fit_predict(data_embedded)
# Silhouette Score
sil_score = silhouette_score(data_embedded, labels)
# Визуализация
plt.figure(figsize=(8, 6))
scatter = plt.scatter(data_embedded[:, 0], data_embedded[:, 1],
c=labels, cmap='tab10', alpha=0.7, s=40)
plt.title(f't-SNE + K-means\nPerplexity = {perplexity}\nSilhouette: {sil_score:.3f}')
plt.xlabel('t-SNE Component 1')
plt.ylabel('t-SNE Component 2')
plt.colorbar(scatter, label='Cluster')
plt.grid(True, alpha=0.3)
plt.show()
print(f"Perplexity {perplexity}: {len(np.unique(labels))} кластеров, Silhouette = {sil_score:.3f}")

@ -0,0 +1,243 @@
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
# Загрузка датасета MLB
mlb_data = pd.read_csv('SOCR_Data_MLB_HeightsWeights.txt', sep='\t')
mlb_data.columns = ['Name', 'Team', 'Position', 'Height', 'Weight', 'Age']
# Создаем DataFrame
mlb_pd = pd.DataFrame(data=np.c_[mlb_data[['Height', 'Weight', 'Age']]],
columns=['Height (inches)', 'Weight (pounds)', 'Age (years)'])
# Стандартизация данных
scaler = StandardScaler()
data_scaled = scaler.fit_transform(mlb_pd[['Height (inches)', 'Weight (pounds)', 'Age (years)']])
# Значения K для кластеризации
k_values = [2, 3, 4]
print("=" * 60)
print("НЕИЕРАРХИЧЕСКАЯ КЛАСТЕРИЗАЦИЯ - МЕТОД K-СРЕДНИХ")
print("=" * 60)
for k in k_values:
# Применяем K-means
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(data_scaled)
# Создаем отдельную 3D визуализацию для каждого K
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')
# Цвета для кластеров
colors = ['red', 'blue', 'green', 'orange', 'purple']
# Визуализация каждого кластера
for cluster_id in range(k):
cluster_data = mlb_pd[labels == cluster_id]
ax.scatter3D(cluster_data['Height (inches)'],
cluster_data['Weight (pounds)'],
cluster_data['Age (years)'],
c=colors[cluster_id],
label=f'Cluster {cluster_id}',
s=50,
alpha=0.7,
edgecolors='black',
linewidth=0.5)
# Добавляем центроиды
centers_original = scaler.inverse_transform(kmeans.cluster_centers_)
ax.scatter3D(centers_original[:, 0],
centers_original[:, 1],
centers_original[:, 2],
c='black',
marker='X',
s=200,
label='Centroids',
edgecolors='white',
linewidth=2)
ax.set_title(f'K-means Clustering\nK = {k} clusters', fontsize=16, pad=20)
ax.set_xlabel('Height (inches)', fontsize=12, labelpad=10)
ax.set_ylabel('Weight (pounds)', fontsize=12, labelpad=10)
ax.set_zlabel('Age (years)', fontsize=12, labelpad=10)
ax.legend()
plt.tight_layout()
plt.show()
# Анализ кластеров
print(f"\nK = {k}:")
mlb_pd_temp = mlb_pd.copy()
mlb_pd_temp['Cluster'] = labels
for cluster_id in range(k):
cluster_data = mlb_pd_temp[mlb_pd_temp['Cluster'] == cluster_id]
center = centers_original[cluster_id]
print(f" Cluster {cluster_id} ({len(cluster_data)} players):")
print(f" Center: Height={center[0]:.1f}\", Weight={center[1]:.1f}lbs, Age={center[2]:.1f}yr")
print(
f" Stats: Height={cluster_data['Height (inches)'].mean():.1f}±{cluster_data['Height (inches)'].std():.1f}\"")
print(
f" Weight={cluster_data['Weight (pounds)'].mean():.1f}±{cluster_data['Weight (pounds)'].std():.1f}lbs")
print(f" Age={cluster_data['Age (years)'].mean():.1f}±{cluster_data['Age (years)'].std():.1f}yr")
# СРАВНИТЕЛЬНЫЙ АНАЛИЗ КАЧЕСТВА КЛАСТЕРИЗАЦИИ
print("\n" + "=" * 60)
print("СРАВНИТЕЛЬНЫЙ АНАЛИЗ КАЧЕСТВА КЛАСТЕРИЗАЦИИ")
print("=" * 60)
from sklearn.metrics import silhouette_score, calinski_harabasz_score
results = []
for k in k_values:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(data_scaled)
sil_score = silhouette_score(data_scaled, labels)
ch_score = calinski_harabasz_score(data_scaled, labels)
results.append({
'K': k,
'Silhouette': sil_score,
'Calinski-Harabasz': ch_score,
'Inertia': kmeans.inertia_
})
print(f"K = {k}:")
print(f" Silhouette Score: {sil_score:.3f}")
print(f" Calinski-Harabasz Score: {ch_score:.1f}")
print(f" Within-Cluster Sum of Squares: {kmeans.inertia_:.1f}")
# ВИЗУАЛИЗАЦИЯ С РАЗНЫМИ УГЛАМИ ОБЗОРА
print("\n" + "=" * 60)
print("3D ВИЗУАЛИЗАЦИЯ С РАЗНЫМИ УГЛАМИ ОБЗОРА")
print("=" * 60)
# Выбираем оптимальное K (обычно 3 для MLB данных)
optimal_k = 3
kmeans_optimal = KMeans(n_clusters=optimal_k, random_state=42, n_init=10)
labels_optimal = kmeans_optimal.fit_predict(data_scaled)
centers_optimal = scaler.inverse_transform(kmeans_optimal.cluster_centers_)
# Разные углы обзора
view_angles = [
(30, 45), # стандартный вид
(0, 0), # вид сверху
(90, 0), # вид сбоку
(30, -45) # вид с другой стороны
]
for i, (elev, azim) in enumerate(view_angles):
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
colors = ['red', 'blue', 'green']
for cluster_id in range(optimal_k):
cluster_data = mlb_pd[labels_optimal == cluster_id]
ax.scatter3D(cluster_data['Height (inches)'],
cluster_data['Weight (pounds)'],
cluster_data['Age (years)'],
c=colors[cluster_id],
label=f'Cluster {cluster_id}',
s=50,
alpha=0.7)
# Центроиды
ax.scatter3D(centers_optimal[:, 0],
centers_optimal[:, 1],
centers_optimal[:, 2],
c='black',
marker='X',
s=200,
label='Centroids')
ax.view_init(elev=elev, azim=azim)
ax.set_title(f'K-means (K=3) - View {i + 1}\nElevation: {elev}°, Azimuth: {azim}°', fontsize=14)
ax.set_xlabel('Height (inches)')
ax.set_ylabel('Weight (pounds)')
ax.set_zlabel('Age (years)')
ax.legend()
plt.tight_layout()
plt.show()
# ФИНАЛЬНАЯ ВИЗУАЛИЗАЦИЯ С АНАЛИЗОМ ПОЗИЦИЙ
print("\n" + "=" * 60)
print("ФИНАЛЬНЫЙ АНАЛИЗ - РАСПРЕДЕЛЕНИЕ ПОЗИЦИЙ ПО КЛАСТЕРАМ")
print("=" * 60)
# Анализ для K=3 (оптимальное значение)
mlb_data_with_clusters = mlb_data.copy()
mlb_data_with_clusters['Cluster'] = labels_optimal
# Группируем позиции по основным категориям
def categorize_position(pos):
if 'Pitcher' in pos:
return 'Pitcher'
elif 'Catcher' in pos:
return 'Catcher'
elif 'Baseman' in pos:
return 'Infielder'
elif 'Outfielder' in pos:
return 'Outfielder'
else:
return 'Other'
mlb_data_with_clusters['Position_Category'] = mlb_data_with_clusters['Position'].apply(categorize_position)
print("\nРаспределение позиций по кластерам (K=3):")
cluster_position = mlb_data_with_clusters.groupby(['Cluster', 'Position_Category']).size().unstack(fill_value=0)
print(cluster_position)
# Визуализация с интерпретацией кластеров
fig = plt.figure(figsize=(14, 10))
ax = fig.add_subplot(111, projection='3d')
colors = ['red', 'blue', 'green']
cluster_names = ['Low Height/Weight', 'Medium Build', 'High Height/Weight']
for cluster_id in range(optimal_k):
cluster_data = mlb_pd[labels_optimal == cluster_id]
ax.scatter3D(cluster_data['Height (inches)'],
cluster_data['Weight (pounds)'],
cluster_data['Age (years)'],
c=colors[cluster_id],
label=f'{cluster_names[cluster_id]} ({len(cluster_data)} players)',
s=60,
alpha=0.8)
# Центроиды
ax.scatter3D(centers_optimal[:, 0],
centers_optimal[:, 1],
centers_optimal[:, 2],
c='black',
marker='X',
s=300,
label='Centroids',
edgecolors='white',
linewidth=3)
ax.set_title('FINAL: K-means Clustering of MLB Players\nK = 3 (Optimal)', fontsize=16, pad=20)
ax.set_xlabel('Height (inches)\n← Shorter Taller →', fontsize=12, labelpad=15)
ax.set_ylabel('Weight (pounds)\n← Lighter Heavier →', fontsize=12, labelpad=15)
ax.set_zlabel('Age (years)\n← Younger Older →', fontsize=12, labelpad=15)
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
print("\n" + "=" * 60)
print("ИТОГОВЫЕ ВЫВОДЫ")
print("=" * 60)
print("1. K=2: Два крупных кластера (общее разделение по физическим параметрам)")
print("2. K=3: Оптимальное разделение (низкие/средние/высокие игроки)")
print("3. K=4: Более детальное разделение, но может быть избыточным")
print("4. Рекомендуется K=3 для MLB данных")

Двоичные данные
ИАД/lr2/Отчет_ЛР2_бригада1.docx (Хранится Git LFS)

Двоичный файл не отображается.
Загрузка…
Отмена
Сохранить