背景:最近学习PCA降维,恰逢NAB总决赛,所以动动手看看各球队的实力分布。数据不会说谎!
数据复制后存为本地excel文件
数据样例
1.读取数据
在读取数据后,将数据分成了team_name、data_Mat两部分,这是因为前者是球队名称,不属于待降维的属性;后者是需要进行降维的26个特征(属性、维度)。
这26个特征中包含胜场数、败场数、胜率等,明显存在相互关联的属性,这就是对其进行降维处理的基础。
import pandas as pd
from sklearn.decomposition import PCA
data = pd.read_excel(r'teams_regular.xlsx') #读取常规赛数据
# data = pd.read_excel(r'teams_playoffs.xlsx')
# 对数据进行区分,首列为球队名称,其余列为多维特征数据
team_name = data.iloc[:, 0]
data_Mat = data.iloc[:, 1:]')
2. PCA降维
由于sklearn库已经提供了包装好的PCA class,所以我们无需按照 原始数据各维度数据减去均值(各维度元素期望为零)、求降维投影后各维度内的方差、求降维投影后两两维度间的协方差、构造降维后的协方差矩阵(对角线元素为方差、非对角线元素为协方差)、将协方差矩阵进行对角化处理、按方差大小对维度排序等操作。
pca = PCA(n_components=2) #实例化一个PCA类,设置类参数n_components=2,表示从26D变为2D
pca.fit(data_Mat)
data_pca = pca.fit_transform(data_Mat) #降维后的数据
查看降维后的2D数据
print(type(data_pca))
print(data_pca)
>>>
>>> [[ 18.07327015 6.47772176]
[ 9.57112844 -8.96316249]
[ 9.55467987 -6.73426989]
[ 12.84008455 -4.42369386]
[ -0.15951735 -4.72242539]
[ 5.78874059 6.53546646]
[ 2.55502467 11.60814732]
[ -2.12610174 1.24236893]
[ -5.12467362 -5.03159773]
[ -1.21491395 -4.4512431 ]
[ -5.35091133 0.40087293]
[ -4.23529513 8.02825804]
[-10.93747531 1.14142101]
[-12.64892828 -5.00385826]
[ -9.33157419 -3.20480159]
[ -7.25353737 7.10079589]]
3. 可视化展示
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
for i in range(int(data_pca.size/2)):
team = data_pca[i]
ax.scatter(team[0], team[1])
ax.annotate(team_name[i], (team[0], team[1]))
plt.show()
30支球队常规赛实力对比
初始数据中每支球队有18项数据,我们不能对其可视化展示,也就不能快速获取各队的综合实力分布信息。采用PCA线性降维为2D后,可以从平面图上快速获取各队的实力对比。
需要注意的是,在降维后新的特征空间内,每个维度不再具有明确的实际意义,我们不能说出横轴、纵轴分别表示什么,但可以很容易判断出:在常规赛降维后对比图中X、Y的取值越小,左下角区域的火箭队、勇士队、骑士队、波士顿等都进入了季后赛,尤以火箭队表现最为抢眼。
16支球队季后赛实力对比
同样的,对16支进入季后赛的球队进行实力对比。截至2018.06.03当日,总决赛已进行1场,萌神带队的勇士表现格外抢眼。
4. 降维到3D
30支球队常规赛实力对比
16支球队季后赛实力对比
完整代码
#!usr/bin/env python
# -*- coding:utf-8 _*-
# Author:leegang [email protected]
# File: NBA_team.py
# Time: 2018/06/03 17:39
import pandas as pd
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
data = pd.read_excel(r'teams_regular.xlsx') #读取常规赛数据
# data = pd.read_excel(r'teams_playoffs.xlsx') #读取季后赛数据
# 对数据进行切分,首列为球队名称,其余列为多维特征数据
team_name = data.iloc[:, 0]
print(team_name)
data_Mat = data.iloc[:, 1:]
pca = PCA(n_components=3) #调整n_component参数以设置降维后的维度
data_pca = pca.fit_transform(data_Mat)
print(type(data_pca))
print(data_pca)
# 降维为2D数据可视化
# fig, ax = plt.subplots()
# for i in range(int(data_pca.size / 2)):
# team = data_pca[i]
# ax.scatter(team[0], team[1])
# ax.annotate(team_name[i], (team[0], team[1]))
# plt.show()
# 降维为3D数据可视化
from mpl_toolkits.mplot3d import Axes3D
fig, ax = plt.subplots()
ax = Axes3D(fig)
for i in range(int(data_pca.size / 3)):
team = data_pca[i]
ax.scatter3D(team[0], team[1], team[2],label=team_name[i])
# ax.legend()
ax.text(team[0], team[1], team[2],team_name[i])
plt.show()