Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement GoalkeeperActionType.PICK_UP and GoalkeeperActionType.CLAIM for StatsBomb #224

Merged
merged 1 commit into from
Dec 29, 2023

Conversation

probberechts
Copy link
Contributor

@probberechts probberechts commented Oct 6, 2023

This commit implements the GoalkeeperActionType.PICK_UP and GoalkeeperActionType.CLAIM qualifiers in the StatsBomb deserializer.

It implements the following StatsBomb to Kloppy mapping:

  • type="Collected" --> GoalKeeperActionType.CLAIM
  • type="KeeperSweeper" + outcome="Claim" --> GoalKeeperActionType.PICK_UP
  • type="KeeperSweeper" + outcome="Won" --> GoalKeeperActionType.SAVE
  • type="KeeperSweeper" + outcome="Success" --> GoalKeeperActionType.SAVE
  • type="KeeperSweeper" + outcome="Clear" --> GoalKeeperActionType.SAVE

@probberechts probberechts marked this pull request as draft October 6, 2023 15:29
@probberechts probberechts changed the title Implement Goalkeeper.PICK_UP for StatsBomb Implement Goalkeeper.PICK_UP and Goalkeeper.COLLECTED for StatsBomb Oct 15, 2023
@probberechts probberechts changed the title Implement Goalkeeper.PICK_UP and Goalkeeper.COLLECTED for StatsBomb Implement GoalkeeperActionType.PICK_UP and GoalkeeperActionType.CLAIM for StatsBomb Oct 15, 2023
@probberechts probberechts force-pushed the feat/statsbomb-goalkeeper-claim branch from 8249631 to 34544fc Compare November 17, 2023 20:53
@probberechts
Copy link
Contributor Author

It is still not entirely clear to me what the StatsBomb "KeeperSweeper" events exactly are. I've tried to compare them with some Opta data and they typically map to saves or sometimes smothers. So, I've decided to map them to the Kloppy GoalKeeperActionType.SAVE event.

@probberechts probberechts marked this pull request as ready for review November 17, 2023 21:05
@JanVanHaaren
Copy link
Collaborator

I actually think that kloppy currently doesn't have a corresponding event type.

StatsBomb records a Keeper Sweeper event when the goalkeeper comes off their line and potentially out of the box to clear the ball. The Keeper Sweeper event can have one of the following four outcomes.

  1. Won (4) when the goalkeeper retains possession.
  2. Success (15) when the goalkeeper clears the ball away from danger.
  3. Claim (47) when the goalkeeper collects the ball.
  4. Clear (48) when the goalkeeper clears the ball.

What are your thoughts on the following mapping to kloppy event types?

  1. Goalkeeper with action type Save.
  2. Clearance.
  3. Goalkeeper with action type Claim.
  4. Clearance.

However, I'm not sure whether we should deserialize goalkeeper events into non-goalkeeper events. I don't really know what the consequences would be.

@probberechts
Copy link
Contributor Author

Mapping them to clearances was also my first idea, but in the examples that I found they were never labeled as a clearance in the Opta data. It could just be my very limited sample, though.

I found one example with video: https://youtu.be/AHuk5Vv6oPc?t=417 (at 62:30).

According to StatsBomb it is a Keeper Sweeper - Clear event. Opta and Wyscout label it as an interception.

StatsBomb event
{
"id" : "758d6ee2-b92c-407c-aaa4-07612076fe34",
"index" : 2055,
"period" : 2,
"timestamp" : "00:17:33.173",
"minute" : 62,
"second" : 33,
"type" : {
  "id" : 23,
  "name" : "Goal Keeper"
},
"possession" : 122,
"possession_team" : {
  "id" : 768,
  "name" : "England"
},
"play_pattern" : {
  "id" : 1,
  "name" : "Regular Play"
},
"team" : {
  "id" : 785,
  "name" : "Croatia"
},
"player" : {
  "id" : 3444,
  "name" : "Danijel Subašić"
},
"position" : {
  "id" : 1,
  "name" : "Goalkeeper"
},
"location" : [ 3.0, 33.0 ],
"related_events" : [ "0bbf3525-0ec8-413f-b92b-1c8bf667aa88" ],
"goalkeeper" : {
  "outcome" : {
    "id" : 48,
    "name" : "Clear"
  },
  "type" : {
    "id" : 27,
    "name" : "Keeper Sweeper"
  }
}
}
Wyscout event
{
          "eventId": 7,
          "subEventName": "Touch",
          "tags": [
              {
                  "id": 1401
              }
          ],
          "playerId": 135747,
          "positions": [
              {
                  "y": 46,
                  "x": 2
              },
              {
                  "y": 31,
                  "x": 12
              }
          ],
          "matchId": 2058015,
          "eventName": "Others on the ball",
          "teamId": 9598,
          "matchPeriod": "2H",
          "eventSec": 1057.611022,
          "subEventId": 72,
          "id": 263155248
      }
