翻訳者|Cui Hao
査読者|Sun Shujuan
機械学習用の大規模なデータ セットを扱うとき、次のようなアドレス バーに遭遇しますか? ?
上記の位置データは非常に複雑で、処理が困難です。アドレスのエンコードは、カーディナリティが非常に高いため困難です。シングルパス エンコード手法を使用して列をエンコードしようとすると、最終的に高次元の結果が得られ、機械学習モデルのパフォーマンスの低下につながります。この問題を解決する最も簡単な方法は、列をジオコーディングすることです。
ジオコーディングは、住所を地理座標に変換することです。つまり、元の住所が経度/緯度に変換されます。
Python でのジオコーディングに役立つさまざまなライブラリが多数あります。最も速いのは Google Maps が提供する API ですが、短時間で変換する必要がある住所が 1000 件を超える場合には、これを使用することをお勧めします。ただし、Google Maps API は無料ではなく、1,000 リクエストあたり約 5 ドルを支払う必要があります。
Google Maps API の無料の代替手段は、OpenStreetMap API です。ただし、OpenStreetMap API は Google マップよりもはるかに遅く、精度も低くなります。
この記事では、上記の 2 つの API を使用したジオコーディング プロセスについて説明します。
まず、Google Maps API を使用して住所を精度/緯度に変換しましょう。まず、Google Cloud アカウントを作成し、クレジット カード情報を入力する必要があります。これは有料サービスですが、最初に Google Cloud アカウントを作成すると、Google から 200 ドルの無料クレジットが付与されます。これは、料金が請求されるまでに、ジオコーディング API を使用して約 40,000 回の呼び出しを行うことができることを意味します。この制限に達しない限り、アカウントに請求されることはありません。
まず、Google Cloud で無料アカウントを作成します。アカウントを設定したら、このチュートリアルに従って Google Maps API キーを取得できます。
API キーを受け取ったら、コーディングを開始できます!
(1) 前提条件
このチュートリアルの Kaggle データセットには Zomato Restaurant を使用します。データセットがパスにインストールされていることを確認してください。次に、このコマンドを使用して googlemaps API パッケージをインストールします。
pip install -U googlemaps
(2) データセットの読み取り
次に、データセットを読み取り、データ フレームのヘッダーを確認してみましょう。
data = pd. read_csv('zomato.csv',encoding="ISO-8859-1") df = data.copy() df.head()
このデータ セットには 21 列と 9551 行があります。
住所列のみをジオコーディングする必要があるため、他のすべての列を削除します。その後、重複するレコードを削除し、最終的に住所列情報のみを取得します。
df = df[['地址']] df = df. drop_duplicates()
データ フレームのヘッダーをもう一度見てください。処理後は、アドレス情報のみが表示されます。
次に、ジオコーディングを開始できます。
(3) ジオコーディング
まず、Python を使用して API キーにアクセスし、次のコード行を実行してこのタスクを完了します。
gmaps_key = googlemaps.Client(key="your_API_key")
次に、住所をジオコーディングして出力を見てみましょう。
add_1 = df['地址'][0] g = gmaps_key. geocode(add_1) lat = g[0]["geometry"]["location"]["lat"] long = g[0]["geometry"]["location"]["lng"] print('Latitude: '+str(lat)+', Longitude: '+str(long))
上記のコードを実行すると、次のような出力が得られます。
上記の出力が得られれば、素晴らしいことです。すべてがうまくいくことを意味します。次のように、同様の処理をデータ セット全体に適用できます。
def geocode(add): g = gmaps_key. geocode(add) lat = g[0]["geometry"]["location"]["lat"] lng = g[0]["geometry"]["location"]["lng"] return(lat, lng)。 df['geocoded'] = df['Address']. apply(geocode)
データ セットのヘッダーを再度チェックして、コードが機能するかどうかを確認します。
df.head()
出力が上のスクリーンショットと同様であれば、おめでとうございます。データ フレーム全体で住所を正常にジオコーディングしました。
OpenStreetMap API は完全に無料ですが、Google Maps API と比較すると速度が遅く、精度も低くなります。この API はデータセット内の多くの住所を見つけることができないため、今回は代わりに location 列を使用します。チュートリアルを始める前に、アドレス バーとロケーション バーの違いを見てみましょう。このタスクを実行するには、次のコード行を実行します。
rreeee地址栏(Address)比地点(Locality)栏细化得多,它提供了餐厅的确切位置,包括楼层号。这可能是地址不被OpenStreetMap API识别,而地点却被识别的原因。
让我们对第一个Locality进行地理编码,看看输出结果。
地理编码
运行以下几行代码。
Import url Import requests data = data[['Locality']] url = 'https://nominatim.openstreetmap.org/search/' + urllib. parse. quote(df['Locality'][0]) +'?format=json' 。 response = requests.get(url).json() print('Latitude: '+response[0]['lat']+', Longitude: '+response[0]['lon'] )
左右滑动查看完整代码
上述代码的输出与谷歌地图API生成的结果非常相似。
现在,让我们创建一个函数来寻找整个数据集合的坐标。
def geocode2(locality): url = 'https://nominatim.openstreetmap.org/search/' + urllib. parse. quote(locality) +'?format=json' response = requests.get(url).json() if (len(response)!=0)。 return(response[0]['lat'], response[0]['lon'] ) else: return('-1') data['geocoded'] = data['Locality']. apply(geocode2)
很好!现在,让我们来看看数据集合的头部。
Data.head(15)
请注意,这个API无法为数据集合中的一些地方提供坐标。
虽然它是谷歌地图API的免费替代品,如果用OpenStreetMap进行地理编码,有可能会失去大量的数据。本教程到此结束!希望你从这里学到了一些新的东西,并对处理地理空间数据有了更好的理解。
原文链接:https://www.kdnuggets.com/2022/11/geocoding-python-complete-guide.html
崔皓,51CTO社区编辑,资深架构师,拥有18年的软件开发和架构经验,10年分布式架构经验。
以上がPython でのジオコーディングの完全なソリューションの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。