Categories
程式開發

在FIFA 20 將技能相似球員進行分組(1):K-均值聚類


引言

足球(歐洲足球)從小就是我最喜歡的運動之一。 過去無論我去哪裡,都會隨身帶著足球,這樣我就能最大限度地利用踢足球的機會。

我也喜歡玩電腦遊戲《FIFA 足球世界》,我覺得,用機器學習來分析FIFA 中的球員是一件很酷的事情。

在本教程中,我將使用K-均值(K-Means)聚類算法在FIFA 20 將技能相似的球員進行分組。

了解聚類

聚類(Clustering)是無監督學習技術的一種(另一種是主成分分析)。

我們可以將觀測值聚類(或分組)到相同的子組中,使子組內的觀測值彼此相當相似,而不同子組中的觀測值彼此相當不同。

在FIFA 20 將技能相似球員進行分組(1):K-均值聚類 1

聚類示例。

上面的散點圖顯示了數據集中有三個不同的組。

了解K-均值聚類算法

K-均值聚類算法是聚類算法中的一種。

基本算法如下:

  • 指定K-聚類並初始化隨機質心。
  • 進行迭代,直到聚類分配停止更改。 該方法將每個觀測值精確地分配到K 個聚類中的一個。
  • 對於每個K 聚類,計算聚類平均值。
  • 繼續查看觀測值列表,並將觀測值分配給平均值最接近的聚類。

其目的是形成聚類,使同一聚類內的觀測值盡可能相似。

K-均值聚類算法使用平方歐幾里得距離計算相似度。

數據集

我們將使用Kaggle 的 FIFA 20 數據集

特徵工程

我們只會選擇數值和每個球員的名字。

df = df[['short_name','age', 'height_cm', 'weight_kg', 'overall', 'potential',
'value_eur', 'wage_eur', 'international_reputation', 'weak_foot',
'skill_moves', 'release_clause_eur', 'team_jersey_number',
'contract_valid_until', 'nation_jersey_number', 'pace', 'shooting',
'passing', 'dribbling', 'defending', 'physic', 'gk_diving',
'gk_handling', 'gk_kicking', 'gk_reflexes', 'gk_speed',
'gk_positioning', 'attacking_crossing', 'attacking_finishing',
'attacking_heading_accuracy', 'attacking_short_passing',
'attacking_volleys', 'skill_dribbling', 'skill_curve',
'skill_fk_accuracy', 'skill_long_passing', 'skill_ball_control',
'movement_acceleration', 'movement_sprint_speed', 'movement_agility',
'movement_reactions', 'movement_balance', 'power_shot_power',
'power_jumping', 'power_stamina', 'power_strength', 'power_long_shots',
'mentality_aggression', 'mentality_interceptions',
'mentality_positioning', 'mentality_vision', 'mentality_penalties',
'mentality_composure', 'defending_marking', 'defending_standing_tackle',
'defending_sliding_tackle', 'goalkeeping_diving',
'goalkeeping_handling', 'goalkeeping_kicking',
'goalkeeping_positioning', 'goalkeeping_reflexes']]

我提取的是總成績高於86 分的球員,因為我們不想使用18000 多名球員進行分組。

df = df[df.overall > 86] # extracting players with overall above 86

將空值替換為平均值。

df = df.fillna(df.mean())

歸一化(標準化/縮放)數據。

  • 我們希望將數據進行歸一化,因為變量是在不同尺度上測量的。
from sklearn import preprocessing
x = df.values # numpy array
scaler = preprocessing.MinMaxScaler()
x_scaled = scaler.fit_transform(x)
X_norm = pd.DataFrame(x_scaled)

使用主成分分析將圖中的60 個維度減少到2 個。

from sklearn.decomposition import PCA
pca = PCA(n_components = 2) # 2D PCA for the plot
reduced = pd.DataFrame(pca.fit_transform(X_norm))

執行K-均值聚類

我們將指定有5個聚類。

from sklearn.cluster import KMeans
# specify the number of clusters
kmeans = KMeans(n_clusters=5)
# fit the input data
kmeans = kmeans.fit(reduced)
# get the cluster labels
labels = kmeans.predict(reduced)
# centroid values
centroid = kmeans.cluster_centers_
# cluster values
clusters = kmeans.labels_.tolist()

通過添加球員的名字和他們的聚類來創建一個新的數據幀。

reduced['cluster'] = clusters
reduced['name'] = names
reduced.columns = ['x', 'y', 'cluster', 'name']
reduced.head()

K-均值聚類圖的可視化

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.set(style="white")
ax = sns.lmplot(x="x", y="y", hue="cluster", data = reduced, legend=False,
fit_reg=False, size = 15, scatter_kws={"s": 250})
texts = []
for x, y, s in zip(reduced.x, reduced.y, reduced.name):
texts.append(plt.text(x, y, s))
ax.set(ylim=(-2, 2))
plt.tick_params(labelsize=15)
plt.xlabel("PC 1", fontsize = 20)
plt.ylabel("PC 2", fontsize = 20)
plt.show()

在FIFA 20 將技能相似球員進行分組(1):K-均值聚類 2

K-均值聚類

看看基於球員位置的聚類是如何形成的,是不是很酷!

我希望本教程對你有所啟發,敬請關注下一篇教程!

作者介紹

Jaemin Lee,專攻數據分析與數據科學,數據科學應屆畢業生。

原文鏈接

https://towardsdatascience.com/grouping-soccer-players-with-like-skillsets-in-fifa-20-part-1-k-means-clustering-c4a845db78bc