備忘録的な

プログラミングや機械学習に関する備忘録

機械学習の知識習得とデータ分析を同時に支援するMALSS interactive

この記事は,機械学習工学 / MLSE Advent Calendar 2018 - Qiitaの2日目の記事です.

tl;dr

機械学習を利用したデータ分析をインタラクティブにサポートしながら,同時にユーザのデータ分析に関する知識習得を支援するPythonライブラリ「MALSS interactive」を作りました.
評価実験に協力してくれる方を絶賛募集中です.

背景と動機

機械学習ブームのおかげで書籍やブログ,オンライン学習コンテンツが充実し,機械学習の勉強・情報収集はとてもやりやすくなりました.
さらに,機械学習の社会実装が進むにつれ,機械学習を用いたデータ分析のプロセスを自動化するツール・サービスも充実してきています.
しかし,忙しいエンジニアは,実務で機械学習を利用するまえに十分に勉強する時間を確保することが困難です.
また,分析の自動化に頼ってしまうと,分析の中身がブラックボックスになり知識が身につかず,より発展的な分析を行うことが難しくなります.

私は機械学習の初学者が勉強をしながら分析を半自動で行うことができるPythonライブラリ,MALSS(MAchine Learning Support System)を開発しています.
Pythonでの機械学習を支援するツール MALSS(導入) - Qiita
MALSSはデータの前処理,アルゴリズム選択,ハイパーパラメータチューニングといった一連の分析手順を自動化します.さらに分析結果をレポートとして出力することで,利用者の知識習得を支援します.
しかし,MALSSはデータの性質や分析結果に応じて動的に分析方法を変えることはできませんでした(そのような作業はMALSS利用の前後で行うことを想定していました).

提案

MALSSを改良し,GUIを備え,ユーザとインタラクティブに分析を進めていくことができる,MALSS interactiveを開発しました.
GitHub - canard0328/malss: MAchine Learning Support System

使い方

MALSSはpipでインストールできます.MALSS interactiveのGUIはPyQt5で作っていますが,MALSSと同時にはインストールされないため,別途PyQt5をインストールする必要があります.

pip install malss
pip install pyqt5

インストールが完了したらPythonインタープリタを起動し,以下のようにMALSSをインタラクティブモードで起動します(lang='jp'を忘れると下手くそな英語が出てきますのでご注意ください...).

from malss import MALSS
MALSS(interactive=True, lang='jp')

MALSS interactiveが起動すると,あとは画面の指示に従いながら分析を行うことができます.その際,例えば下図のように,変数の種類(量的変数,質的変数)の説明,ダミー変数の説明などを行い,データ読み込み結果に応じて,変数の種類をユーザが変更することができたりします.

f:id:canard0328:20181201221227p:plain
f:id:canard0328:20181201221657p:plain

グリッドサーチによるハイパーパラメータチューニングもサポートしています.

f:id:canard0328:20181201222249p:plain

さいごに

MALSS interactiveはできたばかりなので,いろいろご意見いただけると嬉しいです.
また,ただいま評価実験に協力していただける方を絶賛募集中ですので,機械学習の勉強をはじめたばかりの方で,協力してやってもよいという方はぜひご連絡ください*1

*1:このブログへのコメント,Twitter,MLSEのSlackなどでご連絡ください

論文のResearch questionsとContributionsの書き方

英語論文を書いていて,主にIntroductionでResearch questionsとContributionsを書く時に,毎回「どんな表現があったかな?」と調べている気がするのでメモしておきます.

参考にした論文は,読んでいてこの人の書き方は上手だなと思ったものや,早稲田大学鷲崎研究室の論文です.
鷲崎研究室の論文は(専門が違うので中身はよくわからないのですが)書き方の質が高く,先生の教育がしっかりしているのではと勝手に思っています.

Research questions

