1日22時間寝たい

技術頑張ってる最中です

Macでxhostコマンドで”unable to open display”が出るのはCatalinaのせいかも?

サマリ

何が起きたのか

最近話題の「ゼロからのOS自作入門」をMacのDocker環境で写経しようとしたところ、xhostunable to open displayエラーになる。

book.mynavi.jp

DISPLAY変数を設定するなどしてみたが状況は改善せず。

解決方法

色々調べてみると、"Cannot connect to X server"で困っている人が"Download the newest singularity Desktop MacOS"したら出来た旨の記事を見つけたので、macOS 10.15 CatalinamacOS 11 Big Surにアップデートしたところ、できるようになった次第。

詳しい経緯

環境

  • MacBookPro(13-inch, 2017)
  • Docker

流れ

前述の「ゼロからのOS自作入門」本を手元で動かしたいと思ったものの、好き勝手に使えるマシンがMBPだけなのでDockerを検討。すると、以下のサイトでDocker環境を配布してくれている人を発見、かつ、その環境で実際に動かしている人の記事もあったのでこの方法で行くことにした。

zenn.dev

zenn.dev

上記2つの記事を参考にMac + Docker環境を整えている最中、XQuartzのインストール後、xhost + 127.0.0.1をするもxhost: unable to open display ""となる。xhostコマンドで「unable to open display」となる場合の対処などの記事を参考に以下のように変数を設定するもエラー。

$ xhost + 127.0.0.1
$ xhost:  unable to open display ""
$
$ env | grep DISPLAY
$
$ export DISPLAY=:0.0
$ env | grep DISPLAY
$ DISPLAY=:0.0
$ 
$ xhost + 127.0.0.1
$ xhost:  unable to open display "0.0"
$ 

その他DNSの設定やらhostsの設定やらXQuartzのセキュリティ設定やら色々弄ってみるもうまく行かず、以下のスレッドを発見。

github.com

環境など色々違うところはあるものの、

In summary:

  • Download the newest singularity Desktop MacOS (it would not work on another Mac until installing the newest singularity)

ということだったので、macOS 10.15 CatalinamacOS 11 Big Surにアップデートしたところ、まさかの解決。

$ xhost + 127.0.0.1
$ 127.0.0.1 being added to access control list

つまり

OSアップデートはしっかりやっておいたほうがいい(自戒)。

【参加報告】atmaCup#10に参加してみた

はじめに

2021/03/05 〜 2021/03/13 の日程で開催されていたatmaCup#10に参加してみました。

Kaggleに登録してから早数年経っているくせに、コンペはほぼやったことないので間違いなく初心者。コンペタイトルが[初心者歓迎!]だったのでここぞとばかりに参加してきました。

お題は?

コンペページからそのまま以下。

美術作品の属性情報から、その作品がどのぐらい人々に評価されるのか?を予測します。

標準的なテーブルデータに加えて、作者名や作品説明などの自然言語情報や、絵画の色情報などが与えられていて、面白い題材でした。

ただ、残念なことにコンペ期間中に仕事がかなり忙しくなってしまい、実質参加できたのは10時間程度でした。(次のatmaCupまだかなぁ……)

どうだったのか?

LB : 170位

PB : 173位

やったこととしては、ディスカッションが活発&上級者が色々な知見をわかりやすく動くコードで紹介していてくれたので、それをほぼなぞっただけです。あとは絵画の面積足してみたり、適当な特徴量同士の数値をかけ合わせてみたり……。

良かったこと

初心者講座なるものがかなり分かりやすい

合計2回あって、1回目はどうsubmissionするか、2回目はどう工夫するか、というのがメインでした。データの見方とか、手間を省くコードの書き方とか、初心者が知りたいことが詰まってました。2回目のほうは内容が重くてまだ全部理解できていないので、LateSubmissionする自分に期待。

ディスカッションが日本語

Kaggleのディスカッションも頑張って眺めるのですが、英語がわからなさすぎて結構辛いので、日本語で読めるのは精神的にありがたかったです。エンジニアしているくせに英語ができないのが悪い。

サブミットしたときの表示がかわいい

めちゃくちゃやる気が湧く。

今後取り組みたいこと

実験管理

少ししかsubmitできていないですが、特徴量やパラメータやらモデルが分からなくなることが多々。先人の知恵がネットにたくさん転がっているので自分なりの管理方法を模索したいです。

