#はじめに
新型コロナウイルスマップなるものが各社ウェブページ上にアップロードしています。
その関係で、感染症の地理的な広がりとか疫学マップなど、そういったことに興味がでました。
そんななか、datacampのprojectに面白いなものがあったので、やってみたいと思います。
備忘録も兼ねて、投稿したいと思います。
なお、DeepLにて日本語翻訳しています。
#概要
1854年、ジョン・スノー博士は、ロンドンのソーホーで発生したコレラのパターンと発生状況をマッピングすることで、コンピュータを使った空間分析を行った。彼は近隣の死亡者をマッピングし、大多数がある特定の井戸の周りで発生し、死んだ人はその井戸を使用していることを決定しました。これはデータ可視化の最も初期の使用法の一つであるだけでなく、この問題を解決することで、彼は空間分析と現代の疫学を確立しました。
このPythonプロジェクトでは、データを再分析し、ジョン・スノーの有名な地図を再現します。このプロジェクトは、「pandas Foundations」と「Interactive Data Visualization with Bokeh」で習得できるpandasとBokehの知識が試されるように設計されています。
##1. ジョン・スノー博士
ジョン・スノー博士(1813-1858)はイギリスの有名な医師で、公衆衛生史における伝説的な人物として、また麻酔の開発における先駆者として広く知られています。一部の人は、すべての時間の偉大な医師の一人とさえ言う。
麻酔と衛生的な医療の両方を提唱した第一人者として、彼はエーテルとクロロホルムの実験を行っただけでなく、マスクとその投与方法を設計しました。1853年と1857年のヴィクトリア女王の第8子と第9子の出産時には、彼が自らクロロホルムを投与したことで、出産時の麻酔薬の使用が一般に受け入れられるようになったのである。
しかし、後に紹介するように、彼の人生のすべてが成功したわけではありませんでした。ジョン・スノーは、1854年にロンドンのソーホーで発生したコレラの発生源を特定した科学的でかなり近代的なデータアプローチにより、現代疫学の創始者の一人として認識されています(データの可視化、空間分析、データ科学全般、および他の多くの関連分野の創始者と考える人もいます)が、それは必ずしもこのようなものではありませんでした。実際、長い間、彼は単に科学界から無視されていたし、現在は非常に頻繁に神話化されています。
このノートでは、彼の「データの話」を再発見するだけでなく、彼が1854年に収集したデータを再分析し、彼の有名な地図(ゴーストマップとも呼ばれています)を再現します。
# Loading in the pandas module
# ... YOUR CODE FOR TASK 1 ...
import pandas as pd
# Reading in the data
deaths = pd.read_csv("datasets/deaths.csv")
# Print out the shape of the dataset
# ... YOUR CODE FOR TASK 1 ...
print(deaths.shape)
# Printing out the first 5 rows
# ... YOUR CODE FOR TASK 1 ...
print(deaths.head(5))
結果は下記の通り
(489, 3)
Death X coordinate Y coordinate
0 1 51.513418 -0.137930
1 1 51.513418 -0.137930
2 1 51.513418 -0.137930
3 1 51.513361 -0.137883
4 1 51.513361 -0.137883
##2. コレラ襲来!
ジョン・スノーがコレラを発見する前は、コレラはロンドンの過密で不衛生な通りの常連でした。第三次コレラ発生時には、コレラは最も研究されたテーマの一つであり(1839年から1856年の間に、ロンドンだけでも700以上の研究やエッセイが出版されました)、ほぼすべての著者は、コレラ発生の原因は伝染病や「悪い空気」であると考えていました。
ジョン・スノーの麻酔とガスに関する先駆的な研究は、彼にこの病気のマイアズマモデルを疑わせることになりました。もともと彼は、コレラは水や食物によって広まるという説を、『コレラの伝染様式について』というエッセイの中で定式化し、発表していました(1849年の大流行前)。この論文は、ランセット誌とロンドンの医学雑誌で否定的な評価を受けました。
私たちは彼が正しかったことを知っていますが、スノー博士のジレンマは、それをどうやって証明するかということでした。彼の最初のステップはデータをチェックすることだった 私たちのデータセットは、3つの列に489行のデータを持っていますが、より簡単にデータセットを使用して作業するために、我々は最初にいくつかの変更を行います。
# Summarizing the content of deaths
# ... YOUR CODE FOR TASK 2 ...
deaths.info()
# Define the new names of your columns
newcols = {
'Death': 'death_count',
'X coordinate': 'x_latitude',
'Y coordinate': 'y_longitude'
}
# Rename your columns
# ... YOUR CODE FOR TASK 2 ...
deaths.rename(newcols)
# Describe the dataset
# ... YOUR CODE FOR TASK 2 ...
deaths.describe()
結果は下記のとおり
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 489 entries, 0 to 488
Data columns (total 3 columns):
Death 489 non-null int64
X coordinate 489 non-null float64
Y coordinate 489 non-null float64
dtypes: float64(2), int64(1)
memory usage: 11.5 KB
Death X coordinate Y coordinate
count 489.0 489.000000 489.000000
mean 1.0 51.513398 -0.136403
std 0.0 0.000705 0.001503
min 1.0 51.511856 -0.140074
25% 1.0 51.512964 -0.137562
50% 1.0 51.513359 -0.136226
75% 1.0 51.513875 -0.135344
max 1.0 51.515834 -0.132933
##3. 何も知らないくせに ジョン・スノー!
一人の男が、そのミアスマ理論を否定し、他のすべての人が間違っていることを証明することができるなんて、どういうわけか考えられないことだったので、彼の研究はほとんど無視されていました。同僚の医学者たちは言った "何も知らないくせに、ジョン・スノー!"
すでに述べたように、ジョン・スノーの最初の試みは、"miasma "理論を否定的なレビューで終わっています。しかし、ある評論家は、どのような証拠が説得力のあるものになるかという点で有益な提案をしてくれた。1854年にロンドンのソーホーでコレラが発生したことは、スノーに命を救う機会を与えただけでなく、彼の理論をさらに検証し、改善する機会を与えた。しかし、彼が正しかったという最終的な証拠はどうでしょうか?
ジョン・スノーがどうやってやったか分かったので、まずデータを正しく取得しましょう。
# Create `locations` by subsetting only Latitude and Longitude from the dataset
locations = deaths[["x_latitude","y_longitude"]]
# Create `deaths_list` by transforming the DataFrame to list of lists
deaths_list = locations.values.tolist()
# Check the length of the list
# ... YOUR CODE FOR TASK 3 ...
len(deaths_list)
結果は下記の通り
489
##4. ゴーストマップ
彼のオリジナルの地図は、残念ながら入手できません(現存しないかもしれません)。しかし、約1年後の1855年に彼が描いた有名な地図を見ることができます。
この地図は死を描いて視覚化したものなので、ゴーストマップとも呼ばれています。
ジョン・スノーがどうやって描いたのか、データもあるので、現代の技術を使って彼の地図を再現してみましょう。
# Plot the data on map (map location is provided) using folium and for loop for plotting all the points
import folium
map = folium.Map(location=[51.5132119,-0.13666], tiles='Stamen Toner', zoom_start=17)
for point in range(0, len(deaths)):
folium.CircleMarker(deaths_list[point], radius=8, color='red', fill=True, fill_color='red', opacity = 0.4).add_to(map)
map
結果は下記のように、マップが表示されます。
foliumはpythonでleafletを使えるようにしたモジュールです。
##5. ポンプだ!
地図上の死亡者をマークした後、ジョン・スノーが見たものは無作為のパターンではありませんでした(ゴーストマップの再現版でも見ました)。死亡者の大半は、ブロードストリート(現在のブロードウィックストリート)とケンブリッジストリート(現在のレキシントンストリート)の角に集中していました。これらの通りの交差点周辺の死亡者の集団が発生の震源地でしたがそこには何があったのでしょうか?そう、給水ポンプだ。
当時のジョン・スノーは、コレラは水を介して広がるという理論をすでに持っていたので、それを検証するために、近くにある給水ポンプの位置を地図上にマークした。そして、これが全体像でした。
コレラに関連した死亡者の場所と水道ポンプの場所を組み合わせることで、スノーは、大多数がソーホーのブロードストリートにある特定の公共水道ポンプの周辺に集中していることを示すことができました。最後に、彼は必要な証拠を手に入れたのです。
私たちは今、同じことをして、ゴーストマップの私たちのレクリエーションにポンプの場所を追加します。
# Import the data
pumps = pd.read_csv("datasets/pumps.csv")
# Subset the DataFrame and select just ['X coordinate', 'Y coordinate'] columns
locations_pumps = pumps[["X coordinate","Y coordinate"]]
# Transform the DataFrame to list of lists in form of ['X coordinate', 'Y coordinate'] pairs
pumps_list = locations_pumps.values.tolist()
# Create a for loop and plot the data using folium (use previous map + add another layer)
map1 = map
for point in range(0, len(pumps_list)):
folium.Marker(pumps_list[point], popup=pumps['Pump Name'][point]).add_to(map1)
map1
##6. 何も知らないくせに、ジョン・スノー! ≪(再び)
それで、ジョン・スノーは、コレラの流行の結果としての死と、おそらく汚染された公共の水ポンプとの間に関連性があるという証拠をついに手に入れたのです。しかし、彼はそれだけに留まらず、さらに調査しました。
彼は異常(今で言うところの「データの異常値」)を探していて、実際に死亡者が出ていない場所を2つ見つけたのです。1つ目はブロードストリートのすぐ近くにある醸造所で、そこに行って、彼らがほとんどビールを飲んでいたことを知りました(言い換えれば、地元のポンプの水ではなく、ポンプが発生源であるという彼の理論を裏付けています)。死者が出なかった2番目の建物は、ポーランド通り近くの作業所で、彼らの水源がブロード通りのポンプではないことを彼は知った(これは彼の説を再び確認した)。両方の建物の位置は左の地図にも表示されている。
彼は確信していたので、役人は彼と彼の理論を信用していなかったが、彼らは翌日の1854年9月8日にポンプのハンドルを取り外した。ジョン・スノウは後に彼の有名な本の中で、流行のピークの前後の死亡者のデータを年代順に収集して発表したが、ここではハンドルを外した時の効果を分析して比較する。
# Import the data the right way
dates = pd.read_csv("datasets/dates.csv",parse_dates=['date'])
print(dates.head())
# Set the Date when handle was removed (8th of September 1854)
handle_removed = pd.to_datetime('1854/9/8')
# Create new column `day_name` in `dates` DataFrame with names of the day
dates['day_name'] = dates.date.dt.weekday_name
# Create new column `handle` in `dates` DataFrame based on a Date the handle was removed
dates['handle'] = dates.date > handle_removed
# Check the dataset and datatypes
dates.info()
# Create a comparison of how many cholera deaths and attacks there were before and after the handle was removed
dates.groupby(['handle']).sum()
結果は下記の通り
order date attacks deaths
0 1 1854-08-19 1 1
1 2 1854-08-20 1 0
2 3 1854-08-21 1 2
3 4 1854-08-22 0 0
4 5 1854-08-23 1 0
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 43 entries, 0 to 42
Data columns (total 6 columns):
order 43 non-null int64
date 43 non-null datetime64[ns]
attacks 43 non-null int64
deaths 43 non-null int64
day_name 43 non-null object
handle 43 non-null bool
dtypes: bool(1), datetime64[ns](1), int64(3), object(1)
memory usage: 1.8+ KB
order attacks deaths
handle
False 231 528 500
True 715 43 116
##7. 千の言葉の価値がある絵
ポンプからハンドルを取り外すと、感染した水がこれ以上溜まらなくなりました。その後、ポンプの下の湧水が汚水で汚染されていたことが判明した。この行為は、疫学、公衆衛生医学、科学(病原菌理論)を現実の危機に応用した初期の事例として、後に評価されました。
1992年、ポンプのレプリカが、説明と記念のプレートと一緒に、ハンドルのないオリジナルの場所の近くに、現在のジョン・スノーパブの後ろの壁の近くに建てられました。この場所は、小さな壁のプレートの前にあるピンク色の花崗岩の縁石で微妙に目印になっています。
ジョン・スノーのデータから多くを学ぶことができます。絶対数を見ることもできますが、この観察は間違った結論を導く可能性があるので、Bokehを使って別のデータを見てみましょう。
ジョン・スノーのおかげで、データを時系列に並べて見ることができました。
python:7.py
import bokeh
from bokeh.plotting import output_notebook, figure, show
output_notebook(bokeh.resources.INLINE)
# Set up figure
p = figure(plot_width=900, plot_height=450, x_axis_type='datetime', tools='lasso_select, box_zoom, save, reset, wheel_zoom',
toolbar_location='above', x_axis_label='Date', y_axis_label='Number of Deaths/Attacks',
title='Number of Cholera Deaths/Attacks before and after 8th of September 1854 (removing the pump handle)')
# Plot on figure
p.line(dates['date'], dates['deaths'], color='red', alpha=1, line_width=3, legend='Cholera Deaths')
p.circle(dates['date'], dates['deaths'], color='black', nonselection_fill_alpha=0.2, nonselection_fill_color='grey')
p.line(dates['date'], dates['attacks'], color='black', alpha=1, line_width=2, legend='Cholera Attacks')
show(p)
##8. ジョン・スノーの神話&私たちは何かを学んだか?
前のインタラクティブな可視化から、コレラの発生のピークはハンドルを取り外す前に起こり、1854年9月8日以前にはすでに減少していた(下降軌道)ことがはっきりとわかります。
というのも、絶対的な数字だけを比較した場合、ブロードストリートのポンプのハンドルを取り除いたことでコレラの発生が止まったという誤った結論を導く可能性があるからで、それは単に真実ではない(確かに助けにはなったが、発生を止められなかった)。
しかし、人々は英雄や他の神話についての物語が大好きです(科学やデータサイエンスよりも間違いなく)。ジョン・スノーの神話によると、彼はコレラが水を媒介する病気であることを仮説化することによって、2日間で彼らの同等を無視したスーパーヒーローだった。誰も彼の話を聞かなかったにもかかわらず、彼は勇敢に彼の地図を描き続け、彼の発見を持って感染した水ポンプのハンドルを取り除くために地元の当局を説得し、発生を止めた。ジョン・スノーは多くのロンドン市民の命を救った。
この物語の背後にあるものをもっとよく見てみると、限られた道具でこの病気と戦い、自分が正しく、コレラについて「何かを知っている」という証拠を手に入れようとしていた真のジョン・スノウの姿も見えてきます。彼は限られた時間の中でできることをしただけで、飲む前には必ず水を沸かしてから飲んでいた。
#おわりに
英国の医師で、麻酔と医療衛生の発展における先導者であるジョンスノーの行ったコレラマップをpython上で作成しました。現在では、コレラは水媒介性であると判明していますが、当時はまだ不明でした。そのような中でも、仮説を組み立てていき、実証したジョンスノーはすごいですね。