英語 日本語
Does X tend to Y? XはYという傾向があるか?
Does the type of X make a difference in the relationship between A and B? XのタイプによりAとBの関係に差が出るか?
Does X affect the Y performance? XはYの性能に影響するか?
How do X affect Y when Z? ZのときXはYにどう影響するか?
Does X induce a different Y than Z? XはZと異なるYを誘発するか?
Does X between A and B differ? AとBでXは異なるか?
Does X more effectively Y in Z? XはZをより効果的にYか?
Does X improve Y? XはYを改善するか?
Can using X do something more Y than using Z? Xを使うことでZよりよりYできるか?
Can X be done by our method? 我々の手法によりXがdoできるか?
Can we X? 我々はXできるか?
How 副詞 can we X? どれだけ(副詞),我々はXできるか?
Which X types are more likely to induce Y? どのXの種類がYを誘発しやすいか?
How much does X improve Y? Xはどの程度Yを改善するか?

Contributions

英語 日本語
X approach classification based on Y. Yに基づくXのアプローチの分類
The results of X are discussed. Xの結果に対する議論
A new X model is presented. 新しいXモデルの提案
The proposed X successfully Y. 提案手法XはよくYできる
We have proposed a method to X using Y. 我々はYを使ってXする手法を提案した
We have developed a tool that can X. 我々はXできるツールを開発した
We have applied X to Y, and have confirmed its validity. 我々はXをYに適用しその妥当性を確認した。
We propose X that Y by Z. 我々はZによりYするXを提案する
We develop X to Y. 我々はYするためにXを開発する
We validate our method by X. 我々はXにより我々の手法を検証する

論文の貢献ではなく,提案手法Xの貢献として,It...と列挙するパタンもあるようです.
また,判明した事実だけを書くパタンもあるようなのですが,それは貢献なのでしょうか?「事実」を明らかにしたことが貢献では?

Windows+Vim(terminal利用)+Python3.6の環境構築

Vimゆるふわ勢(自分)向けの備忘録です.

Vim8.1で端末ウィンドウがサポートされました.
ぜひ使いたいのですがゼロ(ソースコード)から環境構築するのはちょっと,という場合,
vim-win32-installerか,vim-jp(vim-kaoriya)からバイナリーをダウンロードしてくることになります.
しかし,

  • vim-win32-installerはterminalに対応していない(v8.1.0229)
  • vim-kaoriyaはterminalに対応しているがPython3.5ベース

という問題があります.

今回はvim-kaoriyaを使ってPython3.6で開発できる(補完やコードチェック機能を使える)ことを確認しました.

0. 前提

Pythonは3.6で,Minicondaで環境構築しています.Windows 10 Pro/Homeで確認しました.

1. vim-kaoriyaの用意

vim-jp(vim-kaoriya)からバイナリーをダウンロードして展開します.
ダウンロードしたのはvim81-kaoriya-win64-8.1.0005-20180520.zipです.
terminalが使えることを確認しておきます.

:echo has('terminal')

と打って1が返ってくれば大丈夫です.
f:id:canard0328:20180802164012p:plain:w400
この状態でterminalでPythonを実行することが可能です.
f:id:canard0328:20180802165745p:plain:w300

2. completorによる補完

補完にはcompletorを使います.
vimのパッケージ管理にはVundleやpathogenなどいろいろありますが,ゆるふわ勢な自分はvim8に組み込まれているパッケージマネージャーで十分です.
completorのドキュメントに従って,
$HOME/vimfiles/pack/completor/startフォルダを作成して,
completorをgit cloneするだけです.

Pythonの補完を有効にするにはjediが入っている必要があります.なければ

pip install jedi

で入れましょう(私の場合は気が付いたら入ってましたが,Minicondaの場合conda install jedi?).

次に,completorのドキュメントによると$HOME/_vimrcに次のように書けとあります.

let g:completor_python_binary = '/path/to/python/with/jedi/installed'

私の場合は

let g:completor_python_binary = 'C:\Users\username\Miniconda3'

としました.

設定を終えvimを起動すると次のようなメッセージが出ます.
f:id:canard0328:20180802165849p:plain
この状態では補完が機能しません.
そこで,次のようにPython3.6のdllの場所を$HOME/_vimrcに書いてあげます.

set pythonthreedll=c:\Users\username\Miniconda3\python36.dll

