英雄聯盟是一款多人線上遊戲,擁有百萬人休閒與專業玩家。這是一款 5 對 5 展開激烈角逐的遊戲,玩家為了奪取對方的基地而戰。很顯然,如果你選擇強勢的英雄,那麼在同等水平玩家的比賽中獲勝的可能性就更大。
如果你希望提升遊戲中競爭激烈的排名,那麼想不想試試看利用機器學習分析,在下一場遊戲中根據統計結果做決定?想不想試試看一邊享受自己喜歡的遊戲,一邊學習科技行業流行的機器學習技術?
在我們看來,機器學習是任何人都可以使用的工具,而不僅僅面向擅長數學及掌握了程式設計技術的資料科學家。這些知識都不是必需的,你只需要瞭解排名模型的概念即可。
排名是機器學習的一種應用,它根據引數(比如你在英雄聯盟遊戲中的輸贏)對資料進行排序。我們可以根據資料的排序,預測新資料產生的結果。
換句話說,如果給出一組提莫出場的比賽,並根據輸贏對比賽進行排名,那麼由於每一場比賽都有提莫,該模型就會認為提莫這個英雄是否出場和比賽輸贏之間的關聯性很低。這意味著提莫是否出場,對你的輸贏幾乎沒有影響,因為他與贏得比賽之間的關係不大。因此,如果你要求模型預測自己能否贏得此次有提莫出場的比賽,它就會要求你提供更多資訊,並且會做出錯誤的預測。
(CSDN付費下載自視覺中國)
目標本文無意抹黑提莫,我們希望透過正確引導你對英雄聯盟的興趣,從而引發你對機器學習的興趣。如果我們能教會遊戲玩家機器學習的概念(比如排名模型是什麼),你就能掌握資料驅動分析的力量,並在專案中找到其他應用AI的方法。
因此,在本文中,我們希望透過機器學習排名模型解決下列問題:
哪些英雄能增加我贏得白金或鑽石比賽的勝率?換句話說,就我的水平而言,選擇哪些英雄能夠幫助我提升排名?
哪些因素對於比賽勝負的影響最大?
在十分鐘內,使用某個英雄,贏得一場鑽石比賽並獲得相應金幣的機率有多大?
注意:我的資料集採用了較高水平的遊戲,因為我希望讀者能認真閱讀本文。如果你想了解如何使用拳頭遊戲 API,並生成適合自己水平的資料集以獲得更準確的分析結果,可以檢視我的 GitHub(https://github.com/witchfelicia/LoL-dataset)。
資料集
大多數資料科學家都知道,優秀的模型源自強力且適合的資料集。為了撰寫這篇指南,我們費了九牛二虎之力解析了拳頭遊戲 API 返回的結果,並謹慎地選擇了一組白金與鑽石級別的遊戲資料,其中包含 5000 多行 14 列的資料。
關於如何透過公開的英雄聯盟排位賽資料,生成這套資料集的詳細資訊,請參見我的 GitHub。
總的來看,這套資料集包含 5000 多行,每一行資料包含一位玩家在白金或鑽石級別參加排位賽的資訊。一共 14 列,包括玩家的 KDA、pick和ban的英雄、是否有隊友掛機、10分鐘內贏得的金幣、遊戲結束時的金幣,以及比賽的勝負。
在收集到這些資料以後,下一步我們需要準備訓練模型的資料。
資料清理下面,我們來一場資料“大清洗”。資料清理是機器學習流程中的一個步驟,目的是降低資料中的噪聲,為訓練機器學習模型準備一套整潔、精確的資料。也就是說,大多數時候,原始資料都會包含一些空值、不相干的行或列,如果放任不管,那麼模型在學習這些資料產生的結果並分析走向趨勢時,就會倍感困惑。對於資料清理以及下一步(特徵工程)的工作來說,最大的難題是沒有特定的公式或順序指導我們完成這項工作,因此許多新手都會被勸退。就像英雄聯盟一樣,學習曲線非常陡峭,但是相信自己一定能行!在學習機器學習的各個步驟時,請不斷思考這樣一個問題:“我們為什麼要執行這個操作?”,這樣相信很快你就能學會。下面,介紹一下我們利用拳頭遊戲 API 收集資料的過程,我們隨機選擇了一個白金或鑽石級別的玩家 A 的資料,並生成他們最近 20 場排位賽的資料。然而,如果A的某一名隊友B也是我們的收集物件的25位玩家之一,那麼包含玩家A和B的隊友及對手的資料就會被收集兩次。重複的資料會導致預測結果出現偏差,因為會給模型留下一種印象:某個事件的發生頻率更高。想象一下,如果我們重複記錄亞索一招必殺技贏得的比賽,那麼模型會如何預測亞索玩家的勝率。我們可以刪除重複的資料,如果玩家 A 和 B 的比賽重疊,那麼我們就可以刪除相同的資料,即同一批玩家出現在同一場比賽中,而且是同一夥人贏得了勝利。有時,我們並不確定哪些需要清理,遇到這種情況,我們可以看一看每一列,查詢包含空值、非法值或錯誤值的資料,並將它們過濾出去。
舉個例子,比賽中有 5 個位置,但是特徵“position”(位置)中卻包含第 6 個值:Invalid(無效),這是因為拳頭遊戲 API 無法判斷某位玩家打的是哪個位置。
如果我們保留“position”列中的“Invalid”,那麼模型就會以為玩家可以選擇“Invalid”這個位置。我們當然不希望模型在不準確的值上訓練,因為這會降低模型的準確度。
所以,我們使用過濾(filter)操作,確保僅保留玩家位置確定的資料。
此外,我們還有一列表示玩家在比賽進行到 10 分鐘時積攢的金幣數量,該列包含 35 個“0”值。不幸的是,這 35 行“ten_min_lane_opponent_gold”列為空值的資料必須過濾掉,因為這些資料不完整,會導致預測結果不準確。
回顧一下我們構建模型的初衷,我們希望找出玩家選擇哪個英雄贏得比賽的機率最大。因此,我們必須移除不相關的列。後面我們還會重複這個步驟,因為在提取相關資訊時,某些列也會被移除。
特徵工程該步驟的重點是將現有資訊轉化成明確的有效特徵,因此我們來新增一些列,告訴模型決定排名賽中的優秀玩家的因素有哪些。除此之外,該步驟會進一步過濾資料,並移除不相關的列。
判斷某位玩家的表現是否優異的一種方法是,觀察他們能否在 10 分鐘內擊敗自己的對線對手,這是比賽的關鍵轉折點。雖然這並不能保證他們一定能贏,但為他們帶來了優勢,因為接下來他們就能夠利用自己的力量輔助隊友,並向敵人施壓,而這些都能影響他們的成敗。
由於團隊合作很難界定和測量,所以我們簡單地加一個標籤(列“beat_lane_opponent”),表示玩家是否擊敗了自己的對線對手並佔據了優勢(布林值)。
接下來,我們將列“ten_min_gold”(十分鐘內獲得的金幣)換成一個布林值列,這樣就可以將金幣數量(範圍為2,223~6,075,非常精確的數值)簡化成“True”或“False”,以表明這位玩家是否超過了對手。對於模型來說,這個值更容易理解,而且也有助於決定哪些因素會影響到最終的結果。
最後,我們再加一個比較列,比較一下兩個列,如果超過了對手就返回“True”。
可能有些人非常熟悉 API 與 JSON,我們知道有時我們會收到 JSON 資料,需要編寫程式碼挖掘相關的資料。如果你想知道為何人們以這種格式儲存資料,可以瞭解一下 JSON 資料在儲存輔助資訊方面的實際用途。
在本文中,我們感興趣的是列“challenges”中包含的哪些資料能夠幫助我們實現目標。下面的例子展示了一行 JSON 資料所包含的資訊:
由於我們希望預測某個英雄是否強大,而且有出眾的表現,所以我們只關心“teamDamagePercentage”(團隊傷害比例)。
下面,我們需要一些數學演算。主要的評估因素是與團隊成員相比,你的金幣貢獻率是多少,我們稱之為“gold percentage”(金幣比例),計算公式如下:
為了計算這個值,首先我們需要聚合(即針對一組資料執行操作)比賽與團隊,求出團隊獲得的金幣總數。這個操作稱為聚合總和,詳情請參見這裡(https://www.mage.ai/blog/feature-engineering-total-sum)。
我們透過對列“gold”執行聚合操作,求出團隊的總金幣數“team_gold”。
下面,我們透過相同的操作,求出列“ten_min_gold”(十分鐘內獲取的金幣)的總和,並儲存到列“team_ten_min_gold”(十分鐘內團隊獲取的金幣)中。
每位玩家獲得的金幣數除以團隊總金幣數,就可以求出“gold percentage”(金幣比例)。
與之類似,“ten_min_gold”(十分鐘內獲取的金幣)除以“team_ten_min_gold”(十分鐘內團隊獲取的金幣),就可以求出每位玩家在 10 分鐘內貢獻金幣的比例,即“gold_ten_min_percentage”(10 分鐘內的金幣比例)。
最後,我們利用“gold percentage”(金幣比例)來觀察某位玩家在比賽的過程中做出的貢獻是否在增長。如果某位玩家在 10 分鐘內為金幣比例做出了巨大貢獻,那麼他們是否利用這筆資金幫助隊友取得了勝利?或者這筆資金“打了水漂”?
為了觀察玩家貢獻的金幣比例增長了還是下降了,我們求“gold_ten_min_percentage”(10 分鐘內的金幣比例)與“gold percentage”(金幣比例)之差,我稱這個特徵為“scalability”(成長性)。
在前面的介紹中,我們曾提及在提取完資訊後,我們會移除一些列,也會為了更好地彙總資料而新增一些列。
最終,我們一共有 11 列,分別如下:
● bans:禁用的英雄
● beat_lane_opponent:是否擊敗對線對手
● deaths:死亡次數
● gold:金幣數量
● gold_percentage:金幣比例
● gold_ten_min_percentage:10 分鐘內的金幣比例
● kills:擊殺數量
● picks:選擇的英雄
● scalability:成長性
● team_damage_percentage:團隊傷害比例
● win:輸贏
到此為止,資料的準備工作就完成了,下面我們開始訓練模型。
模型訓練回顧一下,排名模型需要完成的工作:
● 評估的是哪個英雄(列“picks”);
● 在白金和鑽石級別的比賽中獲勝的最大機率;
● 按照獲勝的機率從大到小排列資料,根據每位英雄獲勝的次數,給他們打分;
● 根據排序列表中每位英雄的相對位置,預測選擇某個英雄能否贏得一場排名比賽。
上述內容看起來可能有點不太好理解,我們建立了一個視覺化工具,幫助你熟悉排名及其過程:
訓練模型指的是,模型接收我們精心加工過的資料,然後分割出一批資料,學習如何預測當玩家選擇某個英雄並達成特定目標後能否贏得比賽。
為了公平地計算該模型的準確度,我們使用90%的資料來教模型如何預測哪些英雄能贏得比賽,而其餘的10%則用於測試模型的預測是否正確。
如果你想了解如何分割訓練資料與測試資料,請參見“K折交叉驗證”的相關課程。
評估到此為止,我們的模型已經訓練好了,而且我們能夠解釋模型給出的結果。一般我們會使用準確率、精確率和召回率來評估某個模型的預測結果是否準確。然而,由於這些指標是通用的,所以我們還會使用 SHAP 值來分析每一列對最後結果的影響。
這一切都是為了在下一個再訓練步驟中理解模型,並提升模型的效能。
我們的模型的效能評估結果如下:
接下來,我們需要進行一系列的測試。在測試階段,我們需要透過以下測試樣本來評估上述指標:
● 在我們的測試中,玩家選擇了瑟雷西,最後準確率為 82%,這意味著該模型正確預測瑟雷西玩家結果的成功率為 82%。包括他們輸掉的遊戲。
● 精確率指的是模型正確預測瑟雷西玩家獲勝的機率。
● 召回率為 80%,指的是在我們的測試資料中,如果有 5 次瑟雷西玩家獲勝,則模型可以識別出其中 4 次。
此外,通常我們會利用這三個指標構建一個混淆矩陣。
雖然上述矩陣有點難以理解,但我敢肯定數學科學家一定能看懂。
為了確定哪些列對預測結果的影響最大,我們在頁面“Top features”(頂級特徵)上展示了各個列與預測結果之間的關係。
從上述列表中,我們可以看出:
● 玩家是否能夠擊敗對線對手對比賽的結果並沒有實質性的影響,因為列“beat_lane_opponent”(擊敗對線對手)並沒有出現在該列表中。
● 對比賽結果影響最大的列實際上是“deaths”(死亡次數),表明減少自己的死亡次數就可以增加獲勝的機率,這甚至超出了升級技能。
● 在我們的測試集中,每個英雄只有1~2個預測結果,這說明 5000 行的資料不足以預測英雄聯盟 140 多位英雄。
透過頂級特徵列表,我們還可以看出哪些列對預測結果基本沒有影響。既然“bans”(禁用英雄)、“beat_lane_opponent”(擊敗對線對手)和“team_damage_percentage”(團隊傷害比例)並沒有出現在上述列表中,我們可以在重新訓練的時候排除這些列,從而改進我們的排名模型。
部署 API如果你很好奇一定的金幣數量和死亡次數是否會影響獲取機率,可以嘗試在頁面“Predict > Playground”中部署這個 API,並自定義預測。
在下方的動圖中,我們輸入了“4次死亡”和“7000 金幣”,然後想看一看哪個英雄最有可能取勝的列表。如你所見,在這個死亡次數和金幣數量下,英雄巴德、諾提勒斯、阿利斯塔可以提升你獲勝的機率。
你覺得在經過預處理、訓練和評估後,我們的排名模型能夠回答本文開頭提出的問題了嗎?
問題:哪些英雄能提升我贏得白金或鑽石比賽的機率?
答案:儘管我們沒有足夠的資料,還無法自信地給出結果,但根據1~2個測試結果,我們姑且可以認為:
● 選擇賽特、勒布朗、菲奧娜、拉克絲、慎和賈克斯能夠提高獲勝的機率;
● 選擇悠米、薇可絲和亞索獲勝的機率偏低。
問題:哪些因素對於比賽勝負的影響最大?
答案:死亡次數和金幣數量對獲勝的影響最大,所以如果你想贏得鑽石或白金級別的遊戲,那麼就不要送人頭,還要多賺金幣。
問題:在十分鐘內,使用某個英雄,贏得一場鑽石比賽並獲得相應金幣的機率有多大?
答案:儘管我們無法根據英雄的“picks”做出預測,但你可以透過上述頁面“Predict > Playground”,嘗試不同的輸入(如擊殺次數、金幣數和死亡次數),看看在這些統計資料下哪些英雄獲勝的機率最高。
例如,根據上述結果,在 3 次死亡、7000 金幣會 1 次擊殺的情況下,最有可能取勝的英雄為:賈克斯、路西恩、卡爾薩斯。
原文連結:https://www.mage.ai/blog/league-of-legends-ranking-guide
END
《新程式設計師001-004》全面上市,對話世界級大師,報道中國IT行業創新創造