GIS奮闘記

元GISエンジニアの技術紹介ブログ。主にPythonを使用。

スポンサーリンク

Python で MeCab を使ってテキストの内容を形態素解析してみる ~小説内の頻出単語の抽出~

本日は MeCab を使ってみようと思います。MeCab については最近、以下エントリーでインストール方法と簡単な使い方を紹介しましたが、本エントリーではより実践的な使い方を紹介したいと思います。

www.gis-py.com

やってみること

  1. 「坊ちゃん」(夏目漱石)のテキストデータをダウンロード
  2. 正規表現で不要な文字を除去する(ここはなくても形態素解析が可能ですが、より正確に解析したかったので、この手順を入れました)
  3. MeCab を使用して頻出単語(名詞)TOP10を抽出する

データ入手先

青空文庫さんで色々な小説のテキストデータをダウンロードすることができます。

青空文庫 Aozora Bunko

坊ちゃんのデータはここですね。

図書カード:坊っちゃん

中身はこんな感じです。《にさんち》のようにフリガナが入っていたり、ヘッダーやフッターも除去する必要がありますね

f:id:sanvarie:20190727081956p:plain

実行環境

Windows10
Python3.6.5
Jupyter Notebook

正規表現のサンプル

こういう場合は正規表現を使います。そして、Python で正規表現と言ったら re ですね。

import re

# ファイル読み込み
file = r'bocchan.txt'
with open(file) as f:
    text = f.read()

# ヘッダの除去
text = re.split('\-{5,}',text)[2]

# フッタの除去
text = re.split('底本:',text)[0]

# 最初の一の除去
text = re.sub('一', '', text,1)

# ふりがなの削除
text = re.sub('《.+?》', '', text)

# 入力注の削除
text = re.sub('[#.+?]', '',text)

# 空行の削除
text = re.sub('\n\n', '\n', text)

print(text)

いい感じの結果になりましたね。
f:id:sanvarie:20190726230648p:plain

MeCab を使用して頻出単語(名詞)TOP10を抽出するサンプル

MeCab の処理でも少し re を使います。また、形態素解析した結果を collections.Counter を使用して頻出単語(名詞)TOP10を抽出してみたいと思います。そして、抽出対象は名詞-一般のみにしました。結果は「単語:n」のような形式で出力します。

import re
import MeCab
from collections import Counter

# ファイル読み込み
file = r'bocchan.txt'

with open(file) as f:
    text = f.read()

# ヘッダ部分の除去
text = re.split('\-{5,}',text)[2]
# フッタ部分の除去
text = re.split('底本:',text)[0]
# 最初の一の除去
text = re.sub('一', '', text,1)
# ルビの削除
text = re.sub('《.+?》', '', text)
# 入力注の削除
text = re.sub('[#.+?]', '',text)
# 空行の削除
text = re.sub('\n\n', '\n', text)

# Mecab で形態素解析
tagger = MeCab.Tagger("-Ochasen")
result = tagger.parse(text)
result_lines = result.split('\n')

result_words = []
words = []

for result_line in result_lines:
    result_words.append(re.split('[\t,]', result_line))

for result_word in result_words:

    if (    result_word[0] not in ('EOS', '')
        and result_word[3] == '名詞-一般'):

            words.append(result_word[0])

# 頻出単語TOP10を抽出
counter = Counter(words)
for word, count in counter.most_common(10):
    print('%s : %s' % (word, count))

結果はこのようになりました。
f:id:sanvarie:20190727003355p:plain

なるほどーといった感じですね。「赤」が最頻出の単語(名詞)ということがわかりました。タイトルである「坊ちゃん」という単語はTOP10からは漏れているようですね。気になるので調べてみたら70~80位くらいでしたね。
f:id:sanvarie:20190727003705p:plain

MeCab をもっと使いこなせば本当に色々なことができそうですね。もっと勉強して次回はもう少し複雑なものにもチャレンジしてみようと思います。

【ArcGIS Pro SDK】DAML ID を一括で出力する方法

さて、本日は DAML ID を一括で出力する方法について書いてみようと思います。

そもそも DAML とは?

簡単に言うと、「ArcGIS Pro のUI を定義するもの」でしょうか。XML 形式のファイルでArcGIS Pro SDK で開発を行う場合は必ず使用するものです。詳細は以下のサイトを参考にしてみてください。

community.esri.com

github.com

DAML ID を調べるには

以下のサイトでDAML ID の確認をすることができるのですが、英語、そして、どのコントロールがどのDAML ID なのかよくわからない・・・

github.com

DAML ID を一括で出力するには

以下のようなコマンドライン引数をつけて ArcGIS Pro を起動すると、DAML ID の一覧を取得することができます。