するとこのように,completorの補完機能は有効になったようですが,なぜかPythonの補完ができません.
f:id:canard0328:20180802165934p:plain:w400
そこで,先ほど書いた

let g:completor_python_binary = 'C:\Users\username\Miniconda3'

を削除します.

無事のPythonの補完ができるようになりました.
(なぜこれで上手くいくのか分かりません...)
f:id:canard0328:20180802170026p:plain:w300
Minicondaの仮想環境にのみインストールされているパッケージの補完もできます.
f:id:canard0328:20180802170102p:plain:w350

3. flake8を使ったコードチェック

コードチェックはvim-flake8などが有名ですが,vim8以降に対応しているALEを使用します.

completorのときと同じようにドキュメントに従って,
$HOME/vimfiles/pack/git-plugins/startフォルダを作成して
さらにaleフォルダ内にgit cloneします.

設定も同様にドキュメントに従い,$HOME/_vimrcに以下を追記します.

let g:ale_linters = {'python' : ['flake8'],}

Pythonにflake8が入っていなければpip install flake8またはMinicondaの場合conda install flake8します.

ちゃんとコードチェックしてくれるようになりました.
f:id:canard0328:20180802170143p:plain

あとは自分好みに環境を整えて完成です.
terminalの使い方はこれから勉強します.
f:id:canard0328:20180802170221p:plain

Vimはこれで勉強してます.

「スティーブ・ジョブズ驚異のプレゼン」を読んだ

Podcastで@さんが薦めていたので読んでみました.
ajito.fm

正直信者本臭いな,と思っていたのですが,仕事のプレゼンにも活かせそうな知見が得られたのでまとめておこうと思います.
特にQA対策として,考えられる質問をクラスタリングして,クラスタごとに汎用的な回答を用意しておくというのは良いアイディアだなと思います(ジョブズのテクニックか?とも思いますが)

  1. いきなりスライドを作り始めるのではなく,まずアナログな手段(紙と鉛筆,ホワイトボードなど)でアイディア,流れを整理する
  2. 以下からなるべく多くの要素を取り入れる
    • ヘッドライン,バッションステートメント,3つのキーメッセージ,アナロジー,デモ,パートナー,実例,ビデオ,小道具
  3. 「聞き手はなぜこの発表内容に注意を払うべきなのか」を自問する.発表後に聞き手に覚えてほしいポイントを一つだけ挙げるとしたら?
  4. 選んだポイントをできる限り明快に伝える.少なくとも2回は繰り返す.バズワードジャーゴンは使わない
  5. 自分がなぜそれを伝えたいのか,それを1文にまとめ(パッションステートメント)相手に伝える
  6. 発表するもののビジョンを簡潔に1文で表すヘッドラインを作る.具体的であり,受け手のメリットを示すこと
  7. ヘッドラインは聞き手にとってのよりよい未来を示すもの.自分にとってのではない
  8. 発表したいものについて知ってほしいポイントを全てリストアップし,これを分類し主要メッセージが3つになるまで絞り込む
  9. 3つのキーメッセージそれぞれについて効果を高める部品(体験談,事例,実例,アナロジー,メタファー,推薦の言葉)を用意する
  10. プレゼンの早い段階で問題提起を行う.聞き手の痛みを感じる部分を思い描き,なぜこれが必要なのかを考える
  11. 問題提起には時間を割いて詳しく説明する.痛みを強く感じてもらう
  12. あなたの製品/サービスを気に入る人はいない.人々が気にするのは彼らの問題を解決することだ.どの問題を解決しようとしているのか,に特に注意を払う
  13. 現状を描写し,それが本来どうあるべきなのか,自分のビジョンを示す
  14. 聞き手が痛みを感じるポイントをはっきりとさせたあと,自分がどのような形でその痛みをやわらげるのか,わかりやすく説明する
  15. 1枚のスライドは一つのテーマに絞る
  16. プレゼンの中心テーマには,それを支持するデータを用意する
  17. データは具体性,意義,文脈性が重要.つまり数字を聞き手の暮らしに密着した文脈に置くこと
  18. アナロジーなどの方法で数字をドレスアップすること
  19. 文章はすっきりとさせる.繰り返しをなくし,バズワードジャーゴンを無くす
  20. 発表内容をサポートする,信用のある媒体や人気ブログなどの評価を利用する
  21. 短く魅力的かつ実質的なデモを組み込む
  22. 目から吸収する人,耳から吸収する人,体から吸収する人がいる.すべてに対応する
  23. 意表を突く瞬間を作りこむ(よく練習すること)
  24. ボディランゲージに注意を払う.アイコンタクトを保つ.開いた姿勢をとる.
  25. 抑揚をつける,声を大きくしたり小さくしたりする,スピードを変えるなど喋り方に変化をつける.間にも気をつける
  26. 自分が発表する姿を録画してチェックするとよい
  27. 練習は何度も何度も行う
  28. 想定される質問を全てリストアップしカテゴリ分け(多くても7つ)する.カテゴリごとに汎用的な回答を作成しておき,質問をいずれかのカテゴリに当てはめて回答する
  29. メモは見ない
  30. まず自分がプレゼンを楽しむ
  31. 失敗しても謝らない.うまくいかないことがあればサラッと認め次に進む.自分にしかわからないミスだと思ったらそのまま触れずにおく