手札を増やす

今回あまり時間をかけられなかったせいもあるのですが、"次になにをしよう"という知見がないのが地味に辛かったです。特に今回は短期間コンペだったので、いかに短時間に色々なことができるか、が大事だった気がします。ここは経験を増やすしかないと思っています。

自分なりのパイプラインを作る

コンペに参加したらとりあえず脳直にできることを増やしていきたい。これもコンペに参加することから始めたいと思います。

そもそも機械学習の知識を付ける

機械学習統計学・数学をちまちまと勉強していますが、それが使えるようになるのはいつのことやら……。信じて勉強していくしかない気がする。

チームを組んでみたい

今は初心者MAXなので迷惑をかけるだけかもしれないけど、いつか人とチーム組んでコンペしてみたいです。やる気が途切れなくて済むかも。同じくらいの初心者の人だったら逆に組みやすかったりする……?

おわりに

参加した皆さん、お疲れさまでした。

また、ディスカッションを盛り上げてくれた方、知見やコードを共有してくれた方、運営の方、ありがとうございました。とても楽しかったです。

自然言語処理100本ノック2020やってみる【chap2】

はじめに

自然言語処理100本ノック2020のchapter2をやってみた記事です。

詳細は以下のchap1の記事を参照してください。

hirune-is-supremacy.hatenablog.com

第2章: UNIXコマンド

コード

使用データ

popular-names.txtは,アメリカで生まれた赤ちゃんの「名前」「性別」「人数」「年」をタブ区切り形式で格納したファイルである.

以下の処理を行うプログラムを作成し,popular-names.txtを入力ファイルとして実行せよ.

さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.

!wget https://nlp100.github.io/data/popular-names.txt

# Python用
txt_file = "popular-names.txt"

10. 行数のカウント

行数をカウントせよ.確認にはwcコマンドを用いよ.

python

with open(txt_file) as f:
    txt = f.readlines()
    print(len(txt))
2780

unix

!wc popular-names.txt
 2780 11120 55026 popular-names.txt

11. タブをスペースに置換

タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.

python

with open(txt_file) as f:
    txt = f.readlines()
    new_txt = []
    for i in txt:
        new_txt.append(i.replace("\t", " ").replace("\n", ""))

    print("\n".join(new_txt))
Mary F 7065 1880
Anna F 2604 1880
Emma F 2003 1880
Elizabeth F 1939 1880
Minnie F 1746 1880
...(以下略

unix

!sed -i "s/\t/ /g" popular-names.txt

12. 1列目をcol1.txtに,2列目をcol2.txtに保存

各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.

python

files = ["col1.txt", "col2.txt"]

for num, file in enumerate(files):
    with open(txt_file) as f:
        txt = f.readlines()
        with open(file, "w") as w_f:
            for i in txt:
                w_f.write(i[num] + "\n")
!cut -c 1 popular-names.txt > col1.txt

!cut -c 2 popular-names.txt > col2.txt

13. col1.txtとcol2.txtをマージ

12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.

python

with open("col1-col2.txt", "w") as w_f, open("col1.txt") as col1_f, open("col2.txt") as col2_f:
    col1 = col1_f.readlines()
    col2 = col2_f.readlines()
    for i, j in zip(col1, col2):
        w_f.write(i.replace("\n", "") + j)

unix

!paste -d "\t" col1.txt col2.txt > col1-col2.txt

14. 先頭からN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ.

python

N = input()

with open(txt_file) as f:
    txt = f.readlines()
    for i in range(int(N)):
        print(txt[i].replace("\n", ""))
 5


Mary F 7065 1880
Anna F 2604 1880
Emma F 2003 1880
Elizabeth F 1939 1880
Minnie F 1746 1880

unix

!head -n 5 popular-names.txt
Mary F 7065 1880
Anna F 2604 1880
Emma F 2003 1880
Elizabeth F 1939 1880
Minnie F 1746 1880

15. 末尾のN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.

python

N = input()

with open(txt_file) as f:
    txt = f.readlines()
    for i in range(int(N)):
        print(txt[len(txt) - int(N) + i].replace("\n", ""))
 5


Benjamin M 13381 2018
Elijah M 12886 2018
Lucas M 12585 2018
Mason M 12435 2018
Logan M 12352 2018

unix

!tail -n 5 popular-names.txt
Benjamin M 13381 2018
Elijah M 12886 2018
Lucas M 12585 2018
Mason M 12435 2018
Logan M 12352 2018

16. ファイルをN分割する【Skip】

自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.

python

#N = input()
N = 1000

with open(txt_file) as f:
    txt = f.readlines()
    file_num = int(len(txt) / N) + 1
    #for i in range(file_num):
        # ??????????

unix

!split -l 1000 popular-names.txt split_file

17. 1列目の文字列の異なり

1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはcut, sort, uniqコマンドを用いよ.

python

with open(txt_file) as f:
    txt = f.readlines()
    letter_list = []
    for i in txt:
        letter_list.append(i[0])
    print(sorted(list(set(letter_list))))
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'V', 'W']

