雲をつかむ統計。

確率・統計・機械学習・深層学習を紹介するブログ

2019年を振り返り

f:id:Beluuuuuuga:20191231020928j:plain

はっきり言ってポエムですが、内省のために書きます。ざっくり振り返ってみたいと思います。

2019年にあった大きな変化

転職

  • 新卒で入社した大手メーカーの研究所を1年ほどで退職し、2019年の3月からITベンチャーで働きはじめました。
  • 1社目では、人工知能の研究ができると人事に言われ半ば騙されたような形で、ろくに調べもせず入社してしまいました。同期が僻地の工場や、海外の劣悪な環境へと送られる中、VRなどを駆使した工場の最適化のためのシミュレーションに取組み、社内の中では面白そうなプロジェクトにアサインされました。チームにも恵まれ、日経記事にも取り上げていただきました。しかし、社内政治的なものに巻き込まれるなどして、3ヶ月ほど取り組んだシミュレーションモデルがボツになることや、スキルとしてCADを駆使したCAEなど汎用的な能力であるのかの疑問、直属のトレーナーによる度重なる大声の叱責(字の汚さなど)、給料の低さ(私にとって)など退職するには十分すぎる理由が私にとってありました。また、元々人工知能機械学習を扱ったプロジェクトに携われると聞いて入社したのに、どうなっているんだと部長に尋ねたこともありましたが、よくわからない答えが返ってきたりなどしたため、入社して半年ほどで転職しようと決意しました。

退職

  • 2社目では、サーバーサイドエンジニアとして主にクローラー開発・サーバー保守を中心に行い、1年ほどでどのようなクローラーでも作れるほどになりました。Webの知識がほとんどない状態・Gitの経験なし・プログラミング経験ほぼなしで入社したため、入社してから2ヶ月は辛かったですが、次第に慣れました。年収も100万ほどアップします。初心者エンジニアをここまで育てていただき感謝しています。
  • 入社して半年ほどすると、機械学習を利用した尖った技術に惹かれ入社したはずが、実際に取り組んでいたのはクローラー作りであること・技術としてクラッカーに近い技術が向上し面白いが汎用的でないこと・1年以上在籍しても業務の中で得られる技術がないなどのエンジニアリング的な不満がだんだんと出てきました。また、その他の不満では、ベンチャーでありながらトップダウンで意見が言いにくい社風、技術的に難しいクローラーであるのでブロックされることやクローラーが停止してしまうことが頻繁にあり、その場合休日対応などがありました。休日対応に関して、当時ほぼ毎週4時間は対応しており、デート中にクローラーを修正するなど日常茶飯事でしたし、私以外対応できる方がいなかったので、辛いものがありました。品川の水族館でクローラー修正した時は、さすがに泣きたくなりました。
  • そんな時、仲の良い友人の転職が上手くいき年収が大幅にアップしたことを聞きました。その友人は、データサイエンティストで転職しており、データサイエンティストとしてのキャリアはあまりない状態での転職でした。お付き合いしている方から、年収や労働環境から転職を勧められていたことと、友人の転職が上手くいったこともあり、入社8ヶ月ほどで転職活動を開始しました。当時、残業時間が月50時間ほどで私にとって長かったことや、毎週土日の対応で精神的には参ってしまっている状況での転職でした。
  • 2社目の転職活動は割とスムーズでしたが、短期離職を2回もしてしまうため、3社目の面接は困難を極めました。また、データサイエンティストとして面接を受けたことも面接通過を難しくしてしまっていました。書類はほとんど落ちてしまう状況の中、外資コンサル・大手ECサイト・大手メーカーの3社で最終面接まで通過します。外資コンサルでは、短期離職の疑いありで落ちてしまい、大手ECサイトでは、CS専攻であれば常識であろう知識が答えられないことが理由(私は物理専攻)で落ちてしまいました。幸い大手メーカーで機械学習エンジニアとして転職することができました。1社目や2社目のような失敗はしたくなかったので、面接を受ける中で、こちらから具体的かつ詳細に質問を行いミスマッチがないようにしました。年収も大幅アップしました。

技術力

  • エンジニアリング的には、以下の技術を習得することができました。
  • Git・Rubyでのプログラミング・Webエンジニアリングの知識・サーバーなどの低レイヤーの知識・あらゆるクローラーの作り方・リファレンスなどの読み方・コードの綺麗な書き方・サーバー保守の方法(ボトルネックの特定と対処)・闇の技術

仕事に対する考え方

  • 以下は、2019年で仕事を通して得た考えです。
  • 自分の性質的に、エンジニアリングでは大成しない
    これは、エンジニアの方(2社目)がバグや技術的に上手く行かないときに世に転がっている手法を吟味することなく試す姿勢を見て感じました。その手法で成功したとしても、なぜ上手くいくのか考えない・もしくはあまり考えない方が多くいたように思います。私はそのような姿勢よりも、性格的には数式などのバックグラウンドから理路整然と説明できる事象が好きであり、エンジニアリングでもそれを求めてしまい、進捗が悪かったこともありました。また、新しい技術が世に出たとしても、正直あまり興味が持てません。Rubyのバージョンが上がったからなんだ?という感じです。新しい機械学習の論文がパブリッシュされたりすれば、数理なので興味をもち高いモチベーションで読むことができます。以上のように、エンジニアリングの姿勢とエンジニアリングに対する興味の無さからエンジニアリングで大成することは恐らくないので、今後も数理を生かした職に就こうと考えています。
  • どういう仕事をどういう環境でしたいのか
    具体的には、数理に携われる・プログラミングが書ける・社外でも通用するスキルレベルを得れる・コミットしやすい・大声で叱責しない上司がいる・少ない残業時間・コミュニケーションが取りやすい環境などが挙げられます。興味としては、上記のように数理を生かした仕事ですが、自分は8つの知能でいうところの対人知能が高いと1社目・2社目で評価されたので、エンジニアではなく数理と対人折衝の多いコンサルの方が向いているような気もします。もしくは、教師・宗教家など。