論文:Waiting Lines as a Marketing Issue

TwitterのTLで見かけて興味を持ったので読んでみました.

Waiting Lines as a Marketing Issue
Michel Kostecki
European Management Journal Vol. 14, No. 3, pp. 295-303, 1996
www.sciencedirect.com

色々なサービスの待ち時間について論じたものです.
待ち時間の性質の分類や,様々な待ち時間対策の事例紹介は興味深かったのですが,正直言って論文というよりエッセイのような感じです.エビデンスの示されていない記述が非常に多いのが気になりました.

以下備忘録です.

  • 顧客の待ち時間マネジメントはその他のマーケティングMIXと同等に重要,かつ低コストで効果のある施策が打てる状況にも関わらず十分に検討されていない。

  • 待ち時間が発生することは人気の証拠であったり,それ自体が上質な体験の一部となり得るが,それをあてにするのはリスキー。

  • 顧客を待たせるコストは待ち時間のコストと不快に感じるコストの和。

  • 待つことによる不満足の要因は以下のようなものがある.
    1. 我慢できる時間
    2. 予測される待ち時間
    3. 知覚される待ち時間

  • 我慢できる時間は下記に拠る
    1. 時間の価値(忙しいほど高い)
    2. サービスの価値(高い非日常なサービスでは待てる)
    3. ニーズの強さ(無いと死んじゃうような場合は待てる)
    4. 類似サービスへのアクセスしやすさ(替え難ければ待てる)
    5. 待つときの不快さ(立ちっぱなしはつらい)
    6. 生活ペース

  • 予測される待ち時間は以下のような要因で決定され,この予測待ち時間が我慢できる待ち時間未満であれば,待つという判断をする.
    1. 列の待ち人数
    2. 列の消化速度
    3. 以前経験した待ち時間
    4. そのサービスで予測されるだいたいの待ち時間
    5. 緊急度
    6. 他の客の待ち時間
  • 客の待ちによる不満足の決定要因としては,以下のようなものにより決まる.
    1. 待ちの質(時間,期待との差,快適さなど)
    2. サービス(質,選択肢の貧しさ,価値の無さなど)
    3. 客の質(緊急度,ネガティブマインド,不安,退屈さなど)

  • 待ち時間の削減には,オファーの管理と需要の管理がある。前者は,余剰生産能力の維持,突発需要に対応する機器のリース,柔軟な雇用体系の労働力,客優先のマネジメント,サービスの質の低下(セルフサービスにするなど)などがある。後者は,予約システム,季節調整価格,キャンペーンなどがある。

  • 客がどれくらい待つと考えるか(待たされたと,ではなく?)をperceived waiting timeといいこれも大事。待つことを告げられ,謝罪があり,不安を和らげ,スタッフがちゃんと客を気遣っていることを示すというコミュニケーションが大事。

  • 遅れが発生したときは伝えるべきだが,待ち時間を過少見積りしないほうがよい。appointment syndromeといい,約束時間を過ぎると,それが少しでも不満に感じる。

  • 遅れたときは,顧客メリットを伝えられると良い。例「フライトが遅れてすみません。この遅延はお客様の旅をより安全かつ快適にするためのものです」

  • 不安は待ち時間を長く感じさせる。不安を減らすために,あとでサービスを中断しなければならなくてもまず開始する,予約システムを使う,可能な限り顧客を安心させる,顧客の不安を増すような行動や言動を慎む
  • 事例
    1. 高層オフィスビルのエレベーターの待ち時間が長いという問題に対し,エレベーターのドアの横に鏡を設置。
    2. 空港で荷物が出てくるのが遅いというクレーム。しかし出てくる時間は平均値。問題は荷物受け取り場まで3分でつけてしまうこと。受け取り場を遠くして歩く必要があるようにしたらクレーム止まった。

