1 import pandas as pd 2 import numpy as np 3 import matplotlib.pyplot as plt 4 from sklearn.cluster import KMeans 5 6 7 def build_data(): 8 """ 9 構建數據 10 :return:原始數據 11 """ 12 nba_data = pd.read_excel("./nba_data.xlsx") 13 14 return nba_data 15 16 17 def deal_data(nba_data): 18 """ 19 數據處理 20 :param nba_data: 待處理數據 21 :return: 數據處理之后的nba_data 22 """ 23 # 1、篩選相關特征 24 nba_data = nba_data.loc[:, ["時間", "助攻", "得分"]] 25 # 2、檢測缺失值 26 res_null = pd.isnull(nba_data).sum() 27 print("缺失值檢測結果:\n", res_null) 28 # 3、處理缺失值 29 # 將 時間列的 " " 先轉化為np.nan類型,再進行缺失值處理 30 nba_data.replace(" ", np.nan, inplace=True) 31 # print("轉化之后缺失值檢測結果:", pd.isnull(nba_data).sum()) 32 # 對缺失值進行 處理---??? 33 # (1)刪除---會損失大量數據 34 # (2)拉格朗日插值---時間可能會插上負值,有的數據還特別大 35 # (3)填充---均值、眾數、中位數、上下鄰居 36 # 計算眾數 37 mode = nba_data.loc[:, "時間"].mode()[0] 38 # 填充 39 nba_data.loc[:, "時間"].fillna(value=mode, inplace=True) 40 print("轉化之后缺失值檢測結果:", pd.isnull(nba_data).sum()) 41 # 4、構建最終的特征 42 # 檢測各個特征的數據類型 43 res_dtype = nba_data.dtypes 44 print("各個特征的數據類型:\n", res_dtype) 45 # 46 # # 將時間轉化為float 類型 47 nba_data.loc[:, "時間"] = nba_data.loc[:, "時間"].astype(np.float64) 48 # # 49 # print("數據類型轉化之后的結果:\n", nba_data.dtypes) 50 nba_data.loc[:, "得分/分鍾"] = nba_data.loc[:, "得分"] / nba_data.loc[:, "時間"] 51 nba_data.loc[:, "助攻/分鍾"] = nba_data.loc[:, "助攻"] / nba_data.loc[:, "時間"] 52 53 nba_data = nba_data.loc[:, ["得分/分鍾", "助攻/分鍾"]] 54 print("特征構建之后的結果:\n", nba_data) 55 # 5、處理異常值---數據正常不需要異常值處理 56 print("分鍾得分的最大值、最小值", nba_data.loc[:, "得分/分鍾"].max(), nba_data.loc[:, "得分/分鍾"].min()) 57 print("助攻得分的最大值、最小值", nba_data.loc[:, "助攻/分鍾"].max(), nba_data.loc[:, "助攻/分鍾"].min()) 58 # 6、標准化數據---量級相差不大,不需要標准化 59 60 return nba_data 61 62 63 def km_fit(nba_data, k): 64 """ 65 nba球員聚類 66 :param nba_data: 數據 67 :param k: 聚類的類別數目 68 :return: 69 """ 70 # 1、創建算法實例 71 km = KMeans(n_clusters=k) 72 # 2、訓練數據 73 km.fit(nba_data) 74 # 3、預測 75 y_predict = km.predict(nba_data) 76 77 # 獲取聚類中心 78 center = km.cluster_centers_ 79 80 return y_predict, center 81 82 83 def show_res(nba_data, y_predict, center): 84 """ 85 結果展示 86 :param nba_data: 數據 87 :param y_predict: 預測值 88 :param center: 聚類中心 89 :return: None 90 """ 91 # 1、創建畫布 92 plt.figure() 93 # 2、繪圖 94 color_list = ["r", "g", "pink", "y", "k"] 95 # 散點圖 96 for i in range(nba_data.shape[0]): 97 plt.scatter(nba_data[i, 0], nba_data[i, 1], c=color_list[y_predict[i]]) 98 99 print("nba_data: ", nba_data) 100 print("nba_data.shape[0]: ", nba_data.shape[0]) 101 print("nba_data[i, 0]: ", nba_data[i, 0]) 102 print("nba_data[i, 1]: ", nba_data[i, 1]) 103 104 # 繪制標注 105 plt.plot(center[:, 0], center[:, 1], "bx", markersize=12) 106 # 3、展示 107 plt.show() 108 109 110 def main(): 111 """ 112 主函數 113 :return: 114 """ 115 # 1、加載數據 116 nba_data = build_data() 117 print("nba_data:\n", nba_data) 118 print("nba_data 的列索引:\n", nba_data.columns) 119 120 # 2、數據處理 121 nba_data = deal_data(nba_data) 122 123 # 3、聚類分析 124 # 確定聚類類別數目 125 k = 5 126 y_predict, center = km_fit(nba_data, k) 127 128 print("預測值:\n", y_predict) 129 print("聚類中心:\n", center) 130 131 # 4、結果展示 132 show_res(nba_data.values, y_predict, center) 133 134 135 if __name__ == '__main__': 136 main()