おわりに

  • 2年ごしでデータサイエンティスト(機械学習エンジニア)となれたので、職に就けるか悩んでいる方への助けになればと思います。
  • 2020年は、資格(基本情報・応用情報・統計検定)や、競技プログラミング、数学鍛えて行きたいです。

サイズの異なる同一広告画像の類似度計算

はじめに

画像サイズの異なる同一広告画像の類似度を計算します。2値化などの処理で、固有のhash化したかったですが、失敗しているのでヒストグラムにして類似度計算します。

コード

  • ライブラリ読み込み
from PIL import Image
import cv2
import matplotlib.pyplot as plt
import numpy as np
  • 画像出力
img1 = Image.open('050691a1f51049c4628acef8c65c453e.jpg')
img1

f:id:Beluuuuuuga:20191104203406j:plain

img2 = Image.open('674173f003d2ff9b7e1cc07e2d4746ce.jpg')
img2

f:id:Beluuuuuuga:20191104203426j:plain

  • 画像サイズ確認
img1_size = img1.size
img2_size = img2.size
print(img1_size, img2_size) #=> (796, 416) (480, 251)
  • 方針: 128*128にresize、グレースケール化、 収縮膨張処理を加えて同一画像を作成
# 画像1枚目
# 入力画像の読み込み
img = cv2.imread("050691a1f51049c4628acef8c65c453e")

#リサイズ
img = cv2.resize(img , (128,128))

# グレースケール変換
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

# 方法2 (OpenCVで実装)      
kernel = np.ones((10, 10), np.uint8)
opening1 = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
opening1 = cv2.morphologyEx(opening1, cv2.MORPH_OPEN, kernel)
opening1 = cv2.morphologyEx(opening1, cv2.MORPH_OPEN, kernel)
# 結果を出力
cv2.imwrite("img1.jpg", opening2)

import cv2
import matplotlib.pyplot as plt
import numpy as np

# 画像を読み込む。
img = cv2.imread("img1.jpg", cv2.IMREAD_GRAYSCALE)

# 1次元ヒストグラムを作成する。
hist1 = cv2.calcHist([img], [0], None, histSize=[256], ranges=[0, 256])
hist1 = hist1.squeeze(axis=-1)

# 描画する。
fig, ax = plt.subplots()
ax.fill_between(np.arange(256), hist1, color="black")
ax.set_xticks([0, 255])
ax.set_xlim([0, 255])
ax.set_xlabel("Pixel Value")

f:id:Beluuuuuuga:20191104204145p:plain

# 画像2枚目
# 入力画像の読み込み
img = cv2.imread("674173f003d2ff9b7e1cc07e2d4746ce")

#リサイズ
img = cv2.resize(img , (128,128))

# グレースケール変換
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

# 方法2 (OpenCVで実装)      
# Opening 収縮 膨張3回
kernel = np.ones((10, 10), np.uint8)
opening2 = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
opening2 = cv2.morphologyEx(opening2, cv2.MORPH_OPEN, kernel)
opening2 = cv2.morphologyEx(opening2, cv2.MORPH_OPEN, kernel)

# 結果を出力
cv2.imwrite("img2.jpg", opening2)

# 画像を読み込む。
img = cv2.imread("img2.jpg", cv2.IMREAD_GRAYSCALE)

# 1次元ヒストグラムを作成する。
hist2 = cv2.calcHist([img], [0], None, histSize=[256], ranges=[0, 256])
hist2 = hist2.squeeze(axis=-1)

# 描画する。
fig, ax = plt.subplots()
ax.fill_between(np.arange(256), hist2, color="black")
ax.set_xticks([0, 255])
ax.set_xlim([0, 255])
ax.set_xlabel("Pixel Value")

f:id:Beluuuuuuga:20191104204206p:plain

# ヒストグラムの類似度計算
similarity = cv2.compareHist(hist1, hist2, 0)
similarity #=> 0.8378211241010926

おわりに

  • 類似度0.83のスコアでした。DB内で検索しようと思うと、勾配のインデックスなど作成すれば良いのでしょうか。とりあえず、今日はここまでです。

参照資料

Rustインストール

はじめに

カールコマンドを使用してインストール

$ curl https://sh.rustup.rs -sSf | sh

パスを設定

$ source $HOME/.cargo/env

$ export PATH="$HOME/.cargo/bin:$PATH"

テストスクリプトを作成

$ vi main.rs

fn main(){
    println!("Hello world");
}

プログラムを実行

$ rustc main.rs

$ ./main

資料