unix

※うまく行かなかったのでココを参照。「連続していない離れた重複行も削除したければ、sortコマンドコマンドで予めソートする必要がある。その代わり順番は保存されない。」らしい。

!cut -c 1 popular-names.txt | sort | uniq
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
R
S
T
V
W

18. 各行を3コラム目の数値の降順にソート

各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).

python

# pandas使って良いんじゃんと気づいた
import pandas as pd

txt = pd.read_table("popular-names.txt", header=None, names=["name", "sex", "num", "era"])

txt.sort_values("num", ascending=False).head()
name sex num era
1340 Linda F 99689 1947
1360 Linda F 96211 1948
1350 James M 94757 1947
1550 Michael M 92704 1957
1351 Robert M 91640 1947

unix

!sort -k 3nr,3 popular-names.txt | head -n 5
Linda F 99689 1947
Linda F 96211 1948
James M 94757 1947
Michael M 92704 1957
Robert M 91640 1947
sort: write failed: 'standard output': Broken pipe
sort: write error

19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる

各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.

python

import pandas as pd

df = pd.read_table("popular-names.txt", header=None, names=["name", "sex", "num", "era"])

df["name"].str[:1].value_counts(ascending=False).head()
J    448
M    407
R    211
E    211
A    211
Name: name, dtype: int64

unix

!cut -c 1 popular-names.txt | sort | uniq -c | sort -rn | head -n 5
    448 J
    407 M
    211 R
    211 E
    211 A

【参加報告】「Sports Analyst Meetup #7」に参加した

概要

spoana.connpass.com

  • Sports Analyst Meetup #7
    • スポーツアナリストを目指す人のための勉強会
    • (目指してはないけど分析の仕方とかが面白そうで参加してしまった……対象じゃなさそうで申し訳ない)
  • 環境
    • Zoom(質問はチャット)

運営より

  • 事前アンケート結果①(よく使う分析言語やツールは?)
    • Pythonぶっちぎりだけど次がエクセル(めずらしい)
    • エクエル小技とか前処理LTとかもやれたらいいな by 運営
  • 事前アンケート結果②(好きなスポーツは?)
    • 野球・サッカーはめっちゃ強い
    • 去年に比べてラグビーの順位が上がった
    • 柔道や剣道などのマイナー競技こそLTウェルカムだそう
    • 過去にはeスポーツと言い張ってマジック・ザ・ギャザリングのLTをした猛者がいたらしい

発表

【Yohei_CHIBAさん】東京オリンピックに向けたフェンシング アナリストの仕事 〜タグ付けから逃げられなくて〜

競技:フェンシング

  • 発表資料
    • なし
  • 千葉洋平さん
  • 肩書
    • 一般社団法人日本スポーツアナリスト協会理事
    • 公益社団法人フェンシング協会の協会強化本部アナリスト
  • お仕事
    • 情報戦力面で選手を支える
  • 具体的には
    • パフォーマンス分析作業をフレームワーク
    • 局面/課題/行動/動作に分けて分析
      • 局面/課題/行動がアナリストのお仕事部分
      • 動作は情報化が難しく、選手の知見や経験に頼るしかない
  • 仕事の大部分
    • タグ付け
      • 「だれが/いつ/どこで/なにをして/どうなったのか」をつける
      • sportscodeというソフトを使用
        • 1フレームごとにつける
    • 本来はそもそもの分析や選手とのコミュニケーション、コーチとの打ち合わせをしたい
      • だがしかしタグ付けが多すぎ
        • タグ付けに専門知識がいる
          • 国際審判レベル
        • タグ付け要員を育てるのも時間がかかる
    • このタグ付け作業をいかに効率化するか未来のために今から考えている
  • アウトプットについて
    • 選手たちへの伝え方が重要
      • ビジュアライズにこだわっている
        • 特に若い選手にはビジュアライズが効果を持つ
      • 全てオンラインでやる
  • facebookの友達申請待ってる
  • 【質問】
    • フェンシングにおけるKPIは?オリンピックの前後で変化はありますか?
      • 得点率/失点率を気にしている
      • 一時期、試合時間が短縮されて短時間での勝負だったが、最近はまた時間が延長しており、人気によってそういうものは左右されるかもしれない