Google Cloud Text-to-Speechを使って英語のシャドーイングをする

再来週,国際会議で発表するのですが,私の英語力だと原稿作って暗記していくのが必須です.そこで,合成音声に原稿喋らせて,シャドーイングの練習できないかな?と考えました*1

ちょうど先月,Google Cloud Platform(GCP)でCloud Text-to-Speech(TTS)が公開されました*2.TTSはテキストを音声に変換する技術です.Cloud TTSの特徴はDeepMindが開発したWaveNetという技術が用いられていることで,肉声に近い高品質な音声を生成することができます.
今回はこれを使ってシャドーイング練習用音声を作成します.

ポイントは以下のとおりです.

  1. 原稿を1文1行のテキスト化しておき,一括で1文1音声に変換する
  2. WaveNetを使って高品質な合成音声を生成する
  3. シャドーイングしやすいように,やや発話速度を遅くする
  4. シャドーイングしやすいように,文末に無音を挿入する

準備

GCPやCloud SDK,Cloud TTS APIの設定は公式ドキュメントのとおりに行います.

  1. Quickstart: Text-to-Speech  |  Cloud Text-to-Speech API  |  Google Cloud
  2. Quickstarts  |  Cloud SDK  |  Google Cloud

クライアント側はPythonを使います.準備は以下の通り(Miniconda利用).

pip install --upgrade google-cloud-texttospeech
pip install pydub
conda install -c menpo ffmpeg

音声の生成

基本的には公式ドキュメントの通りにやればよいのですが,シャドーイング練習用に少し修正しています.

話者の変更

voice = texttospeech.types.VoiceSelectionParams(
    language_code='en-US', name='en-US-Wavenet-D')

このページの表からVoice nameにWavenetがついている話者を選択します.6種類のWavenet音声を選択できますが,一通り試してみて話者Dが聞きやすいと感じました.

フォーマットの指定と発話速度の調整

audio_config = texttospeech.types.AudioConfig(
    audio_encoding=texttospeech.enums.AudioEncoding.LINEAR16,
    speaking_rate=0.8)

ファイルフォーマットは,あとで音声ファイルの編集(無音の挿入)を行うためMP3ではなくWAV(LINEAR16)を指定しています.
また,デフォルトの発話速度はシャドーイング練習用としては(私には)早すぎるため,少し遅く(0.8)しています.

文末に無音を挿入

今回,1文1音声ファイルとするのですが,これを音楽プレーヤーで再生すると,音声間のポーズが短く,シャドーイングが(私には)しんどいです.そこで,文末に1秒の無音(ポーズ)を挿入します.音声ファイルの編集はpydubとffmpegというライブラリを使用しています.

with open(path + '.wav', 'wb') as out:
    out.write(response.audio_content)

audio = AudioSegment.from_wav(path + '.wav')
silence =AudioSegment.silent(duration=1000)
audio += silence
audio.export(path + '.mp3', format='mp3')
os.remove(path + '.wav')

Cloud TTSで生成した音声を一度WAVファイルとして保存し,pydubで読み込み,無音を挿入してMP3で保存,最後にWAVファイルの削除という処理になっています.いちいちWAVファイルを生成しなくてもいけるような気もしますが,調べるのが面倒くさかったので...

