PythonでJリーグのデータ分析をしてみた


今回、[FootyStats](https://footystats.org/jp/)というサッカーデータを扱うサイトからJリーグのデータをダウンロードしPythonで色々調べてみました。ただ２０２０年シーズンのcsvデータがまだダウンロードできなかったので２０１９年のデータを使っています。
このサイトはJリーグだけでなく世界各国のリーグの情報を扱っているので、サイトを眺めるだけでも面白いです。

Jリーグ（J1、J2、J、カップ戦）のデータは、それぞれ試合データ、チームデータ、選手データがダウンロードできます。
（順位表は[J.LEAGUE Data Site](https://data.j-league.or.jp/SFRT01/?search=search&yearId=2019&yearIdLabel=2019%E5%B9%B4&competitionId=460&competitionIdLabel=%E6%98%8E%E6%B2%BB%E5%AE%89%E7%94%B0%E7%94%9F%E5%91%BD%EF%BC%AA%EF%BC%91%E3%83%AA%E3%83%BC%E3%82%B0&competitionSectionId=0&competitionSectionIdLabel=%E6%9C%80%E6%96%B0%E7%AF%80&homeAwayFlg=3)から）。



```python
#各種ライブラリをインポート
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
```

#2019年の順位
FootyStatsのデータには勝ち点カラムがなかったので、[J.LEAGUE Data Site](https://data.j-league.or.jp/SFRT01/?search=search&yearId=2019&yearIdLabel=2019%E5%B9%B4&competitionId=460&competitionIdLabel=%E6%98%8E%E6%B2%BB%E5%AE%89%E7%94%B0%E7%94%9F%E5%91%BD%EF%BC%AA%EF%BC%91%E3%83%AA%E3%83%BC%E3%82%B0&competitionSectionId=0&competitionSectionIdLabel=%E6%9C%80%E6%96%B0%E7%AF%80&homeAwayFlg=3)というサイトからURLを直接取得して表示。

```python
#データを取り込む
j1_rank = 'https://data.j-league.or.jp/SFRT01/?search=search&yearId=2019&yearIdLabel=2019%E5%B9%B4&competitionId=460&competitionIdLabel=%E6%98%8E%E6%B2%BB%E5%AE%89%E7%94%B0%E7%94%9F%E5%91%BD%EF%BC%AA%EF%BC%91%E3%83%AA%E3%83%BC%E3%82%B0&competitionSectionId=0&competitionSectionIdLabel=%E6%9C%80%E6%96%B0%E7%AF%80&homeAwayFlg=3'
j1_rank = pd.read_html(j1_rank)
df_rank = pd.DataFrame(j1_rank[0])
df_rank.index = df_rank.index + 1
df_rank[['チーム','勝点', '勝', '分', '敗', '得点', '失点', '得失点差']]
```

![スクリーンショット 2020-12-31 10.44.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496614/246ed1ed-8103-2b41-5d1c-bbcccfa93bcf.png)


###基本統計量をざっと見てみる

```python
df_rank.describe()
```
勝ち点の平均は47点、中央値46.5点なので平均と中央値がほぼ一致してます。一応順位表を確認すると勝ち点46~47が１０位〜６位と真ん中か少し上に集中してます。

![スクリーンショット 2020-12-31 10.04.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496614/db0adee2-9030-2a3b-b734-a98ad2f2c6ea.png)


#Footy Statsのデータを読み込む

今回の分析用のcsvデータを読み込みます。チームデータを見ると、２９３カラムもありました。どんな種類のデータがあるのか確認するのもなかなか大変。。。

```python
df_team = pd.read_csv('j1_team_2019.csv')
pd.set_option('display.max_columns', None)
df_team.head(6)
```
![スクリーンショット 2020-12-30 18.48.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496614/b0d2007c-4995-6dba-73d7-0d82234b8a82.png)

```python

len(df_teams.columns)
#カラム数：293
```

####どんなデータがあるかざっと見てみる
df.culumns()でも表示できますが、for分で回したほうが個人的には見やすいです。

```python
for team in df_team:
    print(team)
```

![スクリーンショット 2020-12-31 9.57.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496614/de654262-4344-2771-ac1c-3ef590647b7f.png)

![スクリーンショット 2020-12-31 9.58.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496614/6a25f2e8-1800-355d-a909-b13ca1499241.png)

全項目は載せきれてませんが、試合の前後半の得点率などとても細かいデータも含まれていそうです。

##勝率

J1チームの勝率についてまとめました。
勝利した試合のうち、どれだけホームで勝利したのか、ホームに強いクラブを見てみたかったので「勝利のうちホーム率」の列を作り、その高い順に並べています。

```python
#勝率
df_team['wins_rate'] = df_team.apply(lambda row: row['wins'] / 34, axis=1)
#ホーム勝率
df_team['home_wins_rate'] = df_team.apply(lambda row: row['wins_home'] / 17, axis=1)
#勝利のうちホーム
df_team['wins_at_home'] = df_team.apply(lambda row: row['wins_home'] / row['wins'], axis=1)
df_team = df_team[['team_name', 'wins', 'wins_home','wins_rate', 'home_wins_rate', 'wins_at_home']].sort_values('wins_at_home', ascending=False).reset_index(drop=True)
df_team.index = df_team.index + 1
df_team.rename(columns={'team_name': 'クラブ名', 'wins': '勝利', 'wins_home': 'ホーム勝利', 'wins_rate': '勝率', 'home_wins_rate': 'ホーム勝率', 'wins_at_home': '勝利のうちホーム率'})
```

![スクリーンショット 2020-12-30 18.23.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496614/4ddd640b-602e-bce8-251f-8a107293c0d9.png)

名古屋が年間9勝していますが、そのうち７試合がホーム（約７８％）とホームで力を発揮してます。仙台も高いですね。下を見ると、近年優勝争いをしている川崎は意外にも低かったです。

## 得点数と勝利数の相関

当たり前ですが、得点を多くとれば勝つ試合も多くなると思いますが、得点数と勝利数の相関を見てみます。横軸に得点数、縦軸に勝利数をプロットしてみます。見た感じやはり正の相関が見られます。

```python
df = df_team
plt.scatter(df['goals_scored'], df['wins'])
plt.xlabel('goals_scored')
plt.ylabel('wins')
```


![スクリーンショット 2020-12-30 18.34.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496614/9901733b-7888-83f0-32d1-b4db12ab2900.png)

####チーム名を表示して見てみる

```python
for i, txt in enumerate(df.team_name):
    plt.annotate(txt, (df['goals_scored'].values[i], df['wins'].values[i]))
    print(txt)

plt.scatter(df['goals_scored'], df['wins'])
plt.xlabel('goals_scored')
plt.ylabel('wins')
plt.show()
```

![スクリーンショット 2020-12-31 11.46.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496614/9f3f7c65-c247-5579-e8d1-b99646293afb.png)



##失点数と勝利数の相関

反対に失点数と勝利数の相関を見てみます。こちらも相関（負の相関）はありそうですが、得点数と勝利数の相関ほど強くはなさそうです。

```python
df = df_team
plt.scatter(df['goals_conceded'], df['wins'])
plt.xlabel('goals_conceded')
plt.ylabel('wins')
```

![スクリーンショット 2020-12-30 18.35.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496614/7856f9dc-e8cc-79a4-0ae3-34b0a7bc8ff1.png)

```python
for i, txt in enumerate(df.team_name):
    plt.annotate(txt, (df['goals_conceded'].values[i], df['wins'].values[i]))
    print(txt)

plt.scatter(df['goals_conceded'], df['wins'])
plt.xlabel('goals_conceded')
plt.ylabel('wins')
plt.show()
```
####チーム名を表示

![スクリーンショット 2020-12-31 11.48.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496614/70c70ee6-6ebc-6c73-2f4d-7e4746f747a3.png)



###相関係数
得点数と勝利数、失点数と勝利数の相関係数をそれぞれ求めてみます。

####得点と勝利数の相関係数

```python
wins = df['wins']
goals_scored = df['goals_scored']
r = np.corrcoef(wins, goals_scored)
r
#相関係数：0.7184946
```

####失点と勝利数の相関係数



```python
wins = df['wins']
goals_conceded = df['goals_conceded']
r = np.corrcoef(wins, goals_conceded)
r
#相関係数：-0.58795491
```

得点数と勝利数の相関係数は約0.72とやはり高めで。失点数と勝利数の相関係数は約-0.58（絶対値0.58)と相関はありそうですが、得点数ほどではありません。


他にも色々分析中なので、追記するかもしれません。
また、2020シーズンのデータがダウンロード可能になったら2020シーズンも色々見てみる予定です。
コロナの影響で過密日程になり、交代枠のルールが変わったりしているので、平年とどう変わったのか比較してみたいです。