【Keisuke Fujiiさん】攻撃・守備戦術の自動分類

競技:バスケットボール

  • 発表資料
    • 後日
  • 藤井慶輔さん
  • 現場での戦術的分析はビデオなどの目視が主
    • 位置計測と統合する技術が開発されたら分析屋やコーチ人の負担軽減になる
      • -->位置データから攻撃守備戦術を自動分類する
  • 3パターン試してみた
    • そのまえにバスケのスクリーンプレーについて
      • シュートを打つ選手を邪魔されないように相手を邪魔する
      • バスケはスクリーンプレーの集合
    • その1:特徴を作成、ML(※MachineLearning)なしでの分類
      • スクリーンに対するチームディフェンスとルールベースで分類
        • 評価は柔軟な戦術性
      • 【結果】解釈性はあるが例外がおおすぎ
    • その2:特徴を作成、MLで自動分類
      • SVM
      • 【結果】特徴は解釈しやすいが一般性がない
    • その3:特徴をMLで学習して抽出し、分類
      • 守備戦術・攻撃戦術で分類
      • AUCで評価
      • 【結果】一般性があり使いやすいが、抽出情報の解釈が難しいときがある
  • 身長とか体重的なデータはまだ考慮していない
    • バスケというスポーツの性質上意味が大きそうなのでいつか組み込みたいとのこと

【nowism1229さん】どうしてバントは減らないのか 〜時間割引の視点から〜

競技:野球

  • 発表資料
  • 東京大学大学院で認知科学の研究中
  • 何故バントが減らないのか?
  • 発表者的には「1打で特典が入るからでは?」と思っている
    • 今日はココを説明する
    • 具体的には=時間割引(:将来的な報酬を割り引いて評価する)の効果が働いているのでは?
  • 分析
    • 送りバントにより、得点まで1打席ほど早い
    • バントの期待値より、時間割引による得点の方を有線しているのでは
  • 追加分析
    • 得点までの時間が短くなるほど期待得点が減る
    • 期待得点的には大損しているものの打席が近いことが良いと思われているのでは
  • 【質問】
    • プロ野球より高校選手権のような1発勝負のほうがこういったバイアスを取りやすくなるのでは?
      • 主観だが、おそらくそうだと思う

【Fanalystさん】アナリストはどのように進化していくのか?

競技:サッカーとか

  • 発表資料
    • 後日
  • 経歴
    • サッカーアナリスト9年
    • 元指導者14年
  • ミッション
    • 日本代表のW杯優勝
  • アナリストの進化要件
    • ビジネス力/データサイエンス/データエンジニアリング
      • Domain知識
      • Origin(原点)
      • Relationship
      • Analysis
      • English
      • Monetize
      • Output
      • Newcomer
        • アナリスト職の多様化も大事

感想

  • LT参加者がとても楽しそうに発表してくれるので聞いていてとても楽しい
  • スポーツの分析はDeNAとかバレーボールとかしか見たことがなかったので想像できなくてすべてが新鮮だった
  • Englishは何回か勉強しようとしたけど使い所がないと勉強する気が起きない……

自然言語処理100本ノック2020やってみる【chap1】

はじめに

言語処理100本ノックをやらねばな〜〜と5年考えていたら2020年版が出てしまい、いい加減ちゃんとトライしようと思った次第。

ページは以下です。

nlp100.github.io

マイルールはこう。

  • とりあえず最後までやる
    • 全然わからないところは飛ばす
    • 飛ばしたところは分かった時点で後から追記
  • 問題そのものをググらない
    • Pythonの関数とかはググるけどコピペで動くものをそのまま持ってきたりしない
    • なので書いてあるコードは全くベストな書き方ではないはず
  • できれば!上期中に!終えたい!
    • 怪しい

第1章: 準備運動

コード