ArcGISPro.exe /dumpcombineddaml

f:id:sanvarie:20190726060326p:plain

そして、ArcGIS Pro が起動するとこのようなテキストが出力されます。これが DAML ID の一覧ですね。日本語のキャプションがついているので、特定のコントロールの DAML ID が知りたい場合は便利な機能だと思います。 f:id:sanvarie:20190726055106p:plain

ArcGIS Pro 上で DAML ID の確認を行う

オプション>ヒントにコマンド ID を表示にチェック>OK で DAML ID を ArcGIS Pro 上で確認することができるようになります。

f:id:sanvarie:20190726055325p:plain

このようにアイコンにカーソルをあてれば、それに割り当てられている DAML ID がわかります。 f:id:sanvarie:20190726055649p:plain

ArcGIS Pro SDK の開発で DAML ID をよくさわるけど、いつも使いたい DAML ID を探すのに苦労をするという方はぜひこの方法を試してみてください。

ArcGIS Pro のデフォルトで表示される地形図を消す方法

さて、ArcGIS Pro のデフォルトで表示される地形図を消す方法を紹介します。

ArcGIS Pro とは

言わずもがなですが、ArcGIS のデスクトップアプリですね。以下エントリーに詳細を書いていますので、興味のある方は読んでみてください。

www.gis-py.com

ArcGIS Pro 起動時

ArcGIS Pro を起動するとデフォルトの表示はこのようになります。

f:id:sanvarie:20190725201707p:plain

  • 注記(地形図)
  • 地形図 (World Topographic Map)

というレイヤがデフォルトで表示されますね。ただ、デフォルトで表示してほしくない、という方もいらっしゃるかと思います。

実行環境

ArcGIS Pro 2.3

※バージョンが異なると UI が微妙に違うかもしれませんが、基本的にはどのバージョンでもこの設定はできるはずです。

対応方法

オプション>マップおよびシーン>ベースマップ>「なし」にチェック>OK で完了です。簡単ですね!

f:id:sanvarie:20190725201939p:plain

f:id:sanvarie:20190725202004p:plain

再度起動をしてみると、デフォルトの地形図が表示されていないことがわかります。

f:id:sanvarie:20190725202055p:plain

ArcGIS Pro は設定変更がかなり柔軟にできるようになっています。「こんなことできないかな?」と思ったら、まずはオプションで設定できるか確認することをお勧めします!

ArcMap で横書きの漢字のアノテーションを縦書きにする方法

本日はArcMapの小ネタについて書いてみようと思います。「横書きの漢字を縦書きにしたい!」でも、「やり方がわからない」「そもそもそんなことできるのか?」と思われている方もいらっしゃるかと思います。今回はそのやり方について書いてみようと思います。

環境

ArcMap10.6.1

サンプルデータ

このような横書きの漢字を用意しました。

f:id:sanvarie:20190721140509p:plain

回転させてみる

私は最初は「回転させたらいいのでは?」と思い、回転させてみました。結果がこれです。

f:id:sanvarie:20190721140546p:plain

これでは漢字の向きがおかしくなってしまいますので、だめですね。

手順

まず、上記のアノテーションを元の角度に戻してから、対象のアノテーションの属性を開きます。

f:id:sanvarie:20190721140751p:plain

右下のシンボルボタンを押下します。

f:id:sanvarie:20190721140711p:plain

CJK方向文字にチェックを入れてOKボタンを押下します。

f:id:sanvarie:20190721140820p:plain

注意

文字のフォントが「Arial」とかだと「CJK方向文字」が表示されないので、ご注意ください。おそらく漢字で使われるフォントのみが対象になっていると思われます。

f:id:sanvarie:20190721140902p:plain

属性ウインドウで適用ボタンを押下してください。

f:id:sanvarie:20190721141016p:plain

再度回転させるとこのように漢字が縦書きになりました。

f:id:sanvarie:20190721141144p:plain

属性ウインドウでこのように複数のアノテーションを選択して一括での設定も行うことができます。

f:id:sanvarie:20190721141528p:plain

簡単ですが、本日は以上です。今後は ArcMap や ArcGIS Pro の小ネタとかも色々紹介できればと思います。

Python で 作成した QR コードを読み込んで Googleマップにとんでみる

さて、本日は Python で QR コードを作成してみようと思います。ただ、単純に QR コードを作成してもつまらないので、作成した QR コードで Googleマップにとべるようにしてみようと思います。

使用するライブラリ

qrcode という Python の QR コード画像生成ライブラリを使います。pip でインストールしてください。

pip install qrcode[pil]

pypi.org

QR コードに埋め込む緯度経度

緯度: 35.678601
経度: 139.740286