一括ファイル作成

出力ファイルパス(拡張子無) <Tab> 読ませたい文

という形式のテキストファイルを用意し,以下のように一括で音声を生成します.

with open('scripts.txt', 'r') as fi:
    for line in fi:
        path, text = line.rstrip().split('\t')
        synthesize_text(text, path)

おわり

スクリプト全体は下記のようになりました.
WaveNet,文全体で聞くとまだ不自然だなと思う部分もありますが,単語レベルだと私にはもう肉声と区別がつきません.
これで学会発表練習がんばります.

「日本語の作文技術」覚え書き

言わずと知れた名著「日本語の作文技術」.

自分が作文をするときだけでなく,人の文章を添削するときにも,なぜ直した方がよいのかをしっかり説明できるようになります.

普段から特に気をつけておきたい点,なかでも覚えておけばすぐに使える注意点を備忘のためにまとめておきたいと思います.

1. 修飾する側と修飾される側の言葉同士をできるだけ直結し,入れ子状態にしない.
×:僕は佐藤が鈴木が山本が告白した場所にいたと言ってたのかと思った.
○:山本が告白した場所に鈴木がいたと佐藤が言っていたのかと僕は思った.

×の例では,「山本が→告白した場所に」の外側に「鈴木が→いた」があり,その外側に「佐藤が→言っていたのかと」,さらにその外側に「僕は→思った」という入れ子状態になっており,非常に分かりにくい分になってしまっています.○の例のように入れ子状態を解消することで読みやすい文章になります.

2. 修飾の順序は節を先にし,句を後にする.
×:黄色いアップリケの縫い付けられたハンカチ
○:アップリケの縫い付けられた黄色いハンカチ

×の例では,ハンカチが黄色いのかアップリケが黄色いのかの区別がつきません.

3. 長い修飾語は前に,短い修飾語は後ろに.
×:僕の親友の鈴木に山本が僕が夢に見るほど大好きな佐藤を紹介した.
○:僕が夢に見るほど大好きな佐藤を僕の親友の鈴木に山本が紹介した.
  1. 僕が夢に見るほど大好きな佐藤を
  2. 僕の親友の鈴木に
  3. 山本が

と長い順にすることで読みやすくなります.ただしこれに関してはなぜ×の例が読みづらいのかについてのロジカルな解説が無く,「別に読みづらくないですけど?」と言われたときにどのように説明すればよいのだろうと思いました.

4. 修飾の順番は,大事な順に.
×:コーヒーで太ももに佐藤さんが火傷をした.
○:佐藤さんが太ももにコーヒーで火傷をした.

特殊な場合を除けば,「佐藤さんが」「太ももに」「コーヒーで」の順に大事でしょう.

5. 長い修飾語が二つ以上あるとき,その境界に点をうつ.

これ自体は当たり前のことのように思いますが,大事なのは読みやすさの向上に貢献しない不要な点をうたないことだと思います.

6. 上記の語順の原則に反する場合に点をうつ.
×:山本が僕が夢に見るほど大好きな佐藤を僕の親友の鈴木に紹介した.
○:山本が,僕が夢に見るほど大好きな佐藤を僕の親友の鈴木に紹介した.

×の例は「3. 長い修飾語は前に,短い修飾語は後ろに」に反していますが,どうしても「山本が」を主語にしたい場合そのあとに点をうつことで誤読を避けることができます.

7. 並列や同列の語の間には読点より中点(・)

作文において読点は非常に重要なため,不用意な使用を避けるために並列や同列の語の間には中点を使うことを推奨しています.ただし同列の語が例えば「トーマス・エジソン」「二コラ・テスラ」のように中点を含む場合,中点を使うことができません.このような場合,筆者は二重ハイフンを使うと言っています(例:トーマス=エジソン).

8. 過去形の使い方

過去形を使う場合,「過去の事実(今はそうではない)」なのか「筆者にとってその話を聞いたのが過去というだけ(事実は今も変わらない)」のかが分かるようにすべきと言っています.