00. 文字列の逆順

文字列”stressed”の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ.

_str = "stressed"
print(_str[::-1])
desserts

01. 「パタトクカシーー」

「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ.

_str = "パタトクカシーー"
print(_str[0:-1:2])

## ぐぐったらこっちでいいらしい
print(_str[::2])
パトカー

02. 「パトカー」+「タクシー」=「パタトクカシーー」

「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.

pato = "パトカー"
taxi = "タクシー"

print("".join([i + j for i, j in zip(pato, taxi)]))
パタトクカシーー

03. 円周率

“Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.”という文を単語に分解し,各単語の(アルファベットの)文字数を先頭から出現順に並べたリストを作成せよ.

sentences = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."

result = [len(i) for i in sentences.replace(",", "").replace(".", "").split(" ")]
print(result)
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]

04. 元素記号

“Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.”という文を単語に分解し,1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字,それ以外の単語は先頭に2文字を取り出し,取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.

sentences = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."

word_list = sentences.replace(",", "").replace(".", "").split(" ")
bool_list = [True if i+1 in [1, 5, 6, 7, 8, 9, 15, 16, 19] else False for i in range(len(word_list))]

result = {}

for i, j in zip(word_list, bool_list):
    if j:
        k = i[:1]
        result[k] = i
    else:
        k = i[:2]
        result[k] = i

print(result)

# 求められてる答えになってる?
{'H': 'Hi', 'He': 'He', 'Li': 'Lied', 'Be': 'Because', 'B': 'Boron', 'C': 'Could', 'N': 'Not', 'O': 'Oxidize', 'F': 'Fluorine', 'Ne': 'New', 'Na': 'Nations', 'Mi': 'Might', 'Al': 'Also', 'Si': 'Sign', 'P': 'Peace', 'S': 'Security', 'Cl': 'Clause', 'Ar': 'Arthur', 'K': 'King', 'Ca': 'Can'}

05. n-gram

与えられたシーケンス(文字列やリストなど)からn-gramを作る関数を作成せよ.この関数を用い,”I am an NLPer”という文から単語bi-gram,文字bi-gramを得よ.

sentences = "I am an NLPer"
n = 2
#sentences = ["I", "am", "an", "NLPer"]

result = []

def ngram(sentences, n):
    for i in range(len(sentences)):
        if i < len(sentences) - (n - 1):
            result.append(sentences[i:i + n])

    return result

print(", ".join(ngram(sentences, n)))

# リストが来たらアウト……
I ,  a, am, m ,  a, an, n ,  N, NL, LP, Pe, er

06. 集合

paraparaparadise”と”paragraph”に含まれる文字bi-gramの集合を,それぞれ, XとYとして求め,XとYの和集合,積集合,差集合を求めよ.さらに,’se’というbi-gramがXおよびYに含まれるか どうかを調べよ.

sentences1 = "paraparaparadise"
sentences2 = "paragraph"

n = 2
result = []

def ngram(sentences, n):
    for i in range(len(sentences)):
        if i < len(sentences) - (n - 1):
            result.append(sentences[i:i + n])
    return result

X = set(ngram(sentences1, n))
Y = set(ngram(sentences2, n))

print("X", X)
print("Y", Y)
print("和集合", X | Y)
print("積集合", X & Y)
print("差集合", Y - X)

for i, j in zip([X, Y], ["X", "Y"]):
    print("’se’というbi-gramが", j, "に含まれるかどうか?")
    if "se" in i:
        print("◯")
    else:
        print("✕")
X {'ar', 'di', 'se', 'ap', 'ad', 'pa', 'is', 'ra'}
Y {'ar', 'ag', 'di', 'se', 'ap', 'ad', 'ph', 'pa', 'gr', 'is', 'ra'}
和集合 {'ar', 'ag', 'di', 'ap', 'pa', 'ad', 'ph', 'ra', 'gr', 'is', 'se'}
積集合 {'ar', 'di', 'ap', 'ad', 'pa', 'ra', 'is', 'se'}
差集合 {'ph', 'ag', 'gr'}
’se’というbi-gramが X に含まれるかどうか?
◯
’se’というbi-gramが Y に含まれるかどうか?
◯

07. テンプレートによる文生成

引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ.さらに,x=12, y=”気温”, z=22.4として,実行結果を確認せよ.

x = 12
y = "気温"
z = 22.4

def create_str(x, y, z):
    return "{}時の{}は{}".format(x, y, z)

print(create_str(x, y, z))
12時の気温は22.4

08. 暗号文

与えられた文字列の各文字を,以下の仕様で変換する関数cipherを実装せよ.※文字列はWikiの『バステト』の説明文

英小文字ならば(219 - 文字コード)の文字に置換 その他の文字はそのまま出力 この関数を用い,英語のメッセージを暗号化・復号化せよ.

def cipher(sentence):
    result = []
    for i in sentence:
        if i.islower():
            result.append(str(219 - ord(i)))
        else:
            result.append(i)
    return result

sentence = "Bastet, the form of the name that is most commonly adopted by Egyptologists today because of its use in later dynasties, is a modern convention offering one possible reconstruction."
print("".join(cipher(sentence)))
B122104103118103, 103115118 117108105110 108117 103115118 109122110118 103115122103 114104 110108104103 12010811011010810911198 122119108107103118119 12198 E11698107103108111108116114104103104 10310811912298 121118120122102104118 108117 114103104 102104118 114109 111122103118105 11998109122104103114118104, 114104 122 110108119118105109 120108109101118109103114108109 108117117118105114109116 108109118 107108104104114121111118 105118120108109104103105102120103114108109.

09. Typoglycemia

スペースで区切られた単語列に対して,各単語の先頭と末尾の文字は残し,それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ.ただし,長さが4以下の単語は並び替えないこととする.適当な英語の文(例えば”I couldn’t believe that I could actually understand what I was reading : the phenomenal power of the human mind .”)を与え,その実行結果を確認せよ.

import random

sentences = "I couldn’t believe that I could actually understand what I was reading : the phenomenal power of the human mind ."

def typoglycemia(sentences):
    result = []
    words = sentences.split(" ")
    for word in words:
        if len(word) <= 4:
            result.append(word)
        else:
            result.append("".join([word[:1], "".join(random.sample(word[1:-1], len(word[1:-1]))), word[-1:]]))
    return result

print(" ".join(typoglycemia(sentences)))
I clund’ot bielvee that I cluod alcaltuy udnersantd what I was randeig : the paneemnohl pwoer of the human mind .

【資格試験】G検定2020#1受けてみた

受験料が高いとか協会がちょっとアレとかで、一部界隈には話題のG検定を受けました。理由は会社が受験料を持ってくれるからオモシロソウダナーと思ったからです。

結論だけ先に書いておくと、紙ベースの参考書問題集が全く当てになりませんでしたまだ合否通知は来ていませんがおそらく落ちているかと思います。受かっていました。驚き。

届いた合否通知メールによると今回の受験者数と合格者数は以下の通りのようです。

総受験者数 合格者数
6,298 4,198

G検定とは

JDLAが主催しているディープラーニングに関する試験で、詳細は以下抜粋。

当協会は、ディープラーニングに関する知識を有し、事業活用する人材(ジェネラリスト)と、ディープラーニングを実装する人材(エンジニア)の育成を目指します。 各々に必要な知識やスキルセットを定義し、資格試験を行うとともに、協会が認定した事業者がトレーニングを提供します。各々年二回実施予定。日進月歩する技術であることから、検定・資格実施年毎に実施年号を付与します。

とりあえず、ジェネラリスト向けとされているG検定を受けました。日時は3月14日の13:00〜でした。詳しく知りたい場合は以下が参考になると思います。

www.jdla.org

購入書籍

以下の2つを買いました。試験にはあまり役には立ちませんでしたが、昨今より少し前のディープラーニングが盛り上がり始めたあたりを俯瞰して勉強できました。読み物として面白いです。あとは、「ディープラーニングって何?」などと聞いてくるググらない管理職とかに渡すにも良い本だと思います。

Amazon CAPTCHAhttps://www.amazon.co.jp/深層学習教科書-ディープラーニング-G検定-ジェネラリスト-公式テキスト/dp/4798157554/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=&sr=www.amazon.co.jp

https://www.amazon.co.jp/徹底攻略-ディープラーニングG検定-ジェネラリスト問題集-スキルアップAI株式会社-明松/dp/4295005665/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=&sr=www.amazon.co.jp

勉強方法としては、どちらの本も単語を聞いたら大体の説明ができるくらいを目処に読みました。ただし、歴史とか昔からの変遷みたいなものを覚えるのが致命的に苦手なので、そこはググラビリティに賭けました。ナントカ博士が人工知能について述べたナントカ会議が開催された年、とかは覚えていません。