Opta event
{
          "id": 1392192502,
          "eventId": 597,
          "minute": 62,
          "second": 34,
          "teamId": 337,
          "playerId": 29214,
          "x": 3.3,
          "y": 59.4,
          "expandedMinute": 64,
          "period": {
              "value": 2,
              "displayName": "SecondHalf"
          },
          "type": {
              "value": 74,
              "displayName": "BlockedPass"
          },
          "outcomeType": {
              "value": 1,
              "displayName": "Successful"
          },
          "qualifiers": [
              {
                  "type": {
                      "value": 56,
                      "displayName": "Zone"
                  },
                  "value": "Back"
              },
              {
                  "type": {
                      "value": 285,
                      "displayName": "Defensive"
                  }
              },
              {
                  "type": {
                      "value": 233,
                      "displayName": "OppositeRelatedEvent"
                  },
                  "value": "531"
              }
          ],
          "satisfiedEventsTypes": [
              91,
              60
          ],
          "isTouch": true
      }

@probberechts probberechts force-pushed the feat/statsbomb-goalkeeper-claim branch 2 times, most recently from 938e677 to 0455e44 Compare December 4, 2023 21:08
@probberechts
Copy link
Contributor Author

A new proposal after discussing with @JanVanHaaren:

  • type="Collected" --> GoalKeeperActionType.CLAIM
  • type="KeeperSweeper" + outcome="Claim" + body_part = "Hands" --> GoalKeeperActionType.PICK_UP
  • type="KeeperSweeper" + outcome="Claim" + body_part = "Foot" or "Head" or "Chest" --> RECOVERY
  • type="KeeperSweeper" + outcome="Won" --> GenericEvent (this never seems to be recorded)
  • type="KeeperSweeper" + outcome="Success" + body_part = "Foot" or "Head" --> CLEARANCE
  • type="KeeperSweeper" + outcome="Clear" + Bodypart = "Foot" or "Head" --> CLEARANCE
  • type="KeeperSweeper" + outcome="Success" + Bodypart = "Hands" or "Chest" or "Other" --> GoalKeeperActionType.SAVE
  • type="KeeperSweeper" + outcome="Clear" + Bodypart = "Hands" or "Chest" or "Other" --> GoalKeeperActionType.SAVE

@probberechts probberechts force-pushed the feat/statsbomb-goalkeeper-claim branch from 0455e44 to ba889e2 Compare December 4, 2023 21:16
Copy link
Collaborator

@JanVanHaaren JanVanHaaren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pull request looks good to me. Thanks!

@JanVanHaaren
Copy link
Collaborator

@probberechts I presume this pull request requires some additional work given that #262 has been merged.

This commit implements the following StatsBomb to Kloppy mapping:

- type="Collected" --> GoalKeeperActionType.CLAIM
- type="KeeperSweeper" + outcome="Claim" + body_part = "Hands" --> GoalKeeperActionType.PICK_UP
- type="KeeperSweeper" + outcome="Claim" + body_part = "Foot" or "Head" or "Chest" --> RECOVERY
- type="KeeperSweeper" + outcome="Won" --> GenericEvent (this never seems to be recorded)
- type="KeeperSweeper" + outcome="Success" + body_part = "Foot" or "Head" --> CLEARANCE
- type="KeeperSweeper" + outcome="Clear" + Bodypart = "Foot" or "Head" --> CLEARANCE
- type="KeeperSweeper" + outcome="Success" + Bodypart = "Hands" or "Chest" or "Other" --> GoalKeeperActionType.SAVE
- type="KeeperSweeper" + outcome="Clear" + Bodypart = "Hands" or "Chest" or "Other" --> GoalKeeperActionType.SAVE
@probberechts probberechts force-pushed the feat/statsbomb-goalkeeper-claim branch from ba889e2 to 3bce8f8 Compare December 26, 2023 19:56
@probberechts
Copy link
Contributor Author

@JanVanHaaren I've done the additional work 😅

Copy link
Collaborator

@JanVanHaaren JanVanHaaren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@koenvo koenvo merged commit 7ad771b into PySport:master Dec 29, 2023
19 checks passed
@koenvo koenvo added this to the 3.14 - Pi milestone Dec 29, 2023
@probberechts probberechts deleted the feat/statsbomb-goalkeeper-claim branch January 1, 2024 10:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants