CodeZine(コードジン)

特集ページ一覧

Apache Sparkによるスケーラブル機械学習入門

IBM Bluemix User Group(BMXUG)リレー寄稿 第5回

  • LINEで送る
  • このエントリーをはてなブックマークに追加

目次

ロジスティック回帰による分類

 機械学習における「分類」では、複数のグループに分類された教師データから母集団におけるグループの分布をモデル化し、未知の入力がどのグループに属するのかを推定します。ここでは、太宰治と宮澤賢治の青空文庫から引用した小説の書き出し部分を教師データとして与え、未学習の小説の書き出しに対して著者を分類するモデルを構築します。

fig10. 青空文庫
fig10. 青空文庫

 本サンプルプログラムでは、BluemixのObject Storageへデータファイルを配置し、Object Storage上のファイルからRDDを生成します。そこで、まずはじめにBluemixでのApache SparkサービスとObject Storageサービスの連携方法について解説します。

 Object Storageサービスをデータソースとして追加するには、まずNotebook右のPaletteから[Data Sources]を選択します。そこから[Add Source]ボタンをクリックするとfig11のようなダイアログが表示されるので、[Create or connect to an Object Storage ...]というリンクをクリックし、遷移先でさらに[Add Object Storage]をクリックすると、fig12のObject Storage選択画面が表示されます。既存のBluemixやSoftLayerのObject Storageも選択できますが、今回は5GBまで無料で利用できるFreeプランを選択してObject Storageサービスを新しく生成します。コンテナ名は「notebooks」としておいてください。

fig11. Add Data Sourceダイアログ
fig11. Add Data Sourceダイアログ
fig12. Object Storage選択画面
fig12. Object Storage選択画面

 Object Storageの追加が終わったあと、再びNotebookに戻りPaletteの[Data Source]から[Add Source]を選択すると、今度はファイルをアップロードできるようになります。list5とlist6の内容をそれぞれ「dazai.txt」と「miyazawa.txt」として保存し、Object Storageへアップロードしてください。

list5(dazai.txt)
メロス は 激怒 した 必ず かの 邪智 暴虐 の 王 を 除か なければ ならぬ と 決意 した メロス には 政治 が わからぬ
昔 の 話 で ある 須々木 乙彦 は 古着屋 へ はいって 君 の ところ に 黒 の 無地 の 羽織 は ないか と 言った
これ は れい の 飲食店 閉鎖 の 命令 が 未だ 発せ られない 前 の お話 で ある 新宿 辺 も こんど の 戦火 で
朝 食堂 で スウプ を 一さじ すっ と 吸って お母さま が あ と 幽 な 叫び 声 を お挙げ に なった
或る とし の 春 私 は 生れて はじめて 本州 北端 津軽 半島 を 凡そ 三週間 ほど かかつて 一周 した ので あるが
list6(miyazawa.txt)
オツベル と きたら 大した もんだ 稲扱 器械 の 六台 も 据え つけて のんのんのんのんのんのん と 大そろ しない 音を たてて やっている
をかし な はがき が ある 土曜日 の 夕がた 一郎 の うち に きました
では みなさん は そういう ふうに 川 だと 言われ たり 乳 の 流れた あと だと 言われ たり していた この ぼんやり と 白い もの が ほんとう は 何 か ご承知 ですか
グスコーブドリ は イーハトーヴ の 大きな 森 の なか に 生まれ ました おとうさん は グスコーナドリ と いう 名高い 木こり で どんな 大きな 木 でも まるで 赤ん坊 を 寝かし つける ように わけ なく 切って しまう 人 でした
二人 の 若い 紳士 が すっかり イギリス の 兵隊 の かたち を して ぴかぴか する 鉄砲 を かついで 白熊 の ような 犬 を 二疋 つれて だいぶ 山奥 の 木の葉 の かさかさ した とこ を こんな こと を 云い ながら あるいて おり ました

 ロジスティック回帰による著者分類プログラムのコードをlist7に記載します。

list7
from pyspark.mllib.regression import LabeledPoint
from pyspark.mllib.classification import LogisticRegressionWithSGD
from pyspark.mllib.feature import HashingTF

# HadoopConfigurationへのCredentialの設定

def set_hadoop_config(credentials):
    prefix = "fs.swift.service." + credentials['name']
    hconf = sc._jsc.hadoopConfiguration()
    hconf.set(prefix + ".auth.url", credentials['auth_url']+'/v3/auth/tokens')
    hconf.set(prefix + ".auth.endpoint.prefix", "endpoints")
    hconf.set(prefix + ".tenant", credentials['project_id'])
    hconf.set(prefix + ".username", credentials['user_id'])
    hconf.set(prefix + ".password", credentials['password'])
    hconf.setInt(prefix + ".http.port", 8080)
    hconf.set(prefix + ".region", credentials['region'])
    hconf.setBoolean(prefix + ".public", True)

credentials = {
    # PaletteのData Sourcesから挿入
}
credentials['name'] = 'files'
set_hadoop_config(credentials)

# 

dazai = sc.textFile("swift://notebooks.files/dazai.txt")
miyazawa = sc.textFile("swift://notebooks.files/miyazawa.txt")

tf = HashingTF(numFeatures = 1000)
features_dazai = dazai.map(lambda line: tf.transform(line.split(" ")))
features_miyazawa = miyazawa.map(lambda line: tf.transform(line.split(" ")))

train_dazai = features_dazai.map(lambda features: LabeledPoint(0, features))
train_miyazawa = features_miyazawa.map(lambda features: LabeledPoint(1, features))
train = train_dazai.union(train_miyazawa)

model = LogisticRegressionWithSGD.train(train.cache())

def label_to_author(label):
    return 'dazai' if label == 0 else 'miyazawa'

test_dazai = tf.transform("私 は その 男 の 写真 を 三葉 見た ことが ある".split(" "))
test_miyazawa = tf.transform("谷川 の 岸 に 小さな 学校 が あり ました".split(" "))

print("Prediction for dazai test: author is %s" % label_to_author(model.predict(test_dazai)))
print("Prediction for miyazawa test: author is %s" % label_to_author(model.predict(test_miyazawa)))

 インポート文の後、Object Storageからデータを取得するため、set_hadoop_config()メソッド内でHadoopConfigurationにObject Storageの資格情報を渡します。credentials変数に与える資格情報は、Paletteの「Data Source」の各ファイルにある[Insert to code]リンク(fig13)をクリックすることでNotebook内に挿入することができます。この際、[Insert to code]をクリックするファイルは、同じObject Storageにアップロードされているものであればどれでも構いません。

fig13. Insert to Codeリンク
fig13. Insert to Codeリンク

 次に、SparkContextのtextFile()メソッドを用いてテキストファイルからRDDを生成します。その後RDDの各行をmap()メソッドで操作しながら、単語ごとにスペースで区切ってHashingTF.transform()メソッドに渡します。HashingTF.transform()メソッドは単語の配列を出現頻度の特徴ベクトルに変換するため、ここでの処理により各著者で頻出する単語や言い回しの特徴がある程度抽出されます。

 次にdazaiとmiyazawaの特徴ベクトルに対してそれぞれ0 or 1のラベリングを行い、結合後キャッシュを用意してLogisticRegressionWithSGD.train()メソッドに教師データとして渡してモデルを構築します。

最後に、教師データに利用しなかった小説の冒頭部分でテストデータを用意し、構築したモデルが著者を判定できるかをテストした結果がlist8です。期待通り、小説冒頭部分から著者を分類することができました。

list8
Prediction for dazai test: author is dazai
Prediction for miyazawa test: author is miyazawa

おわりに

 本稿では、BluemixのApache Sparkサービスを用いて初歩的な機械学習のサンプルプログラムを実装し、SparkとMLlibを活用することでシンプルにスケーラブルな機械学習処理を記述できることをご紹介しました。今回利用したAPIやライブラリは、Sparkに用意されている豊富な機能全体のごく一部なので、もしより詳しい情報を知りたい場合は書籍や公式サイトを参照ください。



  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:IBM Bluemix User Group(BMXUG)リレー寄稿

著者プロフィール

  • 小峰 央志(Bluemix User Group)(コミネ ヒサシ)

    MNU Co., Ltd. 取締役。 サーバサイドアプリケーション開発、Webフロントエンド開発、DevOps、スクラムなど広く浅く取り組む。最近は機械学習を利用したアプリケーション開発に興味があり、主にSemantic Image Segmentationについて勉強しているが敷居の高さに苦戦中...

あなたにオススメ

All contents copyright © 2005-2022 Shoeisha Co., Ltd. All rights reserved. ver.1.5