試験内容について

120分の試験で、問題数は217問でした(うろ覚え)。

ざっくりだとしても1分に2問弱は回答しないと間に合わないし、見直しやチェックをしたい人はもっと早く回答しなければなりません。

が。

今回は(深層)強化学習自動運転法律系の問題のオンパレードでした。途中に出てきた三平方の定理ベイズの公式に和んだと思ったら、果てはドローンの問題まで出るという。

一番面倒時間がかかるのは法律系の問題で、単純に法令や条文、判例が長くひとまとまりの自然言語なので、検索しても選択肢との整合を確認する時間がかなり取られます。全く見たことも聞いたこともない問題文で、「適切なものを選べ」ならまだ良いのですが「適切でないものを選べ」だともうお手上げ状態です。

150問目くらいまでこの傾向が続き、そろそろ時間もなくなってきたしこれは落ちる気しかしない……と諦めかけたあたりで、問題集に載っているような基礎知識問題がポツポツと出始める鬼仕様でした。

この試験が始まったばかりであり、使用技術の進化のスピードが早く、それに伴う法改正や問題が日々出てくるという特性からも、問題集や参考書を買って地道に勉強するというよりは、日頃からディープラーニング系のニュースを気に留めることができる人向けの試験かもしれません。

もし次に受けるとしたら

教科書だけ買って読んで、あとは日頃からニュースを見て覚えておく……?とか?

ベタープラクティスは分からない。

次は統計検定受けてみようかなと思ってます。とりあえず3級から。

【参加報告】「ML@Loft #11. 類似画像/テキスト検索 - オンライン開催」に参加した

コロナのおかげで色々な勉強会がオンラインになってすごく参加しやすいので、嬉しくて1年ぶりのブログ書くことにした。

本日開催された「ML@Loft #11. 類似画像/テキスト検索」に参加しました!

配信はYouTube Live、質問の受付はsli.doでした。勉強会のURLは以下。

ml-loft.connpass.com

sli.doと並行してTwitterでも「#MLLoft」のハッシュタグで盛り上がっていた気がします。

以下、ざっくりとした自分用のメモ。

発表

松井 勇佑 氏 (東京大学 生産技術研究所 助教) 「annbench: 近似最近傍探索アルゴリズムベンチマーク

画像検索を考える上で近傍探索アルゴリズムの選択は重要ですが難しいです。既存の有名なベンチマーキングライブラリは網羅的ですが実行に十数時間かかるという問題がありました。そこで私は軽量でシンプルなベンチマークのライブラリを作りました。これにより手軽に手法を比較出来ます。是非使ってみてください。

speakerdeck.com

  • どんなひと?
    • コンピュータビジョンをやってる
    • faiss(facebook作の強いライブラリ)のwikiの図書いてる
  • 近似再近傍探索について話す
    • どのライブラリどの手法が良いのか?
      • 基本ベンチマークで見るのが良い
        • 横が精度縦が速度
        • 2020年3月現在はNMSLIBとNGTが競っている
        • 素晴らしいが、全部やっていると10時間以上かかる
    • annbenchというライブラリが良い
  • 感想
    • パラメータをその場でoverrideできるのは試行段階では便利そう

中川 裕太 氏 (株式会社ABEJA) 「リピーター分析における特徴量DBって研究課題満載でホントおもしろい!」

