1. 程式人生 > >Udacity資料分析(進階試學)-五王之戰分析

Udacity資料分析(進階試學)-五王之戰分析

概覽

五王之戰(War of the Five Kings)是著名嚴肅奇幻小說《冰與火之歌》中的著名內戰。本專案使用了五王之戰期間的戰爭的資料集,它是所有戰鬥的大集合。

五王之戰分析 - 冰與火之歌

簡介

五王之戰(War of the Five Kings)是著名嚴肅奇幻小說《冰與火之歌》中的著名內戰。這是一場規模空前、波及七大王國的內亂。顧名思義,前後共有五人在戰爭中稱王:喬佛裡、史坦尼斯、藍禮均聲稱自己是鐵王座的合法繼承人。除此之外,羅柏·史塔克被北境眾封臣推選為北境之王,巴隆·葛雷喬伊亦再度掀起獨立大旗,欲擺脫鐵王座的統治,自稱為鐵群島之王。
本資料集(battles.csv)包含了五王之戰期間的戰爭,它是所有戰鬥的大集合。該資料是Kaggle中

Game of Thrones的一部分。

資料中的變數含義解釋:

name: 戰爭的名稱,字元變數。
year: 戰爭發生的年份,數值變數。
battle_number: 本資料中的unique id,對應每一場獨立的戰役,數值變數。
attacker_king: 攻擊方的國王,"/"表示了國王的更換。例如:"Joffrey/Tommen Baratheon"意味著Tomen Baratheon繼承了Joffrey的王位,分類變數。
defender_king: 防守方的國王,分類變數。
attacker_1: 攻擊方將領,字元變數。
attacker_2: 攻擊方將領,字元變數。
attacker_3: 攻擊方將領,字元變數。
attacker_4: 攻擊方將領,字元變數。
defender_1: 防守方將領,字元變數。
defender_2: 防守方將領,字元變數。
defender_3: 防守方將領,字元變數。
defender_4: 防守方將領,字元變數。
attacker_outcome: 從攻擊方角度來看的戰爭結果,分別有:win, loss, draw,分類變數。
battle_type: 戰爭的類別。pitched_battle: 雙方軍隊在一個地點相遇並戰鬥,這也是最基本的戰爭類別;ambush: 以隱身或詭計為主要攻擊手段的戰爭;siege: 陣地戰;razing: 對未設防位置的攻擊。分類變數。
major_death: 是否有重要人物的死亡,二進位制變數。
major_capture: 是否有重要人物的被捕,二進位制變數。
attacker_size: 攻擊方力量的大小,並未對騎兵、步兵等士兵種類有所區分,數值變數。
defender_size: 防守方力量的大小,並未對騎兵、步兵等士兵種類有所區分,數值變數。
attacker_commander: 攻擊方的主要指揮官。指揮官的名字中並沒有包含頭銜,不同的指揮官名字用逗號隔開,字元變數。
defender_commander: 防守方的主要指揮官。指揮官的名字中並沒有包含頭銜,不同的指揮官名字用逗號隔開,字元變數。
summer: 戰爭是否發生於夏天,二進位制變數。
location: 戰爭發生的地點,字元變數。
region: 戰爭發生的地域,包括:Beyond the Wall, The North, The Iron Islands, The Riverlands, The Vale of Arryn, The Westerlands, The Crownlands, The Reach, The Stormlands, Dorne,分類變數。
note: 註釋,字元變數。

提出問題

1.戰役型別和攻守雙方戰力對比與戰役勝率之間的關係?

2.哪位好戰分子出場率最高?

資料評估和清理

# TO DO: load pacakges
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import *
import seaborn as sns
sns.set_style("white")
%matplotlib inline
# TO DO: load the dataset
battles=pd.read_csv('battles.csv')
pd.options.display.max_columns=1000 #顯示全部列 battles.sample(5)

在這裡插入圖片描述

# TO DO: check the dataset general info
battles.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 38 entries, 0 to 37
Data columns (total 25 columns):
name                  38 non-null object
year                  38 non-null int64
battle_number         38 non-null int64
attacker_king         36 non-null object
defender_king         35 non-null object
attacker_1            38 non-null object
attacker_2            10 non-null object
attacker_3            3 non-null object
attacker_4            2 non-null object
defender_1            37 non-null object
defender_2            2 non-null object
defender_3            0 non-null float64
defender_4            0 non-null float64
attacker_outcome      37 non-null object
battle_type           37 non-null object
major_death           37 non-null float64
major_capture         37 non-null float64
attacker_size         24 non-null float64
defender_size         19 non-null float64
attacker_commander    37 non-null object
defender_commander    28 non-null object
summer                37 non-null float64
location              37 non-null object
region                38 non-null object
note                  5 non-null object
dtypes: float64(7), int64(2), object(16)
memory usage: 7.5+ KB
#檢查各列缺失值大概數量
battles.isnull().sum().plot(kind="barh",color='grey',figsize=(10, 6.8));

在這裡插入圖片描述

#檢視戰爭結果缺失值行的內容
battles[battles.attacker_outcome.isnull()]

在這裡插入圖片描述

# 檢查戰役是否存在重複值
battles.battle_number.is_unique
True

從上面可以看出,資料集整體缺失值較多,但大部分無關緊要(如進攻方或防禦方的將領、國王中的缺失值可以看做未參加戰役,可以改為計算參與人數)。根據後續分析結果再進行篩選及調整。

資料探索分析

