IPアドレス群からワールドヒートマップを作成してみた
こんにちは、森田です。
アクセスログの多くには、アクセス元のIPアドレスを含んでいます。
そのIPアドレスを集計し、可視化する方法の1つとしてワールドヒートマップがあります。
本記事では、実際にIPアドレス群からPythonでデータの処理を行い、ワールドヒートマップを行って行きます。
検証環境
- Python 3.8.5
- pandas
- numpy
- geoip2 4.5.0
- pycountry 20.7.3
- folium 0.12.1
使用するデータ
データは下記のようなIPアドレス群を使用します。csvファイルでまとめてあるものとします。
使用ライブラリ
IPアドレスから国を推定するためgeoip2
、geoip2
で取得できる国名コード変換用にpycountry
を使用します。
また、基本的なデータ処理はPandas
を用いて行い、ヒートマップはfolium
を使用します。
Pandas
、pycountry
は、pipコマンドなどでインストールを行います。
pip install pandas pycountry
geoip2(GeoLite2)のインストール
まず、pipコマンドを用いてインストールを行います。
pip install geoip2
geoip2
を使用するためには、ファイルのダウンロードなどが必要となります。
こちらよりGeoLite2 City
のダウンロードを行います。
ダウンロードしたファイルは以下のように使用します。
import geoip2.database ip = '11.109.10.11' reader = geoip2.database.Reader('GeoLite2-City.mmdb') res = reader.city(ip) print(res.country)
geoip2.records.Country(confidence=None, geoname_id=6252001, is_in_european_union=False, iso_code='US', _locales=['en'], names={'de': 'USA', 'en': 'United States', 'es': 'Estados Unidos', 'fr': 'États Unis', 'ja': 'アメリカ', 'pt-BR': 'EUA', 'ru': 'США', 'zh-CN': '美国'})
Foliumのインストール
Foliumは、Pythonの地理データ可視化ライブラリの1つです。
このライブラリは、Quickstartを見るだけなんとなく使えるほど簡単に使用できるのがとても魅力的です。
こちらの使用には、まずpipでインストールを行います。
pip install folium
その後、地図データの別途ダウンロードが必要ですので、下記コマンドでデータをダウンロードします。
git clone https://github.com/python-visualization/folium.git
ワールドマップの場合は、examples/data/world-countries.json
のデータを使用します。
データ前処理
ライブラリ・必要ファイルが準備できたので、先ほどのIPアドレスCSVファイルを国ごとでグループ化していきます。
まず、geoip2で取得できる国名コードがfoliumに対応していないのでpycountryで変換するように関数化します。
import geoip2.database import pycountry def country_checker(ipaddress): try : reader = geoip2.database.Reader('GeoLite2-City.mmdb') response = reader.city(ipaddress) return pycountry.countries.get(alpha_2=response.country.iso_code).alpha_3 except: return None
この関数をそれぞれのIPアドレスに適用させ、country列
を新規で作成していきます。
df["country"] = df["IP"].apply(country_checker)
国ごとでグループ化するため、counts列を追加します。
df["counts"] = 1
では、国ごとでグループ化を行い、countsの合計値を算出します。
import numpy as np df2 = df[["country", "counts"]].groupby('country').agg(np.sum)
counts country AUS 273 BRA 37 FRA 110 GBR 116 IDN 151 ITA 76 JPN 119 SGP 67 USA 474
最後に、foliumで可視化させる場合、国コードを列データとして渡すので、indexから新規にiso_code列
を作成しておきます。
df2['iso_code'] = df2.index
ワールドマップ作成
では、最後にfoliumで可視化を行います。
import folium # world map import m = folium.Map(location=[50, 0], zoom_start=1) geojson = "./folium/examples/data/world-countries.json" # visualization folium.Choropleth( geo_data=geojson, name='choropleth', data=df2, # Input DataFrame columns=['iso_code', 'counts'], key_on='feature.id', fill_color='OrRd', fill_opacity=0.7, line_opacity=1, legend_name='IP Adress Access' ).add_to(m) m.save("world.html")
このようにして作成されたワールドマップは以下となります。
いい感じで上手く可視化されました!
まとめ
今回は、GeoLite2
、Folium
などを用いて、IPアドレスごとのアクセスをヒートマップにしてみましたが、ドキュメントを少し読むだけで作れたのでとても簡単でした!
ぜひ、アクセスログをお持ちの方は、IPアドレスを抽出し、ワールドヒートマップを作ってみてはいかがでしょうか?
今回のコード・ファイル
参考
GeoLite2でサクッとできるIPアドレスの国判定
Folium 0.12.1 documentation Quickstart