NBA 선수 클러스터링

할 일



· 미국 프로 농구 리그 NBA의 플레이어 데이터를 스크래핑하고
k-means를 사용하여 플레이 스타일별로 플레이어를 클러스터링합니다.
· 클러스터링한 데이터를 PCA로 차원 삭감하여 가시화한 후 코사인 유사도로 선수끼리의 유사도를 구한다.

동기



동기로서는 여기 쪽의 기사를 보고 재현해 보고 싶었기 때문입니다.
내용으로는, 팀의 에이스 Kevin Durant 선수가 트레이드 되고, 대신에 들어온 D'Angelo Russell 선수가 팀에 얼마나 맞는지의 지표로서 플레이어를 플레이 스타일별로 클러스터링해, 트레이드 된 플레이어와 같은 클러스터에 소속되어 있는 플레이어라면 팀 안에서 기능하는 것이 아닐까 하는 것입니다.

데이터



NBA에는 대량의 데이터를 제공하고 있다 사이트 가 있어, 이곳에서 Selenium을 사용해 2018-19기의 플레이어 약 500명 중에서 출전 경기가 40 이상, 출전 시간 1000분 이상을 채운 272 사람의 선수 중에서 아래의 데이터를 스크래핑합니다.
아래의 항목 일람 중 득점이나 정밀도에 관한 데이터가 없는 것에 의해 플레이 스타일별로 클러스터링하기 쉬워지고 있을까 생각합니다.
(일부 항목에는 최대값으로 나누어 정규화? 하고 있습니다)

※사용한 항목 일람

인용 원본 htps: //미로. 메 m. 이 m / 마 x / 2464 / 1 * 8 에오 v 294 68vmdKB2g. pg

클러스터링



이러한 데이터를 사용하여 sklearn의 k-means로 클러스터링합니다.
참고 기사에서는 클러스터의 수는 10이었지만, 제 경우에는 14 클러스터의 결과가 제일 좋다고 생각했기 때문에 클러스터의 수는 14로 했습니다.
플레이어는 Dataframe에서 선수의 ID와 이름을 제외합니다.
또한 시각화하고 싶기 때문에 PCA도 준비해 둡니다.
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from IPython.display import display
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
%matplotlib inline

kmeans_model = KMeans(n_clusters=14, random_state=1).fit(players.iloc[:, 3:])
labels = kmeans_model.labels_
#主成分分析の実行
pca = PCA()
pca.fit(players.iloc[:, 3:])
feature = pca.transform(players.iloc[:, 3:])
color_codes = {0:'#00FF00', 1:'#FF0000', 2:'#0000FF',3:'#FD7E00',4:'#000000',5:"#008b8b",6:"#ff00ff",7:"#800000",8:"#fa8072",9:"#ffdab9",10:'#66cdaa',11:"#ffff00",12:"#a9a9a9",13:"#6a5acd"}
colors = [color_codes[x] for x in labels]
plt.figure(figsize=(6, 6))
for x, y, name in zip(feature[:, 0], feature[:, 1], ""):
    plt.text(x, y, name, alpha=0.8, size=10)
plt.scatter(feature[:, 0], feature[:, 1], alpha=0.8, color=colors)
plt.title("Principal Component Analysis")
plt.xlabel("The first principal component score")
plt.ylabel("The second principal component score")
plt.show()


평가가 어렵습니다만, 개인적으로는 상당히 좋은 것은? 라고 생각합니다. . .

검증



주제이지만 Kevin Durant 선수와 D’Angelo Russell 선수가 같은 클러스터에 있는지 알고 싶습니다. 그래서
players["label"] = labels
#Kevin Durantのクラスタのラベル
kd_label = players[players.PLAYER_NAME=="Kevin Durant"].label.values[0]
display(players[players.label==kd_label])


같은 클러스터에 속했습니다! !

코사인 유사도



마지막으로 코사인 유사도로 Kevin Durant와 유사도가 가장 가까운 선수를 보고 싶습니다.
def cosine_similarity_matrix (vectors):
    unit_vectors = vectors / np.linalg.norm(vectors, axis=1, keepdims=True)
    return np.matmul(unit_vectors, unit_vectors.T)

players = players.drop("label", axis=1)
np_players = players.values[:,3:]
np_players = np_players.astype(float)
player_names = ['{}'.format(players[i:i+1].PLAYER_NAME.values[0]) for i in range(272)]
matrix = cosine_similarity_matrix(np_players)
df_players = pd.DataFrame(matrix, index=player_names, columns=player_names)
search_name = "Kevin Durant"
result = df_players[search_name].sort_values(ascending=False).drop(index=search_name)
print(result)


Khris Middleton이라는 선수가 가장 유사도가 높다는 결과가 되었습니다.
솔직히, 나는 몰랐지만 YouTube에서 보면 대부분의 플레이 스타일이 비슷했습니다.
아나가치 정밀도는 나쁘지 않을지도 모릅니다.

마지막으로



자신이 좋아하는 것으로 데이터를 분석해 보면 즐거운 것이군요.
내년 야무라 루 선수가 누구와 유사도가 높은지 기대됩니다.

좋은 웹페이지 즐겨찾기