株式会社 ABEJA では顔特徴量をベースにしたリピーター分析機能を提供しています.ここで用いられている特徴量DBについて,非常におもしろい課題たちをモデルとシステムの両面から振り返り,特にモデルに関して具体的な解決策を紹介します.ここで触れた課題についてLT後にみなさんと深堀りできることを楽しみにしています!

  • ABEJAで提供しているリピーター分析に使っているDBの話
    • 特徴量DBの話
      • 特徴量DBとは?
        • 動画の顔を判定して、リピーターかどうか判定するサービス
        • 動画の顔を時系列で特徴取得-->リピーターかどうか見てる
      • 課題
        • 検索/更新の速度
          • GW(平時の10倍)やお盆は負荷が大きい
            • ぶっちゃけGWに負荷上がりすぎて障害発生-->盆までにどうにかしたい
        • 変更の容易性
          • 元々売れるか分からないサービスだったのでDBは簡素なものだった
          • 修正したアルゴリズムをデプロイすると再起動に丸1日
        • トランザクションの競合
          • 特徴量DBに並列で複数モデルからリクエストが
            • サービス成長に伴うリクエスト増加で段々きつく
            • readとwriteがかぶってデータ不整合
      • 解決法
        • 検索/更新の速度
          • 特徴量の工夫(今日はココだけ話す)
            • 元々-->任意のひとに紐づく特徴量に対して再近傍探索
              • しかし、リピーター分析では検索精度が大事
            • 近似ではなく検索対象を絞る
            • 特徴量をvon-Mises Fisher分布に従うように学習
              • 精度そのまま9.8倍早くなった
        • 変更の容易せい
          • ロジックとデータの分離
        • トランザクションの競合
          • 楽観的なロック
    • 今後
      • 構造がなさそうな空間でどう検索をスケールさせるか
        • CPUで殴ればスケールは可能
        • しかし、金がかかる

氏原 淳志 氏 (BASE株式会社) 「BASEアプリの関連商品の裏側」

BASEアプリではBASEを利用してるECサイトの商品を横断的に検索し購入することができます。よりよい商品探し体験のため、商品ページにはその商品に似た商品を表示しています。この類似商品がどのような仕組みで提供されていて、どのように運用されているかを紹介します。

  • BASE:ネットショップ作成サービス
    • 表示商品の類似商品を提示するシステム
  • 画像の特徴量
    • MobileNet
    • 事前学習モデルをそのまま使っている
    • 全結合層を取って使っている
  • テキストの特徴量
    • fastText&SCDV
  • 近傍探索
    • faiss
      • 圧縮の仕組みが用意されている
      • ドキュメント充実
    • 元々NGTだったがメモリを食う
  • 運用
    • 画像は事前計算、テキストはオンデマンド
    • データチームが作ったモデル等は基本APIで提供

澁井 雄介 氏 (株式会社メルカリ) 「メルカリ写真検索1年の歩み」

メルカリに写真検索の機能が追加されてからちょうど1年が立ちます。この機能がどういう仕組で提供されていてるのかやどのように改善されてきたかなどを、1年間の運用の中で起こった様々な感動秘話を交えて紹介いたします。

  • 汎用APIとしても提供(おそらく社内に対して?)
  • ざっくりとした処理の流れ

    1. 画像から物体検出
    2. 特徴検索(ベクトル変換)
    3. faissのindexから類似アイテムを探す
    4. アプリに結果を返す
  • AWSGCPで、かつk8sという剛健構成

  • 運用したての頃は障害多発
    • ログ/リトライ/監視が不足して障害切り分けができなかた
    • メインスレッドが落ちてもキューが残ってサブスレッドが落ちず、リトライもされず
  • 写真から類似の別商品を探すメルカリIMEがリリースされたて!

  • 感想

    • アプリでの類似画像検索の先駆けはメルカリだった気がするけど、裏ではだいぶマンパワーが頑張ってたんだなと思うと感慨深い

田口 雄哉 氏 (株式会社朝日新聞社)「ELMoで文脈に応じた類似キーワード検索システムを作った話」

朝日新聞社では、Qrichという四択問題を解くことで時事ニュースに触れてもらうクイズサービスを提供しています。従来は4択問題の選択肢を単語ベクトル (word2vec) を用いて検索していましたが、常に近傍の単語が同じため選択肢が固定されるという問題がありました。そこで、文脈に応じて類似キーワードを検索するシステムを作った話をモデル中心に紹介します。

speakerdeck.com

  • word2vecだと記事の内容に関わらず近傍単語が同じになる
    • 単語ベクトルは1単語に1ベクトルがあるのみで意味の多様性はない
    • BERTは時間がかかる
  • ELMoに乗り換え
    • bi-LSTMなので文脈が考慮可能
  • ELMoに読み込ませる記事の工夫
  • 近傍探索
    • 新語は人手でELMoの単語ベクトルを取得してインデックス追加・更新
  • 感想
    • どんなサービスでも新語への対応はベストプラクティスがなかなか出ない印象

全体の感想

  • 再近傍探索に詳しくないのでどの発表も新鮮だった
  • 自然言語処理の潮流が追えていなくてつらい
  • あとみんなfaiss

各発表者の方のスライドはそのうち公開されるそうなので、公開され次第追記します。