首先開始對第一個問題進行探索哪種戰役型別的勝率較高?

#生成1列count用於統計勝率及次數,利用透視表整理戰役型別與勝率的關係
battles['count']=1
battletype=battles.pivot_table('count',index='battle_type',columns='attacker_outcome',aggfunc=sum,fill_value=0).reset_index()
#計算勝率及失敗率
battletype['win_rate']=battletype.win/(battletype.win+battletype.loss)
battletype['loss_rate']=battletype.loss/(battletype.win+battletype.loss)
battletype

在這裡插入圖片描述

#繪製條形圖
p=battletype.plot.barh(x='battle_type', y=['win_rate','loss_rate'],stacked=True)
_ = p.set(xticklabels = "", xlim = [0, 1], ylabel = "Battle type", xlabel = "Attacker Win Rate VS Loss Rate")
plt.title('Comparison of battle winning ratio', fontsize =15)
plt.legend(loc='center', bbox_to_anchor=(1, 1.1))
plt.show()

在這裡插入圖片描述

從上圖中可以看出,razing和ambush勝率驚人,雖然資料量不多,但是勝率也是高達100%,看來出奇制勝也許才是勝利的關鍵,siege並未給防守方帶來更多獲勝的機會,進攻方仍然可以達到90%勝率。除去戰役型別,接下來對雙方戰鬥力進行分析。

battlesize = battles[["attacker_size", "defender_size", "attacker_outcome","count"]].dropna(axis = 0)
battlesize['size_diff']=battlesize['attacker_size'] /battlesize['defender_size']
battlesize

在這裡插入圖片描述

sns.set(style="darkgrid")
sns.lmplot(x='attacker_size', y='defender_size', hue = 'attacker_outcome',data = battlesize,
          fit_reg=False)
plt.show()

在這裡插入圖片描述

import statsmodels.api as sm
battlesize[['loss','win']]=pd.get_dummies(battlesize['attacker_outcome'])
battlesize=battlesize.drop('loss',axis=1)
battlesize['intercept']=1
logit_mod=sm.Logit(battlesize['win'],battlesize[['intercept','size_diff']])
result=logit_mod.fit()
result.summary()
Optimization terminated successfully.
         Current function value: 40.841116
         Iterations 6

在這裡插入圖片描述

從邏輯迴歸分析的結果來看,戰力差距似乎對進攻方的勝率並沒有什麼影響,接下來我們研究下第二個問題,到底哪個好戰分子出場率最高呢?

#將進攻方的國王拆分成單個字串並加入新list kings
kings=[] 
temp=[kings.extend(x) for x in battles.attacker_king.dropna().str.split("/")]
atk_king=pd.DataFrame(kings,columns=['atk_king'])
atk_king['count']=1
#統計進攻方國王出場率
atk=atk_king.groupby('atk_king').agg({'count':'count'}).reset_index().sort_values('count',ascending=False)[:].reset_index()
from pyecharts import TreeMap
#繪製矩形樹圖
data =  [{"value":atk['count'][i],
          "name":atk['atk_king'][i]} for i in range(atk.shape[0])]
treemap = TreeMap("進攻方國王出場率", width=600, height=300)
treemap.add("", data, is_label_show=True, label_pos='inside')
treemap.render()
treemap

在這裡插入圖片描述

看來Tommen Baratheon和Joffrey經常發動戰爭,瘋狂搶鏡啊

#將進攻方的指揮官拆分成單個字串並加入新list commanders
commanders=[] 
temp=[commanders.extend(x) for x in battles.attacker_commander.dropna().str.split(",")]
atk_cmd=pd.DataFrame(commanders,columns=['atk_cmd'])
atk_cmd['count']=1
atk_commander=atk_cmd.groupby('atk_cmd').agg({'count':'count'}).reset_index().sort_values('count',ascending=False)[0:50].reset_index()
from pyecharts import WordCloud
name = atk_commander['atk_cmd'].tolist()
value = atk_commander['count'].tolist()
wordcloud = WordCloud(width=1200, height=600)
wordcloud.add("", name, value, word_size_range=[20, 100],shape='circle')
wordcloud.render()
wordcloud

在這裡插入圖片描述

Robb Stark作為進攻方的指揮官,也是參與指揮了多場戰役啊。

得出結論

問題

1.戰役型別和攻守雙方戰力對比與戰役勝率之間的關係?

結論:針對戰役型別,使用詭計(ambush)和對未設防進攻(razing)獲勝的機率較高,使用計謀和突襲可能對戰果會有影響;相反攻守雙方戰力對比卻沒發現有明顯影響勝率的因素,相關性不高。

2.哪位好戰分子出場率最高?

結論:進攻方國王Tommen Baratheon和Joffrey出場率最高,而指揮官中Robb Stark出場率最高

反思

問題:在你的分析和總結過程中是否存在邏輯嚴謹。是否有改進的空間? 你可以從下面的一些角度進行思考:

  1. 資料集是否完整,包含所有想要分析的資料?
  2. 在對資料進行處理的時候,你的操作(例如刪除/填充缺失值)是否可能影響結論?
  3. 是否還有其他變數(本資料中沒有)能夠對你的分析有幫助?
  4. 在得出結論時,你是否混淆了相關性和因果性?

答案:首先資料集中缺失內容較多,一定程度上影響了對資料的分析。由於時間有限,有些內容未做更深入的相關性分析,可以從多個因素分析影響勝率的因素,無法給出更加準確的結論,希望經過後面的學習,繼續完善對專案的分析。