商業智慧期末報告 === ###### tags: `assignment` 106423058 黃晉豪 107423031 楊竣憲 ## 第一節 - 定義商業問題 《英雄聯盟》(League of Legends,LoL)是一款多人線上戰術遊戲,在一局遊戲中,5~10位玩家各自操控具有獨特能力的「英雄」與電腦AI或真人玩家控制的英雄對戰,遊戲的勝利目標是要摧毀對方的最後基地。 根據[官方公布數據](https://medium.com/@tingcc/%E9%81%8A%E6%88%B2%E5%B8%82%E5%A0%B4-%E6%AF%8F%E5%B9%B4%E9%83%BD%E5%9C%A8%E9%81%8E%E6%B0%A3%E7%9A%84%E8%8B%B1%E9%9B%84%E8%81%AF%E7%9B%9Flol-%E5%8F%88%E6%9B%B4%E9%81%8E%E6%B0%A3%E4%BA%86%E5%97%8E-6de0246445c),至2015年7月為止,遊戲的月活躍(每個月至少玩一次)超過1億名玩家,而每天都玩的玩家超過2700萬,高峰時段甚至有超過750萬人同時在線上,《英雄聯盟》在玩家間享有的高人氣顯而易見。 《英雄聯盟》自2011年起,不僅有舉辦世界賽、各國區域賽,且每年的玩家人數不停增加,在2019年的世界大賽總決賽中,同時有4400萬線上觀看的觀眾,以16種語言在20個平台直播,由此可知《英雄聯盟》在電子競技的領域裡的地位、影響力、商業價值。 研究獲勝的關鍵因素 ,讓一般玩家與電競選手能了解自己的優勝劣勢 進而規劃完整的策略 讓每位玩家都能改善自己的勝率,吸引更多的玩家參與其中,而不是讓玩家覺得遊戲難度太高, 慢慢地退出此款遊戲。 ## 第二節 - 了解資料特性 我們使用Kaggle通過 Rito Gaming(遊戲官方)所收集來的數據,資料來源 為:(https://www.kaggle.com/bobbyscience/league-of-legends-diamond-ranked-games-10-min) ,我們針對資料集進行一連串前處理後,再將資料集切分為訓練與驗證兩部分(細節於後續章節說明),本節主要說明資料集中原始數據(raw data)的欄位、類別、特性等進行初步理解,並簡單描述資料意義,找出可能的影響主題的因素。 表 (一 )將說明此資料集中,各項資料屬性的意義,型態及各屬性值: | 欄位名稱 | 資料意義 | 資料型態 | | -------- | -------- | -------- | | gameId | 編號 | int | | blueWins | 藍方勝利與否(1 or 0) | int | | blueWardsPlaced | 藍方布置的哨兵數量 | int | | blueWardsDestroyed | 藍方摧毀紅方的哨兵數量 | int | | blueFirstBlood | 藍方取得開場第一個擊殺與否(1 or 0) | int | | blueKills | 擊殺紅方玩家次數 | int | | blueDeaths | 藍方玩家死亡次數 | int | | blueAssists | 藍方玩家助攻擊殺次數 | int | | blueEliteMonsters | 藍方殺死的中立高階怪物數量(以下兩者相加) | int | | blueDragons | 藍方殺死的飛龍數 | int | | blueHeralds | 藍方殺死的諭示者數 | int | | blueTowersDestroyed | 藍方摧毀紅方的防禦塔數量 | int | | blueTotalGold | 藍方整場遊戲獲得的金錢 | int | | blueAvgLevel | 藍方腳色的等級 | int | | blueTotalExperience | 藍方整場遊戲獲得的經驗 | int | | blueTotalMinionsKilled | 藍方殺死的小兵數量 | int | | blueTotalJungleMinionsKilled | 藍方殺死的中立小兵數量 | int | | blueGoldDiff | 藍方與紅方的金錢差異 | int | | blueExperienceDiff | 藍方與紅方的經驗差異 | int | | blueCSPerMin | 藍方每分鐘殺死的小兵數量 | int | | blueGoldPerMin | 藍方每分鐘獲得的金錢數量 | int | | ------ | ------ | ----- | | 之後為紅方的數據 | 格式皆與上半部分相似 | 此處不另外顯示 | | ------ | ------ | ----- | ## 第三節 - 資料前處理 - 找尋空值: 在開始分析資料之前先查看該資料集是否含有空值。 ```python= df.info() ``` ![](https://i.imgur.com/lEsbork.png) 該資料集中無空值,因此無須去除空值 - 資料合併:在資料中有些欄位與所要分析之結果無關(如gameId),以及將重複的欄位進行刪除。 ```python=+ cols = ['gameId', 'redFirstBlood', 'redKills', 'redEliteMonsters', 'redDragons','redTotalMinionsKilled', 'redTotalJungleMinionsKilled', 'redGoldDiff', 'redExperienceDiff', 'redCSPerMin', 'redGoldPerMin', 'redHeralds', 'blueGoldDiff', 'blueExperienceDiff', 'blueCSPerMin', 'blueGoldPerMin', 'blueTotalMinionsKilled'] df_clean = df_clean.drop(cols, axis = 1) ``` ```python=+ df_clean.info() ``` ![](https://i.imgur.com/vFHTIuL.png) - 選取特徵: 我們想了解那些特徵對於贏得遊戲較相關,因此我們將探討各項特徵間以及各項特徵與遊戲結果(勝利與否)之關係。 ```python=+ g = sns.PairGrid(data=df_clean, vars=['blueKills', 'blueAssists', 'blueWardsPlaced', 'blueTotalGold'], hue='blueWins', size=3, palette='Set1') g.map_diag(plt.hist) g.map_offdiag(plt.scatter) g.add_legend(); ``` ![](https://i.imgur.com/QF5dMqP.png) 查看藍隊各項特徵間的關係,可以發現有許多多重共線性特徵,因此我們接著查看各特徵間的相關係數。 ```python=+ plt.figure(figsize=(16, 12)) sns.heatmap(df_clean.drop('blueWins', axis=1).corr(), cmap='YlGnBu', annot=True, fmt='.2f', vmin=0); ``` ![](https://i.imgur.com/tHKX83k.png) 我們可以發現許多特徵對於贏得遊戲都存在高度相關的關係。 基於上述結果,我們對資料集做進一步的處理。 ```python=+ cols = ['blueAvgLevel', 'redWardsPlaced', 'redWardsDestroyed', 'redDeaths', 'redAssists', 'redTowersDestroyed', 'redTotalExperience', 'redTotalGold', 'redAvgLevel'] df_clean = df_clean.drop(cols, axis=1) ``` 接著我們去除掉相關係數較低的特徵。 ```python=+ corr_list = df_clean[df_clean.columns[1:]].apply(lambda x: x.corr(df_clean['blueWins'])) cols = [] for col in corr_list.index: if (corr_list[col]>0.2 or corr_list[col]<-0.2): cols.append(col) cols ``` ![](https://i.imgur.com/pVWYeC0.png) 最後將資料以直方圖進行呈現,可得以下結果。 ```python=+ df_clean.hist(alpha = 0.7, figsize=(12,10), bins=5); ``` ![](https://i.imgur.com/xrHEQ1r.png) ## 第四節 - 建立模型與評估 - 首先將資料集切分為訓練、測試集。 ```python=+ from sklearn.preprocessing import MinMaxScaler from sklearn.model_selection import train_test_split X = df_clean y = df['blueWins'] scaler = MinMaxScaler() scaler.fit(X) X = scaler.transform(X) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - 樸素貝葉斯模型(Naive Bayes) ```python=+ from sklearn.naive_bayes import GaussianNB from sklearn.metrics import accuracy_score clf_nb = GaussianNB() clf_nb.fit(X_train, y_train) pred_nb = clf_nb.predict(X_test) acc_nb = accuracy_score(pred_nb, y_test) print(acc_nb) ``` ![](https://i.imgur.com/1H22eMX.png) - 決策樹(Decision Tree) ```python=+ from sklearn import tree from sklearn.model_selection import GridSearchCV tree = tree.DecisionTreeClassifier() grid = {'min_samples_split': [5, 10, 20, 50, 100]}, clf_tree = GridSearchCV(tree, grid, cv=5) clf_tree.fit(X_train, y_train) pred_tree = clf_tree.predict(X_test) acc_tree = accuracy_score(pred_tree, y_test) print(acc_tree) ``` ![](https://i.imgur.com/y4k638W.png) - 隨機森林(Random Forests) ```python=+ from sklearn.ensemble import RandomForestClassifier rf = RandomForestClassifier() grid = {'n_estimators':[100,200,300,400,500], 'max_depth': [2, 5, 10]} clf_rf = GridSearchCV(rf, grid, cv=5) clf_rf.fit(X_train, y_train) pred_rf = clf_rf.predict(X_test) acc_rf = accuracy_score(pred_rf, y_test) print(acc_rf) ``` ![](https://i.imgur.com/TOySTRu.png) - 邏輯斯回歸(Logistic Regression) ```python=+ from sklearn.linear_model import LogisticRegression lm = LogisticRegression() lm.fit(X_train, y_train) # get accuracy score pred_lm = lm.predict(X_test) acc_lm = accuracy_score(pred_lm, y_test) print(acc_lm) ``` ![](https://i.imgur.com/y6YQIv1.png) - KNN ```python=+ from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier() grid = {"n_neighbors":np.arange(1,100)} clf_knn = GridSearchCV(knn, grid, cv=5) clf_knn.fit(X_train,y_train) pred_knn = clf_knn.predict(X_test) acc_knn = accuracy_score(pred_knn, y_test) print(acc_knn) ``` ![](https://i.imgur.com/LvbSPPx.png) - 各模型的結果比較: ```python=+ data_dict = {'Naive Bayes': [acc_nb], 'DT': [acc_tree], 'Random Forest': [acc_rf], 'Logistic Regression': [acc_lm], 'K_nearest Neighbors': [acc_knn]} df_c = pd.DataFrame.from_dict(data_dict, orient='index', columns=['Accuracy Score']) print(df_c) ``` ![](https://i.imgur.com/pGTMG26.png) 從模型訓練結果,我們可以發現邏輯斯回歸和隨機森林的預測結果較佳。 ## 第五節 - 部署 隨著近年網路的快速發展,不管是實況直播、youtuber、社群媒體等等許多相關的網路產業都開始興起,其中電競比賽及相關活動所帶來的收益及影響力更是逐漸上升。《英雄聯盟》在 2017的世 界賽中官方所提供的獎金只有 225萬美金,但卻靠著販賣周邊而貢獻比賽的金 額卻高達 235萬美金,反而比官方所提供的獎金高出 10萬美金,由此可見不論是遊戲玩家還是觀眾對於賽事的參與度及貢獻度都是非常可觀的。 除此之外,本研究之所以選擇《英雄聯盟》作為分析題目是因為在2012年,正是由台灣在世界賽中取得冠軍,這件事也使得當時該遊戲在台灣帶動了整個相關產業的風潮。直到今日,《英雄聯盟》在台灣依舊是最多年輕人接觸的一款線上遊戲。 因此我們希望根據現有資料集所建置出來的模型能夠用玩家過去的遊戲紀錄來預測此玩家的勝率為何,提供不管是對於一般、職業玩家或是遊戲公司都是非常有用的資訊。再者,我們也嘗試透過多種演算法找出特徵與勝率關係,並試圖找出影響勝率的關鍵參數為何,不僅提供給每位玩家能夠改善自己勝率的關鍵因子,也更能夠提升玩家的黏著度和增進玩家的技術。