2018年2月28日水曜日

【Googleクラウド・機械学習編】日報解析バッチ作成中4~集計~

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

最近は機械学習について勉強中です。
現在はGoogleの機械学習API「CLOUD NATURAL LANGUAGE API」の検証と、Pythonの勉強を並行して進行しています。

初心者の勉強として、簡単なバッチを作っている最中です。
大した内容はありませんが、お付き合いください。


集計へ

前回にて、何とか自分の日報メールをAPIに食わせて、結果ファイルを取得するところまで成功しました。
現状、以下のようにJSONファイルがズラリとローカルに保管されております。


一個一個のファイルの中身は、以下のようにJSON文字列が入っています。

{
  "entities": [
    {
      "name": "日報",
      "type": "OTHER",
      "metadata": {},
      "salience": 0.20918807,
      "mentions": [
        {
          "text": {
            "content": "日報",
            "beginOffset": 21
          },
          "type": "COMMON"
        }
      ]
    },
    {
      "name": "結合テスト項目書",
      "type": "OTHER",
      "metadata": {},
      "salience": 0.113717824,
      "mentions": [
        {
          "text": {
            "content": "結合テスト項目書",
            "beginOffset": 169
          },
          "type": "COMMON"
        },
        {
          "text": {
            "content": "結合テスト項目書",
            "beginOffset": 203
          },
          "type": "COMMON"
        }
      ]
    },
    {
      "name": "稼働時間",
      "type": "OTHER",
      "metadata": {},
      "salience": 0.111668386,
      "mentions": [
        {
          "text": {
            "content": "稼働時間",
            "beginOffset": 53
          },
          "type": "COMMON"
        }
      ]
    },

……続く


ファイルには


  • "name": "結合テスト項目書"
  • "salience": 0.113717824

のように「キーとなる単語」と、その重要度が数値でセットされています。
つまり、単語毎にグルーピングして集計すれば、私の日報の中から頻出する重要キーワードが浮かび上がる、と。
こういう段取りなわけです。

では、集計バッチを作ってみましょう。


集計バッチ

こんなものを作りました。

import os
import json

dirPath = 'C:/MyMail_result'
files = os.listdir(dirPath)

#連想配列を作成
map = {}

#ファイルを全部読み込み
for file in files:
    f = open(os.path.join(dirPath,file))
    data = json.load(f)
    f.close()

    #name毎にsalienceを集計
    for entity in data['entities']:

        name = entity['name']

        if name in map:
            map[name] = map[name] + entity['salience']

        else:

            map[name] = entity['salience']

#集計結果をソート
resultList = reversed(sorted(map.items(), key=lambda x:x[1]))

#出力
for data in resultList:
    print(data[0] + '\t' + str(data[1]))

それほど大したバッチではありませんが、特徴は連想配列かな?


  • map = {}

PythonではこれでHashMapを作ったことと同じ事になります。

私の好みの部分もありますが、オブジェクト指向において、Mapというのはちと問題児だと思います。
基本的には「型」を定義して、そこに突っ込むのがオブジェクト指向であって、その「型」は厳密に定められているものです。

Mapは何でもぶっこめるので型も何もあったもんじゃない。
ソースがグジャグジャになる原因の一つだと思います。

しかしですね、ここで考慮しなければならないのが、Pythonが動的型付け言語であるということです。

Mapに何でもぶっこんでおいても、Pythonが動的に型を合わせてくれますので。
静的型付け言語で、必要に応じてキャストまでしなければならないJavaとは大きく違う部分です。

つまり、Pythonはむしろ、気軽にMapを使ってパッパと開発していく、そういう用途の為の言語であると言えるでしょう。

だから今回みたいに、ちょっとした計算バッチはパッパとMapで済ませてしまえばOK。

前も書きましたが、Pythonは「ちょっとした計算の集合体」に向く言語です。
Javaは「定められた一貫性」に優れる言語です。

見方を変えれば、
HTTPリクエストやJSONファイルみたいに、どんな内容でも自由に突っ込まれてくる情報の取り扱いは、Pythonが優れる。
RDBMSみたいに、「このテーブルのこのカラムはVARCHAR2」とガッチリ決まっていて不動の所はJavaが優れる。

ならば、「WebシステムでDBに保存する処理はどっちの言語が良いの?」と問われれば、
これが悩ましいです。

MVCモデルのうち、コントロール部はPython、モデル部はJavaに軍配が上がると思います。(ビュー部はHTMLだから関係無い)

従って、私がここ最近Pythonを触ってみた感触としては、こういう感想です。

  • テーブルの数が多いシステムはJava。
  • テーブルの数が少ないシステムはPython。

指標値とするべきはテーブルの数!!

「テーブルの数が多い=STEP数も多い=画面数も多い」となりがちなので、STEP数や画面数を指標としても同じような判断に落ち着く事も多いと思いますが、
テーブル数主眼が本質という考え方はアリだと思います。

「多い/少ない」の分かれ目は、これも感覚的なものですが……、20コくらいが上限じゃないでしょうか?
一つのシステムで20テーブルを超えたら、もう大規模システムの領域だと思います。
Pythonで似たようなことをやりたいなら、システムを2つに分割して10テーブルの小さなシステムを2つ作るとか、
サービスデザインを見直すべきところでしょう。

集計結果

ともかく、これで集計出来ました。
さあ、私の日報の分析結果は如何に。

日報 30.935778224999996
稼働時間 17.395398603999993
概要 7.594298239
詳細 4.874361350999999
作成 4.006452768100001
打ち合わせ 2.7061136348
提案書作成作業 1.90614234
ネットワーク接続作業 1.6254301270000004
プロパー 1.5154260646000002
作業 1.4572377554000002
ジェニシス 1.4317204425000003
見積もり 1.4068984159999998
稼働 1.245910729
事 1.1966940003
技術調査 1.1899960548
ソース解析 1.07680666
人 1.0335532006
予定 1.002557445
気づき 0.9903137190000001
帳票 0.9701202919999999
サンプル 0.9039525214999999
構築方針書 0.8930587449999999
マネージャー 0.8877154268999999
連絡事項 0.8676672089
システム 0.8229978675000001
プロジェクト 0.8194439760000002
話 0.8187522889000002
資料 0.8143453079000003
Java 0.7839326217000001
客先 0.7562989093
こと 0.7256286095000003
準備 0.6499679165000001
画面 0.6439224732000001
BI 0.6338003121
サンプルHTML 0.6266641692999999
Oracle 0.6084089060000001
GCOM 0.5797013178999999
検討 0.5605384631
機能 0.5536394495999999
パッケージ 0.5513561149999999
調査 0.5406491108
現場 0.5338922546000001
プラン 0.5171976732
方針 0.4683039328
要件定義 0.4537456172
単体テスト 0.44251170900000003
部分 0.4377159611
設計書 0.4054884552
内部 0.3879731024
方 0.3855670599999999
ビジネスフロー 0.384925288
クラウド基盤 0.3830445173
要件定義工程 0.3821089
開発 0.3820660644
結合テスト項目書 0.37300472500000004
チームミーティング 0.36438519610000003
放置状態 0.363936127
STEP数 0.35657688679999994
ビジネスフロー作成フェーズ 0.3412589773
ソースレビュー 0.338786632
BIプラン 0.337376835
提案書 0.32983535729999996
画面構成検討 0.32272407500000005
提案書作成作業:08:00h 0.31764615100000004
ございませ 0.30836847
構成 0.30728194200000003
帰社 0.30420098119999994
レビュー 0.3030037097
状況 0.3007273611
支援 0.29845437710000006
ソース解析:08:00h 0.293045449
もの 0.29084775009999997
待機 0.28608122
調整 0.285563885
チャンス 0.27885413449999996
合宿 0.2785616205
結合テスト 0.277871993
リリース 0.263083156
感じ 0.25053776079999995
問題 0.25040119800000005
導入 0.24158003300000003
勉強会 0.2364971065
画面構成検討:08:00h 0.235985352
案件 0.2346195449
承認 0.2288930412
Oracleクラウド 0.22463897
インターネット 0.22296365950000002
★個人名につき秘密★ 0.22103915889999995
時間 0.21647127900000002
構築方針書作成:08:00h 0.213250314
処理 0.212900709
HTML 0.2093946756
見積もり作業 0.20597136
客先打ち合わせ 0.204712169
内部調整:08:00h 0.204112792
プロジェクト構築検討:08:00h 0.202727818
課題 0.20266155249999998
結合テスト項目書作成:08:00h 0.197733019
ソース解析作業 0.19659552349999998

全部で2000行もあるのでTOP100だけ載せますが……。

ん、ん~……。

何も読み取れないというのが正直なところ。

とは言え、「あっ、この人、SEだ!!」ということは伝わってきますよね。

私だと使い道が思い浮かばなくても、広告業とかやっている人には使い道がありそうな気もしますね。

断定的な処理を行う材料には使えなくて、ヤマを張る為の参考情報くらいが使い道なようです。

例えば、


  • 客先打ち合わせ 0.204712169


「打ち合わせ」というキーワードで引っ掛けて、その数字が0.5を超えたら、それだけ日報に多数の「打ち合わせ」という単語が登場しているということですから、

「コイツは打ち合わせばっかりやっている可能性がある。不要な会議をやっていないか確認して、必要であればテコ入れしろ!!」

とアラートを出すとか、ね。

具体的な実用化案までは考えられませんか、どういうシロモノかという感覚は理解出来た気がします。

終わりに

興味本位で始めた連載でしたが、なかなか面白かったと思います。
自分の業務で即刻役に立つものではありませんが、見分を広めるという意味では良かったかな、と思います。

ネットで記事を読むだけと、ショボくても良いから自分で作ってみるのは、結構違うものです。

今後も色々と調べていきたいですね。

0 件のコメント:

コメントを投稿