ここがどこかといいますと永田町駅ですね。

作成する QR コード

GoogleマップへのリンクURLを格納する QR コード を作成します。上記の緯度経度をパラメータにした URL は以下のような形になります。この URL を QR コードに埋め込みます。

https://www.google.com/maps/search/?api=1&query=35.678601,139.740286

手順

今回は以下のような流れで進めてみようと思います。

  1. QRコードの作成(Python)
  2. 作成したQRコードをスマートフォンで読込
  3. Googleマップが指定した緯度経度で起動することを確認

実行環境

Windows10
Python3.6.5

サンプルコード

緯度経度を埋め込んだ QR コード作成のサンプルです。

# coding: utf-8
import qrcode

file_name = r"D:\python\qr.png" # QRコードの作成先

lat = "35.678601"  # 緯度
lon = "139.740286" # 経度

qr = "https://www.google.com/maps/search/?api=1&query=%s" \
         % (lat + "," + lon) # QRコードに埋め込む情報

img = qrcode.make(qr) # 画像作成
img.save(file_name)   # 保存

すごく簡単にできました。

作成したQRコードの画像を開くとこのようになっています。 f:id:sanvarie:20190720110800p:plain

作成したQRコードをスマートフォンで読込むとGoogleマップが出てくるのでタップします。 f:id:sanvarie:20190720111837j:plain

このように指定した緯度経度でGoogleマップを起動することに成功しました。 f:id:sanvarie:20190720111902p:plain

少し拡大させてみました。ピンが置かれている場所は間違いなく永田町ということがわかりますね。 f:id:sanvarie:20190720131025p:plain

ズームとかも指定できるみたいなので、細かい設定などをしたい方はGoogleMapへのリンクURL作成方法を調べた - Qiitaを読んでみてください。

この仕組みを利用すればマップをクリックした箇所をQR コード化してその場所をGoogleマップで確認なんてこともできるかと思います。今度はこれをもう少し発展させたものを作ってみたいですね。

Python3では SimpleHTTPServer ではなく http.server を使うべし

本日はちょっとローカルサーバーをたてたくて、あれっとなった時のお話です。

簡単にローカルサーバーをたてるならやっぱり SimpleHTTPServer かなと思い、

python -m SimpleHTTPServer 8080

を実行。しかし、

No module named SimpleHTTPServer

とでて、あれっ?となり調べてみると、Python2にはあった SimpleHTTPServer という標準ライブラリのモジュールが、Python3では http.server というモジュールに統合されていることがわかりました。

なので、Python3 では

python -m SimpleHTTPServer [ポート番号]

ではなく

python -m http.server [ポート番号]

としなければなりません。お気を付けください。

C# の WebRequest を使って標高API を使ってみる

さて、本日は C# のWebRequest を使って標高API を使ってみようと思います。最近はまっている標高APIですが、以下エントリーでは C# で作った画面から標高APIを呼び出している Python スクリプトを実行して、実行結果を画面に表示しました。今回はそれを C# オンリーで標高APIを使ってみたいと思います。

www.gis-py.com

今回実装するもの

簡単な画面を作りました。処理は以下のような流れです。

  • 作成した画面で緯度経度を入力し実行
  • 標高APIで標高値を取得し、それを標高のテキストボックスに表示

f:id:sanvarie:20190719232535p:plain

インストール

以下をNuget でインストールしてください。

  • System.Net.Http
  • Newtonsoft.Json

環境

Windows10(64bit)
Visual Studio2017
.NET Framework4.7.2

サンプルコード

実行ボタンの処理を記述します。

private async void BtnExecute_Click(object sender, RoutedEventArgs e)
{
    // パラメータ作成
    var parameters = new Dictionary<string, string>()
    {
        { "lon", LonText.Text },
        { "lat", LatText.Text },
        { "outtype", "JSON" },
    };

    // URL作成
    var url = $"http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?{await new FormUrlEncodedContent(parameters).ReadAsStringAsync()}";

    // 標高APIにリクエスト投げる
    WebRequest request = WebRequest.Create(url);

    using (Stream response_stream = request.GetResponse().GetResponseStream())
    {
        using (StreamReader reader = new StreamReader(response_stream))
        {
            // 標高取得
            var jObject = JObject.Parse(reader.ReadToEnd());
            ElevationText.Text = jObject.GetValue("elevation").ToString();
        }
    }
}

実行

このように入力し、実行を押します。
f:id:sanvarie:20190719232749p:plain

実行後、標高APIから取得した標高が表示されます。
f:id:sanvarie:20190719232801p:plain

この緯度経度の場所がどこか気になる方は以下エントリーを読んでみてください。

www.gis-py.com

簡単ですが、本日は以上です。