# Football Player Clustering

*English translation by SOTA – AI Community of the Russian original. Licensed CC BY-NC-SA 4.0, like the original. Organisers who would like this translation removed can email sota.ai.community@gmail.com.*

*Contest 2 (27 June 2025) of the Kazakhstan IOAI Team Selection Test (Отборочные на IOAI), 2025; the contest hub marks this contest "Unrated". This is the Overview tab of the Kaggle competition "TST day2 Upsolving", the host's public upsolving copy of the contest, open from 27 June to 15 July 2025. Its subtitle reads: "This is a copy of the original contest. In the original, the metric worked incorrectly. The error has been fixed here." Original: [kaggle.com/competitions/tst-day-2-upsolving](https://www.kaggle.com/competitions/tst-day-2-upsolving). The Data tab is translated in a separate file.*

## Overview

In this task you are to cluster football players on the basis of their playing attributes, taken from the FIFA game. The dataset contains skills such as dribbling, passing, stamina, shot power, shooting accuracy and goalkeeping skills.

The goal is to divide the players into groups (clusters) that correspond to their hidden playing positions (for example, forward, defender, goalkeeper, etc.).

## Description

## 📌 What you need to do

* Analyse the features (34 playing skills in total).
* Apply clustering methods (for example, KMeans, DBSCAN, GMM, etc.).
* Determine the optimal number of clusters.
* Assign a cluster label to each player.
* Submit a `submission.csv` file with the columns: `id`, `positions`.

## Evaluation

## 📊 Evaluation metric: **B-Cubed F1 for multi-position clustering**

### 🧠 What the metric measures

Each player can have **several positions** (for example, `{CM, CAM}`). The purpose of the metric is to check how well the participant has grouped players with **overlapping positions**.

For each player $i$:

1. **Precision(i)** is the fraction of players in **the same predicted cluster** who have **at least one position in common** with player $i$:

$$
\text{Precision}_i = \frac{|\{j \in \text{Cluster}_i,\; j \ne i,\; y_j \cap y_i \ne \emptyset\}|}{|\text{Cluster}_i| - 1}
$$

2. **Recall(i)** is the fraction of players who have at least one position in common with player $i$ **and are in the same cluster**:

$$
\text{Recall}_i = \frac{|\{j \ne i,\; y_j \cap y_i \ne \emptyset,\; j \in \text{Cluster}_i\}|}{|\{j \ne i,\; y_j \cap y_i \ne \emptyset\}|}
$$
### 3. Averaging over all players:

$$
\text{Precision}_{avg} = \text{mean of } \text{Precision}_i
$$

$$
\text{Recall}_{avg} = \text{mean of } \text{Recall}_i
$$

---

### 4. Final result:

B-Cubed F1 = 2 * Precision_avg * Recall_avg / (Precision_avg + Recall_avg)


---

### 📌 Example

A cluster contains 3 players:

* Player 1: `{ST}`

* Player 2: `{ST, CF}`

* Player 3: `{CB}`
  (all of them are **in the same cluster**)

* **Precision(1)**:
  There are 2 other players in the cluster, and only 1 of them (player 2) overlaps in position
  → precision = 1 / 2 = 0.5

* **Recall(1)**:
  Player 2 is the only player whose positions overlap, and he is in the same cluster
  → recall = 1 / 1 = 1.0

* The values for the other players are computed in the same way; they are then averaged and the final F1 is computed.

---

### ✅ Advantages

* Supports **multi-class** (multi-position) labelling
* Takes into account both the **precision** of the clusters and their **recall**
* Does not depend on cluster size: each player makes an **equal contribution**
* The metric value always lies within **\[0, 1]**
