世界杯欧洲预选赛|1999年美国女足世界杯|静海码头的世界杯海洋之旅站|jinghaimt.com

数据分析笔记

一、相关知识点

对于无监督的K-Means聚类需要确定k值,最佳k值的确定有两种常用的评估方法,用于确定最佳k值:“簇内离差平方和拐点法”、“轮廓系数法”。① 拐点法:在不同的k值下计算簇内的离差平方和,然后通过可视化的方法找到“拐点”所对应的k值② 轮廓系数法:该方法综合考虑了簇的密集性与分散性两个信息,如果数据集被分割为理想的k个簇,那么对应的簇内样本会很密集,而簇间样本会很分散,轮廓系数的计算公式如下:其中,a(i)体现了簇内的密集性,代表样本i与同簇内其他样本点距离的平均值;b(i)反映了簇间的分散性,其计算过程是:样本i与其他非同簇样本点距离的平均值,然后从平均值中挑选出最小值。

二、代码

import pandas as pd

import numpy as n

# 读取网页中的数据表

table = []

for i in range(1,7):

table.append(pd.read_html('https://nba.hupu.com/stats/players/pts/%d' %i)[0])#使用pandas中的read_html函数读取虎扑体育网页中的球员数据表

# 所有数据纵向合并为数据框

players = pd.concat(table)

# 变量重命名

columns=['排名','球员','球队','得分','命中-出手','命中率','命中-三分','三分命中率','命中-罚球','罚球命中率','场次','上场时间']

players.columns=columns

players.drop(0,inplace=True)

print(players)

players.to_csv(r"../data/players.csv",encoding='utf_8_sig')#将结果写入本地文件players.csv

#原始数据中命中率的格式为x%,需要进行标准化处理转化为数值形式,小数点后保留3位小数。

# 读取球员数据

import pandas as pd

import matplotlib.pyplot as plt

import numpy as np

players = pd.read_csv(r'../data/players.csv')

players.head()

# 中文和负号的正常示

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

plt.rcParams['axes.unicode_minus'] = False

#绘制得分与命中率的散点图

import seaborn as sns

sns.lmplot(x = '得分',y = '命中率',data = players,

fit_reg = False, scatter_kws = {'alpha':0.8,'color':'steelblue'})

plt.show()

# 构造自定义函数,用于绘制不同k值和对应总的簇内离差平方和的折线图

def k_SSE(X, clusters):

# 选择连续的K种不同的值

K = range(1,clusters+1)

# 构建空列表用于存储总的簇内离差平方和

TSSE = []

for k in K:

# 用于存储各个簇内离差平方和

SSE = []

from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters=k)

kmeans.fit(X)

# 返回簇标签

labels = kmeans.labels_

# 返回簇中心

centers = kmeans.cluster_centers_

# 计算各簇样本的离差平方和,并保存到列表中

for label in set(labels):

SSE.append(np.sum((X.loc[labels == label,]-centers[label,:])**2))

# 计算总的簇内离差平方和

TSSE.append(np.sum(SSE))

# 中文和负号的正常显示

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

plt.rcParams['axes.unicode_minus'] = False

# 设置绘图风格

plt.style.use('ggplot')

# 绘制K的个数与GSSE的关系

plt.plot(K, TSSE, 'b*-')

plt.xlabel('簇的个数')

plt.ylabel('簇内离差平方和之和')

# 显示图形

plt.show()

from sklearn import preprocessing

# 数据标准化处理

X = preprocessing.minmax_scale(players[['得分','罚球命中率','命中率','三分命中率']])

# 将数组转换为数据框

X = pd.DataFrame(X, columns=['得分','罚球命中率','命中率','三分命中率'])

k_SSE(X, 15)

# 构造自定义函数,用于绘制不同k值和对应轮廓系数的折线图

def k_silhouette(X, clusters):

K = range(2,clusters+1)

# 构建空列表,用于存储个中簇数下的轮廓系数

S = []

for k in K:

from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters=k)

kmeans.fit(X)

labels = kmeans.labels_

# 调用字模块metrics中的silhouette_score函数,计算轮廓系数

from sklearn.metrics import silhouette_score

S.append(silhouette_score(X, labels, metric='euclidean'))

# 中文和负号的正常显示

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

plt.rcParams['axes.unicode_minus'] = False

# 设置绘图风格

plt.style.use('ggplot')

# 绘制K的个数与轮廓系数的关系

plt.plot(K, S, 'b*-')

plt.xlabel('簇的个数')

plt.ylabel('轮廓系数')

# 显示图形

plt.show()

k_silhouette(X, 10)

# 将球员数据集聚为3类

from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters = 3)

kmeans.fit(X)

# 将聚类结果标签插入到数据集players中

players['cluster'] = kmeans.labels_

# 构建空列表,用于存储三个簇的簇中心

centers = []

for i in players.cluster.unique():

centers.append(players.loc[players.cluster == i,['得分','罚球命中率','命中率','三分命中率']].mean())

# 将列表转换为数组,便于后面的索引取数

centers = np.array(centers)

# 绘制散点图

sns.lmplot(x = '得分', y = '命中率', hue = 'cluster', data = players, markers = ['^','s','o'],

fit_reg = False, scatter_kws = {'alpha':0.8}, legend = False)

# 添加簇中心

plt.scatter(centers[:,0], centers[:,2], c='k', marker = '*', s = 180)

plt.xlabel('得分')

plt.ylabel('命中率')

# 图形显示

plt.show()

res0Series = pd.Series(kmeans.labels_)

res0 = res0Series[res0Series.values == 0]

print(players.iloc[res0.index])

res0Series = pd.Series(kmeans.labels_)

res0 = res0Series[res0Series.values == 1]

print(players.iloc[res0.index])

res0Series = pd.Series(kmeans.labels_)

res0 = res0Series[res0Series.values == 2]

print(players.iloc[res0.index])

把球员分成三种类别,可以对比球员的价值,在实际应用中可以作为参考,帮助球队进行人才的挑选。