2018年02月の記事一覧

前の月  ||  次の月

ハーバードビジネススクールの学生からSansanの事業戦略について提案を受けました

こんにちは。人事部のびんです。

今回は、社内のとあるつながりから実現した、Harvard Business School(以下「HBS」)と行った取り組みについてレポートします。

HBSの2年生時の選択科目にImmersive Field Course(IFC)という体験型の科目があり、世界のさまざまな都市に学生が滞在し、現地企業のプログラムに参加するというカリキュラムがあります。

今回、日本からは複数企業がその対象となりましたが、カリキュラムで取り組むテーマが「アナログとデジタルの融合」ということもあってか、Sansanにも打診があり、HBSから4名の学生を受け入れることになりました。

2017年の11月頃から、Skypeなどを用いながら準備がスタート。1月3日~1月12日の期間(週末の3日間は東北地方を訪問)、学生4名が表参道本社のオフィスで行う成果発表に向けた調査を行いました。

9日間という短い時間ではありましたが、プログラムの実施期間中は、学生がそれぞれSansanのメンバーと交流を深めながら、ディスカッションを行い、プログラムに取り組みました。そして、最終日には代表の寺田をはじめとする役員が全員参加した場で、成果としてSansanの事業戦略についての提案を発表しました。

残念ながら、その発表についての詳細は公開することができませんが、当日に撮影した写真を一部掲載しますので、皆さまには最終日の雰囲気だけでも伝わればと思います!

DSC 1156 1 - ハーバードビジネススクールの学生からSansanの事業戦略について提案を受けました
DSC 1225 1 - ハーバードビジネススクールの学生からSansanの事業戦略について提案を受けました
DSC 1191 1 - ハーバードビジネススクールの学生からSansanの事業戦略について提案を受けました
DSC 1228 1 - ハーバードビジネススクールの学生からSansanの事業戦略について提案を受けました
DSC 1172 1 - ハーバードビジネススクールの学生からSansanの事業戦略について提案を受けました
DSC 1243 1 - ハーバードビジネススクールの学生からSansanの事業戦略について提案を受けました

発表後、HBSの学生とSansanのメンバーが記念撮影。無事に発表が終わり、今回の企画を担当した池西(写真下段、左から2番目)も安堵の表情を浮かべています。

最後に、今回の企画を担当した池西のコメントを紹介します。

担当者コメント

HBSの学生に対して、なかなか難しいトピックを題材として提示したこともあり、最初はどのような形で発表されるのか全く予想できませんでした。そういったこともあり、正直なところ心配していた部分もあったのですが、HBSの人的ネットワークを活用した準備のプロセスと最終提案の内容は、いずれも短期間でまとめられたものとは思えないほどのクオリティーの高さでした。発表を聞いたメンバーたちからも「さすが」という言葉が口々に出ていたほどです。

また、今回のプログラムに参加したHBSのメンバーは一様に、誰もが知っているような有名企業での就業経験を持っていました。今回の期間中、そういった企業での就業経験などについても、食事をしながら話を聞けたことは、とても貴重なものとなりました。

今後、Sansanは今まで以上に海外展開を加速させていきます。そんなSansanのメンバーにとって、今回のような機会は非常に良い刺激となるため、これからも積極的に取り組んでいきたいと考えています。

最終発表に参加した社員からは、さまざまな質問が飛び交い、発表の会場は熱気にあふれていました。「こうした機会を今後も定期的に作っていけるように動いていきたい」と、人事部一同で思っています。

そして、この場を借りまして、プログラムに参加されたHBSの学生の皆さん、サポートをしていただきましたHBS日本リサーチセンター長の佐藤様、プログラム期間中通訳を行っていただきました樋口様に感謝の言葉を述べさせていただきます。

本当に貴重な機会を提供くださり、ありがとうございました!

text: 伊東敏
2018/02/28

XGBoostにおける単調性制約について調べてみた

お久しぶりです。DSOC R&Dグループの中野です。

今回は、機械学習界隈の皆さんが大好きなXGBoostの一機能とProbability calibrationについて調べたことを報告します。

背景

社内で解釈しやすい決定木について議論する機会があり、勾配ブースティングのライブラリーであるXGBoostでは単調性制約を加えることができることを紹介しました。その場では、「指定した上下関係が満足される分割の中でゲインを最大にするものが選ばれるんですよ」と解説したのですが、それでは不十分だったことを最近になって気が付きました。

以下のように身長から体重を予測する例を考えてみましょう。あくまでも模式図なので、実際にこのような分割が起こるかどうかは、気にせずに見てください。

tree - XGBoostにおける単調性制約について調べてみた

1回目の分割では、「身長が低く体重の軽い」グループと「身長が高く体重の重い」グループが抽出されています。

問題となるのは2回目の分割です。「身長が低く体重の軽い」グループ内の分割、「身長が高く体重の重い」グループ内の分割は単調性があるのですが、上から2番目のグループと3番目のグループで重みが逆転してしまいました。

さて、XGBoostではどのようにして単調性制約を実現しているのでしょう。

実装の確認

単調性制約は、 src/tree/param.hValueConstraint 構造体の中で実装されているようです。当該ヘッダーファイルには、指定された閾値でデータを分割したときのスコア計算についての処理が記述されています(※コード)。

CalcWeight メソッドに目的の処理が書かれています。

if (w < lower_bound) {
  return lower_bound;
}
if (w > upper_bound) {
  return upper_bound;
}
return w;

lower_bound, upper_bound でノードに割り当てる重みを制限しているようです。これらの上限・下限は、少し下の SetChild メソッドで設定されていました。

if (c == 0)
  return;
/* 中略 */
if (c < 0) {
  cleft->lower_bound = mid;
  cright->upper_bound = mid;
} else {
  cleft->upper_bound = mid;
  cright->lower_bound = mid;
}

c == 0 は単調性制約なし、 c < 0 は特徴量に対してターゲットが単調減少する制約、 c > 0 は特徴量に対してターゲットが単調増加する制約に対応しています。
例えば c > 0 のケースでは、親のノードの重みの平均値を

  • 特徴量の小さい子ノードに対する重みの上限
  • 特徴量の大きい子ノードに対する重みの下限

として設定しています。

このような機構で分岐が深くなった場合でも単調性が保たれるようです。

実際にこの機能を利用するには、以下のようにパラメータを追加します。ここでは2列目の特徴量に対して単調増加、4列目の特徴量に対して単調減少としています。

param['monotone_constraints'] = '(0,1,0,-1,0)'
model = xgb.train(param, dtrain, num_round)

scikit-learnラッパーを用いる場合でも以下のように利用できます。

model = xgb.XGBClassifier(
    monotone_constraints='(0,1,0,-1,0)'
)
model.fit(x_train, y_train)

キャリブレーションへの適用

ここまでXGBoostの単調性制約について確認してみましたが、そのような制約をかけるのは「解釈しやすくするため」という理由が多く、精度向上を目指してXGBoostを使っていることとはマッチしません。

真っ当な適用先としては、分類問題におけるキャリブレーションが挙げられます。勾配ブースティングやディープラーニングのような高次元の学習器は、学習データに対するロスを殆どゼロにできるので、モデルが出力する確率も0%か100%に近く自信過剰なものになります。テストデータに対して、当然ながらそこまでの精度を出せないため、対数損失などで評価する際には、キャリブレーションという調整が必要になることが知られています。

下の図において、モデルの出力と実際の頻度における関係が理想的な青色の線から乖離しているのを補正します。scikit-learnのドキュメントの絵を見ると、下の図中で左のグラフに似た図がありますが、われわれが関心があるのは汎化性能なので右のグラフ、つまり検証のデータに対して補正をするのが正しいようです。元のコードでも検証データを相手にしています。1

calibration - XGBoostにおける単調性制約について調べてみた

キャリブレーションをするのに手軽な方法としてscikit-learnにIsotonic regressionが準備されています。
このIsotonic regressionとXGBoostによるキャリブレーションを比較してみましょう。

Isotonic regressionのscikit-learnによる実装は2乗誤差最小化をしているため、キャリブレーションには不向きかもしれません。一方で、XGBoostは調整できるパラメーターが多いことがネックです。

今回は、Kaggle Porto Seguro’s Safe Driver Predictionのデータを利用しました。コンペでは、Giniが評価基準だったためにキャリブレーションは不要でしたが、ここでは対数損失を見ることとします。

まずは、学習データ x_train, y_train を用いてベースのモデルを構築します。

clf = xgb.XGBClassifier(
    max_depth=5,
    learning_rate=0.05, n_estimators=500,
)
clf.fit(x_train, y_train)

次に、学習データとは別の x_valid, y_valid を使ってキャリブレーション用モデルを学習します。

p_valid = clf.predict_proba(x_valid)[:, 1]
# Isotonic regression
cal_iso = IsotonicRegression(out_of_bounds='clip')
cal_iso.fit(p_valid, y_valid)
# XGBoost
cal_xgb = xgb.XGBClassifier(
    max_depth=3,
    learning_rate=0.05, n_estimators=100,
    monotone_constraints='(1)'
)
cal_xgb.fit(p_valid.reshape(len(p_valid), 1), y_valid)

ベースモデルの出力値とキャリブレーションした確率は、単調増加の関係になることが期待されるので monotone_constraints='(1)' としています。

さらに、別のデータセット x_test, y_test に対して対数損失を計算した結果が以下になります。

xgb iso - XGBoostにおける単調性制約について調べてみた

今回のケースでは、XGBoostの方がキャリブレーションの性能が良くなりました。単調性制約がかかっているので max_depth, n_estimators は大きめの値を設定して問題なさそうです。

不均衡データかどうか、ベースモデルの性能などの諸条件によってどちらのキャリブレーション方法の精度が良くなるか、変わる可能性があります。私が取り組んだ別のタスクにはIsotonic regressionの方が良好だったものもあるので、比較して使っていくのがベターかと思います。

リンク

執筆者プロフィール

text: DSOC R&Dグループ 中野良則

  1. 勾配ブースティングとRandom forestでカーブの凹み方が逆なのは、興味深いです。Random forestでは弱学習器を並列にまとめているので出力が丸くなりやすいようです。 
2018/02/27

Pythonで書かれたOSSのコードを最適化してPull Requestがマージされるまで

はじめまして。2018年1月に入社した奥田(@yag_ays)です。

先日、scikit-learn-contribの1つであるCategory Encodersの最適化を実装したPull Requestがマージされたので、そこに至るまでのプロファイルや最適化の過程を紹介したいと思います。

普段、私の仕事は機械学習やデータ分析がメインで、あまりPythonの処理レベルで早いコードを書いたりすることはありません。もちろん最適化なんてことについては、あまり経験を持っていない素人なのですが、この記事が皆さんのプロジェクトを最適化する際の参考になれば幸いです。

tl;dr

  • scikit-learn-contribの中のcategory_encodersの実行速度を最適化した
  • Pythonのプロファイリングにはline_profiler、デバッグにはpdbが便利
  • Pandasのカラムをfor文で書き換えるコードを書くことはやめよう

Category Encodersとは?scikit-learn-contribとは?

Category Encodersとは、カテゴリ変数をさまざまな数値の変数に変換するパッケージです。機械学習において特徴量を作成する際には、多くのアルゴリズムはカテゴリ変数をそのまま扱うことができず、何らかの量的変数に置き換えて表現する必要があります。

そういったカテゴリ変数の変換手法を実装したライブラリーがCategory Encodersです。One-Hot EncodingやBinary Encodingといった定番の変換手法はもとより、Target EncodingといったKaggleなどの分析コンペティションにおいても使われる手法が多数収録されています。

さて、このCategory Encodersはscikit-learn-contribプロジェクトの1つに登録されています。scikit-learnは、Pythonで最も有名な機械学習のライブラリーですが、そのscikit-learnのAPIの流儀に従って実装されたライブラリー群がscikit-learn-contribです。本家ほどの知名度や利用者こそないものの、ニッチなアルゴリズムや本家ではできない実験的なコードが収録されています。

なんか遅くない……?

ことの発端は、仕事で新しく扱い始めたデータを加工しているときでした。数千レコードくらいのそれほど多くないデータセットだったのですが、Category EncodersでOne-Hot Encodingするのになんと1分近くかかるのです!

One-Hot Encodingのアルゴリズム自体がそんなに重いわけはないだろうと本家scikit-learnの似た機能で試してみると、当然ながら1秒以内に終わります。データ量であったり、エンコーダーに受け渡すデータ形式まで疑ったりしたのですが、何ら問題はなく、あれこれと考えるうちにたどり着いたのが、カテゴリー変数に含まれるカテゴリーの種類数でした。

どうやらカテゴリー変数に含まれるカテゴリーの種類が多くなると、処理が極端に重くなるようです。手元で簡単なコードを書いてみると、確かにカテゴリー数が少ないと一瞬で終わる処理がカテゴリー数を少し増やしただけで、途端に重くなってしまいました。

そのときの状況を擬似的なコードで表すと、以下のような感じです。

import category_encoders

# sample data
num_category = 1000
many_categories_list = ["category_{}".format(i) for i in range(num_category)]

encoder = category_encoders.OneHotEncoder()
encoder.fit(many_categories_list)

ここではサンプルのデータとしてmany_categories_listという変数に、カテゴリー数がちょうど1000個になるようなリストを作成しています。実際に上記コードを回してみると、カテゴリー数が5や10くらいだと問題ないのですが、1000や10000で試すと処理が重くなることを確認できました。

この問題に直面した当初は「もうCategory Encodersは使わずに、他のライブラリーを使うか、自分がスクラッチで書くか」と思っていたのですが、Category Encodersが便利なライブラリーであることには変わりなく、今後のことを考えると使わないという選択肢が惜しいことから、仕事を終えてから原因究明に取り掛かることにしました。

実行が遅い箇所をプロファイルする

まずはおもむろにコードを眺めますが、私はウィザードではないのでライブラリーの中のどのコードが遅いのか、検討がつきません。そこで「推測するな、計測せよ」という教えに従い、Category Encodersの処理の中でどの部分がボトルネックになっているのかを突き止めます。

がむしゃらに1行ずつコードを動かして確かめるのも一つの手ですが、Pythonにはさまざまなプロファイラーが存在します。そもそものコードの実行時間を図るtimeであったり、cProfileといった多機能なプロファイラーが標準で実装されていたりしますが、いろいろと試す中で今回はline_profilerというプロファイラーを利用しました。

line_profilerは、コードの行単位で実行時間や実行ステップ数などがプロファイリングできるライブラリーです。今回は、IPythonで利用できる%lprunというマジックコマンドを利用しました。

%load_ext line_profiler
%lprun -f category_encoders.OneHotEncoder.fit category_encoders.OneHotEncoder().fit(many_categories_list)

これを実行すると、以下のような結果が出力されます。

ここでは注目すべき部分だけを抜き出して表示していますが、実行結果にはcategory_encoders.OneHotEncoder.fitのコード全体が表示されています。また、各カラムの意味は左からLine #, Hits, Time, Per Hit, % Time, Line Contentsとなっています。

1254c852b0a58caace4991c233854ff7 - Pythonで書かれたOSSのコードを最適化してPull Requestがマージされるまで

これを見ると、どうやらOneHotEncoder.fit()が遅いのは、その内部で呼ばれているOrdinalEncoderという別のクラスが原因のようです。それでは、再度line_profilerを使って、今度はOrdinalEncoder.fit()の中身をプロファイルしてみましょう。

%lprun -f category_encoders.OrdinalEncoder.fit category_encoders.OrdinalEncoder().fit(many_categories_list)

59bd59ce8a9bfb34143d634229b997d2 - Pythonで書かれたOSSのコードを最適化してPull Requestがマージされるまで

今度は、OrdinalEncoder.fit()ではなく同じクラスに実装されているOrdinalEncoder.ordinal_encoding()の呼び出しに時間がかかっています。ここまで来ると、後は同じことの繰り返しです。ordinal_encoding()のプロファイルを取りましょう。

%lprun -f category_encoders.OrdinalEncoder.ordinal_encoding category_encoders.OrdinalEncoder().fit(many_categories_list)

3cc8af2b8da0d8cc005dd003ac6173f5 - Pythonで書かれたOSSのコードを最適化してPull Requestがマージされるまで

ようやく見つけました! この273行と274行のPandasのコードが、category_encoders.OrdinalEncoder().fit(many_categories_list)という1行の処理全体について処理時間の99%を占めていることが判明しました。ここが遅いために、この箇所を呼び出しているOne-Hot Encoding自体も遅くなっていたんですね。

動作が重い箇所の2カラム目にある実行回数を見てみると1000と表示されており、プロファイルで指定したカテゴリー数の1000と同じであることから、ここのコードはカテゴリーの数だけfor文が呼ばれていることが推測できます。

修正のためにデバッグする

さて、Category Encodingsの中で処理が遅い部分が特定できたので、今度はこの箇所を最適化して何とか実行時間を短くしなければいけません。しかし、私はこのパッケージの作者ではないので、このクラスの変数categoriesに何が格納されているのか、変数Xは何を示しているのか、すぐには理解できません。

そこで、デバッグのためにpdbという標準パッケージを利用します。

まずは、デバッグしたいOrdinalEncoderのクラスのコードをそのままコピペして、テスト用のソースコード(ここではslow.pyとする)を用意し、そのクラスの中で処理の重い行の手前にブレークポイントを設定します。この状態で実行することで、ブレークポイントまで処理が進んだ状態で一旦実行が停止され、そこからは対話形式で1行ずつ処理を進めたり、各種変数の値を確認したりすることができます。

ここでもIPython上でpdbを動かすことができるipdbを使います。

# slow.pyのOrdinalEncoderクラスの一部
categories = [x for x in pd.unique(X[col].values) if x is not None]
X[str(col) + '_tmp'] = np.nan
import ipdb; ipdb.set_trace() # here
for idx, val in enumerate(categories):
    X.loc[X[col] == val, str(col) + '_tmp'] = str(idx)

挙動を確認するのがデバッグの目的であり、プロファイリングのときのようにそれほど多くのカテゴリー数は必要ないので、カテゴリー数が4つのリストをサンプルデータにしました。

# slow.pyの実行部分
category_list = ["a", "b", "c", "a"]
encoder = OrdinalEncoder()
encoder.fit(category_list)

それではコードを実行してみましょう。すると、下記のように対話型のIPythonの画面が表示されます。出力されているコードを見ると、今は274行目まで実行が完了し、現在275行目のfor文で処理が停止していることが分かります。

$ python slow.py
> /Users/okuda/dev/github/categorical-encoding_orig/slow.py(275)ordinal_encoding()
    274                 import ipdb; ipdb.set_trace()
--> 275                 for idx, val in enumerate(categories):
    276                     X.loc[X[col] == val, str(col) + '_tmp'] = str(idx)

ipdb>

続いては、この状態で登場する変数の確認です。普段、IPythonを利用しているときと同じく、変数名だけを入力してリターンキーを押すと、その変数の中身を表示してくれます。categoriesにはカテゴリーの種類が、Xにはカテゴリーのリストに加えて、_tmpという行が新しく追加されていることが分かりました。

ipdb> categories
['a', 'b', 'c']
ipdb> X
   0  0_tmp
0  a    NaN
1  b    NaN
2  c    NaN
3  a    NaN

ここでは、for文は何をしているのでしょうか。pdbではnコマンドを入力するごとに、1行ずつ次のコードを実行することができます。for文を1回実行するために、2回nコマンドを入力し、改めてXの中身をのぞいてみましょう。

ipdb> X
   0 0_tmp
0  a     0
1  b   NaN
2  c   NaN
3  a     0

何となく処理の内容がつかめましたね。どうやら、カテゴリー名に対応する数字を新しいカラムに追加しているようです。aというカテゴリーはcategoriesの中で一番先頭だったので、ここでは0が0行目と3行目に代入されています。このまま処理を進めると、1行目のbには1が、2行目のcには2が入りそうですね。実際にやってみると、確かにそのような結果となりました。

最適化

ここまでのプロファイリングとデバッギングを踏まえると、下記のようなことが分かりました。

  • ordinal_encoding()内部のfor文が異常に遅いこと
  • for文の中では、カテゴリごとに番号を割り振って新しいカラムに代入していること
  • この部分を最適化すれば、処理時間を大幅に短縮できそうであること

次に問題となるのは、どうやってコードを修正するかです。こればかりは、経験と勘がものをいう世界かと思われるかもしれませんが、今回の場合はそうではありません。「Pandas for loop」みたいな感じでGoogle検索してみると、英語・日本語を問わず、多くの記事で「Pandasはfor文を使うと処理が遅くなる」と書いてあります。よくある落とし穴なんですね。修正の方法についても、丁寧に書かれている記事が多く公開されています。

そこで、今回はPandasのmap関数を利用して、列単位で「カテゴリー名aなら0、カテゴリー名bなら1……」といった操作を実装しました。細部は割愛しますが、問題点の最適化自体は下記のコード1行で済んでしまいました。

X[str(col) + '_tmp'] = X[col].map(lambda x: categories_dict.get(x))

この修正を踏まえて、いくつかのデータで実行した結果が元の実装のものと変わらないこと、Category Encodersのユニットテストを通して、最適化が問題ないことを確認しました。

なお、いくつかのPandasの高速化の記事を見ると、mapを使った別の書き方やNumpy Arrayを使ったベクトル化などで、より高速化を図れるような方法も紹介されていますが、今回はCategory Encodingsで実装されているコードとの整合性や可読性、修正箇所の少なさを優先して、上記の方法を採用しました。いろいろな部分を修正したくなる気持ちになりますが、1つの問題を解く際に他の問題を同時に解くことは望ましくありません。

最適化の結果

最後に、最適化によってどれくらい早くなったのか、処理時間を計測してみます。カテゴリー数が10、100、1000、10000の疑似データセットを作成して、元の実装と最適化後の実装、それぞれで処理を10回ずつ実行したときの平均処理時間を取ったのが、以下のグラフです。

9e619c5000181ec37e673b12fd38bfbf - Pythonで書かれたOSSのコードを最適化してPull Requestがマージされるまで

オレンジ色の線が元実装の処理時間、青色の線が最適化後の処理時間です。y軸のスケールが大きすぎて最適化後の処理時間がよく分かりませんが、とにかく大幅に短縮されていそうなことが分かります。実際に数字を見てみると、カテゴリ数10の場合では25ミリ秒→5ミリ秒と約5倍の高速化、カテゴリー数1000の場合に至っては85秒→0.025秒と約3400倍も高速化できていることが分かります。これで、大きなデータを処理する場合でも処理時間に悩む必要がなくなりそうです。

なお、ここで用いたコード全体は以下のgistから見ることができます。

https://github.com/scikit-learn-contrib/categorical-encoding/pull/58

Pull Requestと本体へのマージ

以上の結果を踏まえて、Category EncodersのGitHubからPull Requestを出し、無事にマージされました。

optimizing ordinal_encoding by yagays · Pull Request #58 · scikit-learn-contrib/categorical-encoding

2018年2月20日時点では、まだ公式アップデート前のためpipで更新することはできませんが、直接GitHubからインストールすることで試すことはできます。もしCategory Encodersの実行速度問題で悩んでいる方がいらっしゃれば、下記のコマンドで最新版をインストールして、試してみてください。

$ pip install git+https://github.com/scikit-learn-contrib/categorical-encoding

まとめ

いかがだったでしょうか? 今回は、Category Encodersというライブラリーを最適化する上での過程を紹介しました。こうやって書いてみるとあっさりしていますが、実際に試行錯誤しているときは、上手くいかないことばかりで結構大変でした。ただ、こうやって問題の発見から原因を突き止めて改善していくまでの一連の流れをプロファイリングやデバッギングの技術を駆使して解決していくことができたことは、とても良い経験になったと思います。この方法が最適化の全てではありませんが、もし何かのプロジェクトで最適化をしたいときには、参考にしていただければ幸いです。

執筆者プロフィール

text:DSOC R&Dグループ 奥田裕樹
2018/02/20

諦めずに向き合い続けた先に見える景色がある

こんにちは。人事部の河野です。

前回の記事では、Sansan初の長期インターン生の一人、松浦禎也さんとそのメンターを務めた社員へのインタビューを掲載しました。

今回は、同じく長期インターンシップでSansan事業部に配属されていた関根江里子さんと、長期インターンシップの責任者を務めた人事部の濱坂愛音へのインタビューです。

長期インターン生の中でも特に成果を出すことにこだわっていた関根さんが、今回のインターンシップでどんな苦労を乗り越えて、Sansanで何を学んだのか、聞いてきました。

Interviewee

まずはお二人のことを教えてください。

関 根 :慶應義塾大学経済学部3年の関根江里子です。学生時代の経験としては、大学の水泳部のマネージャーを務め、週4日朝練に参加するような水泳漬けの毎日でした。大学2年生時から企業の長期インターンシップに参加するようになり、最初は人材系の企業でお世話になりました。Sansanが4社目のインターンシップ先となりました。

濱 坂 :人事部新卒採用担当の濱坂です。Sansanでは、Sansan事業部の営業部での就労を経て、2016年12月に人事部へ異動しました。今回の長期インターンシップ企画の責任者を務めています。

ミッションドリブンな企業で働いてみたかった

今回、Sansanの長期インターンシップに応募した経緯を教えてください。

関 根 :理由は2つあります。一つ目の理由は、人材業界とは異なる業界でインターンシップにチャレンジしたかったからです。過去の原体験から、私は人材業界が抱える問題を解決したくて、人材系の企業で1年以上のインターンシップ経験を積んできました。とはいえ、このまま人材業界で生きて行くと決めるためには、一度は異なる業界に触れて、自分の決断に納得しているかを確かめることが必要だと思っていました。
二つ目の理由は、自分が創りたい会社の姿がSansanと重なっていたからです。将来、人材業界の課題解決をミッションとするような会社を創業するとき、社員全員がミッションに共感しているような会社を創りたいと考えていました。長期インターンシップの面接を受ける中で、Sansanは社員全員がミッション達成のために同じ方向を向いて働いている企業であるように感じました。ミッションドリブンな会社をどうすれば創ることができるのか、「この環境で学びたい」と強く思いました。

濱坂さんは、採用前に関根さんの面談を行ったそうですが、彼女のどんなところに魅力を感じましたか?

濱 坂 :初めて面談したときの記憶が鮮明に残っています。最初は大人しくて優しそうな女の子が来たなと思いました(笑)。しかし、話していくうちにその雰囲気と心の内に秘めた人材業界を変えたいという信念の強さのギャップに驚かされました。将来成し遂げたいミッションが、彼女の中に明確にあったので、どんなことでも歯を食いしばりながらやり切れるだろうと思いました。

DSC 8878 1 - 諦めずに向き合い続けた先に見える景色がある

「世の中の問題を解決したいというブレのない軸が関根さんの魅力」と語る、濱坂。

関根さんは、長期インターンシップの3カ月間でどんな仕事を担当しましたか?

関 根 :私に与えられたミッションは、「Facebookアプリの広告によってリードを100件獲得すること」でした。最初は広告に掲載する文言とバナー画像のレイアウトを作り、実際に配信してからはその運用まで行いました。また、広告配信を担当する一方で、Sansanの無料トライアルユーザーの動向も調査しました。リード化に至るまでの導線部分に課題を見つけ、UXの改善も提案しました。幸運なことに、アプリのリニューアルの時期と重なっていたため、アプリストアに掲出されるテキストの修正も経験することができました。

多岐にわたる業務を短期間で担当したんですね。今回のインターンシップ期間中で、特に大変だったことは何ですか?

関 根 :広告配信までのプロセスです。世の中に出せるほどの質の高い言葉をなかなか書くことができませんでした。案を何回出しても指摘を受けてしまい、何度も修正を繰り返しました。自分の不甲斐なさから、涙を流すこともありました。しかし、泣いていても前には進まないので、試行錯誤を続けました。結局、1本目の広告を配信するまでに1カ月以上の期間がかかりました。あの苦労の日々は、忘れられません。今、改めて当時の原因を振り返ってみると、Sansanの創りたい世界観に自分の理解が追いついていなかったことで、広告を通してターゲットに訴求するサービスの価値が曖昧になってしまっていたのだと思います。

自分から周りに働き掛け、機会を掴む

どうやってその苦境を乗り越えましたか?

関 根 :同じSansan事業部内の営業部に自らお願いをして、オンラインで行う商談に同席させてもらいました。商談に同席することで、どんなことに課題意識を持った方がSansanに興味を持たれたのか、潜在顧客層の考えを知ることができました。この経験によって、広告配信におけるペルソナ設定に手触り感を持つことができ、広告の質を高めることに結び付けました。また、業務以外の時間では、社員の方とランチに行くことで、社員の方々が自社のプロダクトに対して純粋に価値を感じて働いていることを知ることができ、Sansanという会社への理解も一層深まりました。

DSC 8804 1 1080x720 - 諦めずに向き合い続けた先に見える景色がある

3カ月のインターンシップを最後まで諦めずにやり切り、すがすがしい表情を浮かべる関根さん。

インターンシップの期間中、濱坂さんとは面談を実施したり、一緒にランチにも行ったりしたそうですが、関根さんの姿はどう写りましたか?

濱 坂 :ずっともがいていましたね。Sansanのお客様は、世界中のビジネスパーソンです。大学生の関根さんが経験したことのない、ビジネスパーソンの気持ちを考えて、広告を作ることは非常に難しかったと思います。しかし、彼女の負けん気もあって、社員に協力を仰ぎながらターゲットのイメージを膨らませようと行動している姿は素晴らしかったです。また、他のインターン生に対しても影響力を発揮していました。インターン生同士のミーティングでは、事前課題を自ら設定してミーティングの時間をより有意義なものにしようと、主体的に提案していました。どの仕事に対しても、前のめりになって、当事者意識を持って取り組む、彼女にとっての当たり前の基準が非常に高いと感じました。

本質的に価値がある仕事に、逃げずに向き合う

インターンシップで得られたことや学んだことは何ですか?

関 根 :業務面では、こだわりを持つ大切さを学びました。Sansanでは、文章の一言一句やデザインの美しさなど、細部にまで徹底的にこだわるようなカルチャーがあると感じました。効率性を重視しながらも、時間を掛けてでも本質的に価値があることに正面から向きあう姿勢は、これから仕事をしていく上で自分にとって一生の財産になりました。
自分の成長という観点では、自分の未熟さを知る機会になりました。最初の1カ月間は、自分で考えて行動するという自走ができず、社員の方がいないと仕事が前に進まないような状態でした。そのような弱い自分に気付かされ、人から指示される前に自分で走り出せるような力を身に付ける必要があると痛感しました。3カ月間の長期インターンシップをやり遂げたことで、周りに協力を仰ぎながら仕事を前に進めていく力が少しずつですが、身に付いてきた実感もあります。

今回のインターンシップでの成果は、どんな形で会社に貢献しているのですか?

濱 坂 :関根さんが発見した、無料トライアルユーザーのリード獲得導線における課題は、2018年卒の内定者に入社前課題として取り組ませています。現在は、彼女が導き出した仮説に対して、顧客にヒアリングを行い、仮説を立てながら検証している段階です。この課題については、3カ月という短い期間で解決できるほど簡単なものではありませんでしたが、Sansan事業部が着手したかった課題に対して、正面からメスを入れて向き合ってくれたことは、会社にとって大きな価値があることだったと思います。

DSC 8785 1 - 諦めずに向き合い続けた先に見える景色がある

インターン生が残した成果が会社の成長につながっていると、嬉しそうに語る濱坂

最後に、二人はどんな人にSansanの長期インターンシップをお勧めしますか?

関 根 :インターンシップを経験したことがない人と、逆にインターンシップを数社で経験していて自信がある人です。前者のような人については、仕事とは何かをまだ知らないまっさらな状態の内にこだわりを持って仕事をするくせが身に付けられることが非常に魅力的だと思います。後者のような人に関しては、熱量が高く、優秀な社員の方と一緒に働くことで「自分はちっぽけな存在なんだ、まだまだ力不足だ」という挫折を経験してもらい、自らで成長機会を勝ち取ってもらいたいからです。

濱 坂 :Sansanでは、ビジネスのためのビジネスではなく、世界を変えるためのビジネスを経験することができます。「紙の名刺」というビジネスにおける古くからの慣習と戦い、当たり前を塗り替えていくことの面白さややりがいを感じることができると思います。ミッションにひも付けて、市場を創っていくことにワクワクする方、世の中を変えたいと思う方にぜひ来てもらいたいです。

いかがでしたか? 今回は、長期インターン生の一人と長期インターンシップの責任者へのインタビューを通して、インターン生がどのように苦労を乗り越えて成果を出したのか、その成果が会社の事業へと貢献されたのかを紹介しました。

これから長期インターンシップ先を検討している学生の皆さんにとって、この記事が参考になれば幸いです。

interview & text: 人事部 河野淳平
2018/02/15

【Techの道も一歩から】第8回「API GatewayとAWS Lambda PythonでAPI開発」Vol. 3:エラー処理

こんにちは。DSOC R&Dグループの高橋寛治です。

WebAPIの勉強をしなければ! と感じる機会があり、思い立ったが吉日と、早速書籍『Web API: The Good Parts』を購入して学んでいるところです。

シリーズ3回目となる今回は、AWS Lambdaを利用したAPI開発の際のエラー処理について紹介します。

APIに求められるエラー処理

WebAPIを簡単に説明すると、WebAPIとはHTTPプロトコルにより提供されるAPIです。一般的にJSONが、クライアントとサーバー間で受け渡しされます。

どのようなエラー処理が必要になるかを考えてみます。

例えば、無効なJSONがリクエストされた際に、どのような情報があるといいでしょうか。

GithubのAPIの例ですと、HTTPステータスコードは400 Bad Requestを返し、JSONのmessageにエラーの詳細を記述しています(以下のコードは、Githubのマニュアルから引用しています)。

HTTP/1.1 400 Bad Request
Content-Length: 35

{"message": "Problems parsing JSON"}

HTTPステータスコードで、リクエスト内容にエラーの要因があることが分かり、messageを読むことで無効なJSONを投げたことが原因であると分かります。

HTTPステータスコードとmessageの役割を掘り下げると、HTTPステータスコードはクライアントのプログラムが受け取り、次の処理を定めるものと考えられます。それに対して、messageは、開発者が読み解くことのできるものとなります。

さまざまなWebAPIのエラー表現をまとめた素晴らしい記事がQiitaにありますので、先人の力を借りて、良いAPIを設計しましょう。

今回、作成するAPIは以下の仕様としました。

  • HTTPステータスコード
    • 200:成功
    • 404:無効なリクエスト
    • 500:内部エラー発生
  • JSONの形式
{
    "message": "メッセージ",
    "hogehogeResult": [何らかの結果]
}

AWS LambdaとAPI Gatewayでどのようにエラー処理を行うか

API Gatewayでは、Lambda関数が送出する例外に応じて、HTTPステータスコードおよびメッセージを設定できます。

以下のスクリーンショットは、API GatewayのPOSTエンドポイントの管理画面です。

api gateway 1280x466 - 【Techの道も一歩から】第8回「API GatewayとAWS Lambda PythonでAPI開発」Vol. 3:エラー処理

対応付けたいHTTPステータスコードの定義は、メソッドレスポンスで行います。

以下の図は、メソッドレスポンスに400, 404, 500を追加したものです(200はデフォルトです)。

44d29d2792be3bad9a9ed98c7bbb20d6 - 【Techの道も一歩から】第8回「API GatewayとAWS Lambda PythonでAPI開発」Vol. 3:エラー処理

次に、設定したHTTPステータスコードをLambdaの例外にひも付けます。ひも付けは、Lambdaエラーに対して正規表現マッチングを行います。

具体的には、PythonのExceptionクラスの__str__に設定された文字列表現が、正規表現の対象となります。

以下の図は、HTTPステータスコード404に対して、^[404:NotFound]$をひも付けたものです。正規表現のエスケープに注意してください。

0e4aae38a1f5494592124a884058f7cb 1145x720 - 【Techの道も一歩から】第8回「API GatewayとAWS Lambda PythonでAPI開発」Vol. 3:エラー処理

Pythonのコードでは、Exceptionクラスを継承し、__str__に対して、^[404:NotFound]$を記述します。

class NotFoundError(Exception):
    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return "[404:NotFound]"

ベストプラクティスかどうかは分かりませんが、404や500といった接頭辞を__str__に記述することで、正規表現として取り扱いやすく設定しました。

Lambda関数は実行時間の制限もあるため、制限時間を超える想定外の処理はエラーとしてハンドリングさせてみます。

正規表現は、(^[500:InternalServerError].*|.*Task timed out.*)となり、[500:InternalServerError]から始まるエラー、もしくはTask timed out.が含まれるエラーの場合に500エラーとなります。

戻り値のJSONは、本文マッピングテンプレートにより設定可能です。本文マッピングテンプレートのリファレンスを参考に設定します。Javascriptと似た記法のテンプレートになります。本文マッピングテンプレートを空にした場合、Lambdaのレスポンスがそのまま通過します。

以下のマッピングテンプレートでは、Lambdaから送出されたエラーメッセージ(Exceptionの__str__)を”message”にひも付け、結果は空を返します。

{
    "message" : "$input.path('$.errorMessage')",
    "hogehogeResult": []
}

Lambda側のエラーをどう設計していくか

ここまでで、API GatewayとAWS Lambdaを連携させた場合のエラーの取り扱いについて、流れが分かったかと思います。

私も悩んでいますが、正規表現マッチは1つのHTTPステータスコードに対して、1行の正規表現しか記述できないため、HTTPステータスコードのひも付けという枠組の中で、どのようにエラー処理を設計するかが難しいです(もちろん|により複数の正規表現を含めることは可能ですが、可読性は落ちます)。

コードで404や500と分かるような文字列を含めるとしても、どのレイヤーでHTTPステータスコードとひもづくエラーを送出するかの設計が難しいです。何かのモジュールを用いた場合は、そのモジュールが送出する例外をCatchして、__str__を設定する必要があります。

今、開発しているAPIでは、一つ一つの例外クラスに、[404:NotFound][500:InternalServerError]といった文字列を__str__にセットしています。404系エラーのクラスを作り、子クラスで具体的なエラーを定義するのも一つの手かもしれません。

もしかすると、たくさんの例外を考慮するようなLambda関数の利用が、そもそも設計ミスかもしれません。とはいえ、手軽にサーバーレスAPIが作れるため、使わないわけにはいきません。

使いやすいAPIを目指して

使いやすく、そして分かりやすいAPIを提供する上で、適切なメッセージやエラーコードを返すことは重要です。

今回は、WebAPIのエラーについて今一度考えた後に、API GatewayとAWS Lambdaを用いた際のAPIエラーの取り扱いについて紹介しました。

次回はデプロイについて紹介します。

執筆者プロフィール

過去記事

▼第7回
「API GatewayとAWS Lambda PythonでAPI開発」Vol. 2:ローカルでの開発環境構築

▼第6回
「API GatewayとAWS Lambda PythonでAPI開発」Vol. 1:API GatewayとAWS Lambdaを知る

▼第5回
快適なシェル環境の再構築を自動化する

▼第4回
第16回情報科学技術フォーラム(FIT2017)で登壇

▼第3回
第11回テキストアナリティクス・シンポジウム

▼第2回
R&D論文読み会勉強会

▼第1回
言語処理100本ノック勉強会

text:DSOC R&Dグループ 高橋寛治
2018/02/13

開発環境をより良く。社内制度「Geek Seek」Part 2

こんにちは。息子の影響もあり、「ひつじのショーン」が最近のマイブームな人事部のびんです。

今回は、エンジニアやデザイナーなど専門的な技術・知識を必要とする社員を支援する制度「Geek Seek」を紹介したいと思います! ……といっても、Geek Seekの紹介は2回目となり、1回目の記事はこちらで読むことができます。

前回の記事では、制度の概要とちょっとした利用例の紹介のみにとどまったので、今回はもう少しリアルな利用者の声をお伝えしたいと思います。

利用者の代表として、エンジニア、デザイナーとそれぞれ1名ずつにGeek Seekについてインタビューしました。

Geek Seekの利用について早速伺いたいと思いますが、まずは簡単に自己紹介してもらえますか。

高 橋 :Sansan事業部プロダクト開発部とビジネス開発部を兼務しています、エンジニアの高橋洸です。

友 近 :Eight事業部でプロダクトのデザインを担当しています、友近玲也です。

高橋さん、Geek Seekを利用してどんなものを購入しましたか?

高 橋 :書籍を何冊かと、有料のソフトウエアを購入しました。書籍は、主にKindle版で購入しているので、本で購入した書籍の数は少ないですが、他の社員と比較して利用頻度は高い方になるかなと思います。ソフトウエアは、開発に使うエディターやタスク管理のためのものを買いました。それらは、日々業務で使用しています。

DSC 1386 - 開発環境をより良く。社内制度「Geek Seek」Part 2

高橋がGeek Seekで購入した書籍の一部と購読に使用しているKindle。全体のうち8割ほどは、Kindleで購入して読んでいるとのこと。

(Geek Seekの利用状況を確認して)結構、買っていますね。エンジニアの方は、どういう時に書籍を買うんですか?

高 橋 :僕の場合は中長期的な視点で、考え方を学びたい時ですかね。技術的にすぐに知りたいと思うものは、正直ネットで調べちゃったほうが早いので。

他の利用シーンはありますか?

高 橋 :私の場合、2017年の10月からビジネス開発部という部署を新しく兼務したこともあって、技術本に限らずにもう少しビジネスよりのインプットを増やすためにも活用しています。ビジネス開発部では、新サービスの開発を少人数で行っていて、職種に関係なく議論を交わしています。そういったときに、ビジネスサイドの方(総合職)の会話レベルについていくのになかなか苦労したので、技術系以外の本もGeek Seekを利用して購入しました。その中でも『イノベーションと企業家精神(著:P. F. ドラッカー)』という本があって、これは良かったですね。エンジニアとして仕事をしてきたこともあり、正直なところビジネス的な観点からの知見はまだまだ足らないので、それを補ってくれています。

ソフトウエアも購入しているとのことですが、どのような利用を想定して購入しましたか?

高 橋 :業務効率を上げるあげるために尽きます。ソフトウエア開発を行うに当たって、コード管理を楽にするためのツールはたくさんあります。有料のものは機能も充実しているので使いたいと思うのですが、そんなときにGeek Seekがあると、試してみようと使ってみることに前向きになれますね。そのおかげで、いろいろなものを試しながら業務効率化はかなり進んだと思います。

DSC 1326 - 開発環境をより良く。社内制度「Geek Seek」Part 2

高橋は上司からも「かなりの読書家」と評価されている。向上心を後押しする制度として、Geek Seekの存在は貴重だと語ります。

デザイナーの友近さんはどうですか? どんなものを購入されました?

友 近 :僕は、書籍も購入しましたが、デザイナーが利用するハードウエアの1つであるペンタブやモバイル端末もGeek Seekで購入しました。

書籍についての利用目的は、エンジニアと近いですか?

友 近 :そうですね……。近いところもありますが、ちょっと違うところもありますね。デザイナーの場合、デザインの参考となるような絵を探すことがあります。エンジニアの場合だとネットで探してしまうという話でしたが、それについてはネットで探すよりも、書籍の方が分かりやすくまとまっているので、書籍から探すことの方が多いです。

モバイル端末ですが、会社支給のテスト端末でいいのでは? とも思ったのですが、具体的にどんな使い方をしていますか?

友 近 :スマホを日常的に使いながら、そこからユーザ体験を確かめたいと考えているようなデザイナーやエンジニアは多いです。部分的な確認であれば、確かにテスト端末でもいいのですが、他のサービスを試してみて自社サービスへのヒントが見つかることもありますので、さまざまな端末を日常的に持っていたいですね。例えば、iPhoneの最新機種を試したいとか、私用携帯はiOSなのでAndroidの動きを見てみたい、というような目的にも活用できます。

ペンタブって、デザイナーの方にとっては、メジャーなツールなんですか?

友 近 :そうみたいですね。最近、触れてないですけど(笑)。同僚は、結構使っているみたいです。これでプロダクトサイトや各種ランディングページに掲載されるイラストを書いたりしていますね。

DSC 1396 - 開発環境をより良く。社内制度「Geek Seek」Part 2
DSC 1334 - 開発環境をより良く。社内制度「Geek Seek」Part 2

Sansanでは、複数名デザイナーがペンタブを業務で利用している。

DSC 1310 - 開発環境をより良く。社内制度「Geek Seek」Part 2

デザイナーとして、Geek Seekという制度に価値を感じていると話す、友近。

今回は、実際にGeek Seekを利用している社員のリアルな声を聞いてみました。

今回の記事で挙がった、Geek Seekの利用対象は、書籍、ソフトウエア、ハードウエア、モバイル端末でしたが、その他にも同制度では勉強会や技術カンファレンスなどへの参加費用も補助しています。

これからも、社内のエンジニアやデザイナーには、日々のインプットや業務効率化を後押しする制度として、引き続きGeek Seekを上手に活用してもらいたいと思っています。

text: 人事部 伊東敏(びん) photo: 馬場健太
2018/02/08

【R&D beans】第11回 サシランチ企画 「新世界への挑戦」

こんにちは! DSOCの大木です。

最初からお詫びとなりますが、今回のサシランチ、実は2017年11月頃に行ったものです。公開まで時差があってすみません!!

そこで、今回のゲストである山本が現在は何をしているか、本編の後にチラ見せしたいと思います(面白い画像をもらうことができたのです!)。

それでは、サシランチ、始まるよ!

今回のゲスト

ゲスト:DSOC R&Dグループ 山本純平
入社歴:2年7カ月 (R&D歴は5カ月※インタビュー実施時)
エニアグラム:タイプ3「成功を追い求める人」、タイプ5「知識を得て観察する人」
ストレングスファインダー:着想、分析思考、戦略性、内省、適応性
大木CHECK:お気に入りの服は、カラー違いで持っている

お店:おもてなし 青山本店
ごはん:ランチにぎり(山本) 、イクラエンガワネギトロ丼(大木)


IMG 2420 1 - 【R&D beans】第11回 サシランチ企画 「新世界への挑戦」

山本が注文した、にぎりのセット。金目鯛のおすしもあります。

IMG 2419 1 - 【R&D beans】第11回 サシランチ企画 「新世界への挑戦」

お味噌汁や茶碗蒸しなども付きます。具がいっぱい!

大 木 :よろしくお願いします! 早速ですが、この企画では、いつもストレングスファインダーとエニアグラムを聞くところから始めてるんですが、ご自分のものを覚えてらっしゃいますか?

山 本 :調べてきました。

大 木 :優しい!

山 本 :ストレングスファインダーは、着想、分析思考、戦略性、内省、適応性。

大 木 :あ、着想! R&Dグループのメンバーは、持ってる人が多いです。

山 本 :エニアグラムは3と5なので、「成功を追い求める人」と「知識を得て観察する人」です。

大 木 :Sansanの社員に多い組み合わせですね! ご自身では納得感はありますか?

山 本 :3については「何かやっていないと気が済まない」というのがあるので、そこかなと。休みの日にも割と調べものをしています。

大 木 :確か、小さなお子さんがいらっしゃると思うのですが、お時間は作れるものですか?

山 本 :そうですね。朝の子どもが起きる前の時間や昼寝している間にやってます。R&Dに異動してきて、知らないことばかりなので、やばいなーと思って、頑張って勉強しています。ずっとやっていたアプリ開発の業務とは、全然違うので。

 

大 木 :Sansanに入る前は、どんなことされていたんですか?

山 本 :新卒で入ったのは、携帯関係の会社でした。その当時はガラケーだったんですが、メールとかブラウザとかを作っていました。携帯で動くブラウザっていうのを初めて作ったのは、その会社です。

大 木 :えー! すごいですね! 何年にご入社されたんですか?

山 本 :2001年です。

大 木 :ということは、高校生にも携帯が普及したくらいですね。1999年か2000年くらいまでは、液晶のバックライトが緑色とかオレンジ色とかだった記憶があります。着メロも最初は単音で、その後に16和音とか出てきて、自分で着メロの本を見ながら曲を入れてましたよね(笑)。

山 本 :入れてましたね(笑)。

大 木 :携帯が急激に進化していったころだったから、その業界にいたのは楽しかったでしょうね!

山 本 :そうですね。会社はすごく儲かっていました(笑)。それで、「携帯のOSを作るぞ」となっていって。

大 木 :オリジナルのですか?

山 本 :そうです。iOSとかAndroidとかは、まだなかったので。

大 木 :わ! 実現できたんですか?

山 本 :シリコンバレーとか行って作っていましたが、その間に大手企業などの介入があったりして、うまくいきそうもないなという感じになってしまいました。

大 木 :残念です〜。ずっとその会社にいらっしゃったんですか?

山 本 :その後は、6人くらいのスタートアップに転職しました。ソーシャルアドレス帳みたいなサービスを手掛けている会社で、6年くらいはいました。

大 木 :そちらでも開発をされてたんですか?

山 本 :そうですね。そこでは、iOSアプリとかを作ってました。

 

大 木 :なぜSansanに転職されたんですか?

山 本 :Webだけ、アプリだけに閉じている世界ではなく、実物とつながっている仕事がしたい、つまり「物とテクノロジーの両方に接点がある会社で働きたい」という思いがあったんです。かといって、そういう経験や知識はなかったんですけど……。

大 木 :Sansanに入られてからは、どのくらいですか?

山 本 :2年半くらいですね。R&Dに異動する前は、Eight事業部にいました。

大 木 :入社されて最初のころは、R&Dグループに興味はなかったんですか?

山 本 :いえ、実はオペレーション部(R&Dグループが属するDSOCの前身となる組織)に配属予定だったんです。

大 木 :え! そうなんですか。

山 本 :でも、内定が出てから入社までの間に、Eight事業部からEightのアプリ開発をやってほしいと言われて、まあいいかなと(笑)。

大 木 :いいんですか(笑)。

山 本 :そうですね(笑)。まあ、でもいつかはDSOCに行きたいとは、ずっと伝えていました。

大 木 :Eightは、Sansanと比べると新しいサービスなので、これからやれることが多くて魅力的でもあると思うんですが。

山 本 :そうですね。Eightには、スピード感があります。目まぐるしく状況が変わっていくので、そういうことが楽しめるとすごくおもしろいと思います。僕がDSOCに異動したのは、2017年の6月だったですが、11月にはエンジニアの人数が1.5倍に増えていて驚きました。

 

大 木 :Eight事業部では、どんなことをやられていたんですか?

山 本 :Androidのアプリを作っていました。

大 木 :そういえば、(山本)純平さんがKotlinの勉強会で登壇されていた記憶があります。

山 本 :Eight事業部のときはKotlinでしたけど、今はPythonを使ってます。

大 木 :Pythonは、もともと使われていたんですか?

山 本 :いえ、あんまり。

大 木 :では、新しく勉強し直してるんですか?

山 本 :まあ、そうですが、言語がどうこうというよりは、機械学習の理論などの方が比重としては大きいですね。

 

大 木 :R&Dグループでは、どんなことをやってるんですか?

山 本 :今は「会社の名寄せ」です。Aという会社とBという会社が同じか、それを判定するというものです。例えば「アシスト」っていう名前の企業は、日本に1000社くらいあるんです。

大 木 :多いですね(笑)!

山 本 :それを同じ「アシスト」っていう会社なのか、それとも違う「アシスト」っていう会社なのかを判断したいわけです。そんなときにどうするかというと、「住所が同じなら会社も同一だろう」という仮説を立ててみる。これで7割くらいは解決できます。でも、支店がたくさんあったりすると、住所は異なるけど同じ会社ってことになりますよね。そうしたら、メールアドレスのドメインに注目して、それが同じなら同一企業だろうって判断します。

大 木 :なるほどー。それって、名刺のデザインも判断材料に加えられないですか?

山 本 :次のステップは、そこになると思います。今はデータ化された文字列で判定してみています。

大 木 :人の目で実際の名刺を見れば、名刺のフォーマットやフォント、ロゴなんかで、大抵は判断できますよね。

山 本 :それを自動でできるようにするっていうのが、僕のやっていることですね。

 

大 木 :R&Dグループに異動されてみてどうですか?

山 本 :異動してからまもなくは、社会人になってから今までやって来たことが全て無に帰すぐらいに異なる分野だったので、本当に何が何だか分からなかったです。来たかったけど、来ちゃってどうしよう、というような感じです(笑)。

大 木 :ずっとアプリ開発のお仕事をされていたんですもんね。しかも、携帯アプリの草創期から。

山 本 :アプリはずっとやっていたので得意ですし、自分の強みだと思っています。でも、これから先を考えたときに、果たしてアプリだけをやっていていいのかと。大きな決断でしたが、R&Dに挑戦できて良かったと思います。全く新しいことをやらせてくれる会社って、そうそうないですし、楽しんでやっています。機械学習とか、データ分析をもっとちゃんとできるようになりたいですね。

大 木 :アクティブな思考ですね! 見習いたいです!

今回のまとめ

R&D内でのポジション:エンジニア出身なので「なんでも作れる」と頼られがち
属性:iOSもAndroidも得意なパパ
こぼれ話:「Kotlinイン・アクション」の翻訳に参加!


 

サシランチ本編は、ここまでです。ここからは、おまちかね「最近の山本!」のコーナーです。前置きはせずに、もう、すぐに見せちゃいます!

まずはこちら。

22147ec7a3efc6241439fa16720b8e2a - 【R&D beans】第11回 サシランチ企画 「新世界への挑戦」

Sansanの社員が交換した名刺の枚数を地図にマッピングしたもの。

Sansanの社員が交換した名刺の枚数が地図上で示されています。港区や千代田区の辺りにある企業と名刺交換(出会い)が特に多いことが分かります。

続いてはこちら。

sansan quicktime 4 - 【R&D beans】第11回 サシランチ企画 「新世界への挑戦」

Sansanの社員が行った名刺交換をリアルタイムでマッピングしたもの。

今度は動いてます!

これはある時間帯における、Sansanの社員による名刺交換の様子です。

Sansanには、表参道本社をはじめとして、大阪、名古屋、福岡などに支店を構えていますが、各拠点での名刺交換の様子がよく分かります。ここでは、社員の出張時の出会いも見ることができます。

このような名刺交換の分析を行うことが、DSOCの目指す「出会うべき人と出会える世界」への第一歩となります。

いかがでしたか?

更新が遅れてしまったおかげ(?)で、山本がサシランチ後にR&Dグループで何をしているのか、時系列に沿って感じてもらえたのではないでしょうか(ポジティブに捉えさせていただきます!)。

それでは、また!

text: DSOC 大木由香
2018/02/06

「たにくっしょん」を導入しました

こんにちは、デザイナーの山本です!

2017年、表参道本社内にある社員用のフリースペース「Stadium」に導入された、新しいクッションを紹介します。

その名も「Tanicushion®(たにくっしょん®)」。多肉植物をモチーフにしたクッションです(祝い花をモチーフにしたクッション「Ohanacushion®(おはなくしょん®)」も一緒に導入されました)。

導入数は……どどーん! と、約30個!

これだけの数をオフィスに導入したのは、Sansanが初めてとのことです。スペースに設置された木のベンチにもぴったりで、一気に雰囲気が明るくなりました。

室内緑化ツール「Tanicushion®」

tanicushion1 - 「たにくっしょん」を導入しました

グリーンのクッションが「Tanicushion®」、色鮮やかなクッションが「Ohanacushion®」です。

Tanicushion®は、多肉植物のユニークな形や魅力を再現した、室内緑化ツールです。

本物の植物とは異なり、水やりも不要(水をあげすぎる心配もなく!)で、いつでも生き生きとした多肉植物が癒してくれます。

多肉植物って、かわいいですよね。抱きしめたいと思ったことはありませんか。「ないよ……」と思った方もぜひトライしてください!

Tanicushion®は、表面の手触りも良く、ふかふかで程よいボリューム感なんです。国内の職人さんにより、一つ一つ手作業で作られていると聞いて驚きました。植物の有機的な形を再現するには手作業が必要なんだそうです。

多肉植物のかわいらしさはそのままに、トゲトゲを気にせずに、思う存分ぎゅーっとできる幸せを味わえます!

オフィス緑化でリラックス

tanicushion2 - 「たにくっしょん」を導入しました

膝とPCの間に置くのもオススメの使い方です。

Tanicushion®が導入されてから、Stadiumで作業やミーティングをする社員が増えたように感じます。

もともと植栽はいくつか置かれていましたが、クッションという実際に触れられるアイテムが置かれたことで、より植物が身近に感じられ、リラックスした状態で働けるようになったのではないでしょうか。

植物のことを知ってほしいから

tanicushion4 - 「たにくっしょん」を導入しました

Tanicushion®のシリーズの1つ、「アガベ 笹の雪」。インテリアとしても人気があるとか。

Tanicushion®には、プリントされた植物の学名が書いてあります。それは「植物について知ってほしい」という、Tanicushion®の発案者である鎌田美希子さんの考えによるもの。もし気に入った植物がプリントされていたら、ぜひ調べてみてください。自生する地域や育て方など、調べることで新しい発見があるかもしれません!

ちなみに、写真で紹介したクッションの「笹の雪(Agave victoriae-reginae)」は、乾燥に強く耐寒性もあるので育てやすい多肉植物だそうです。

Tanicushion®の発案者、鎌田美希子さん

tanicushion3 - 「たにくっしょん」を導入しました

鎌田さん(写真右から2番目)とクッション納品時に記念撮影。

Tanicushion®を生み出したのが、プランツディレクターの鎌田美希子さん。2018年からは、大学院博士課程にて植物と人の関係性の研究を開始するそうです。植物に関してアカデミックな知識を持ち合わせているという面も魅力的です。

鎌田さんにお会いすると、いつも植物柄の服を着ていらして、植物に対する並々ならぬ愛を感じます。ちなみに、ご自身が大切に育てている植物や、旅行先で出会った植物を撮影して、クッションにしているそうです!

Tanicushion®が体感できるイベントも開催!

来週2月9日に表参道で行われるICEが主宰する「ICE JAM」では、「Tanicushion®の間(ま)」として実際にTanicushion®を体感できるスペースが登場します!

ICE JAMに参加される予定の方、楽しみにしていてください!

ICE JAM -UXをシコウする-

Sample ICE JAM blog 1 - 「たにくっしょん」を導入しました

オールジャンルのクリエイターが集い、交錯する、実験的な一夜。ヒトの根源的な感覚、「みる」「きく」「ふれる」「あじわう」ことを通して、ユーザー体験(UX)の本質とイノベーションのヒントを探ります。

日時:2018年2月9日(金)18:00開場
会場:IDOL
住所:東京都港区南青山5-11-9 B1F
Tel:03-6427-4779

▼詳細
https://jp.corp-sansan.com/ice/icejam-2018

▼ICEの活動について
【AIインタビュー】ICEって何デスカ?

text: ブランドコミュニケーション部 山本真優 photo: 石野千尋山本真優
2018/02/02

自分の信念と行動が人を動かす

こんにちは。人事部の河野です。

先日は、Sansan初の長期インターン生の一人、山村真生さんに長期インターンシップに参加した感想をレポートしてもらいました。

今回は、同じく長期インターンシップでSansan事業部に配属されていた松浦禎也さんと、そのメンターを務めた社員へのインタビューを掲載します!

Sansanで実際に働いている社員と一緒になって、自分の頭で考え、体を動かし、形にするという経験を通して、そこにどんな苦労や成長があったのか、話を聞いてきました。

Interviewee

まずはお二人のことを教えてください。

松 浦 :早稲田大学政治経済学部3年の松浦禎也です。大学では、行動経済学を専攻しています。在学中には、ベトナムで日本語学校の立ち上げに参加し、僕自身も現地の学生に日本語を教えた経験を持っています。

志 賀 :Sansan事業部マーケティング部のコンテンツ企画グループでリーダーを務めています。コンテンツ企画グループは、マーケティングから営業段階までさまざまなシーンで活用されるコンテンツの企画・制作し、「Sansan」というプロダクトの価値や可能性をお客様へ伝える役割を担っています。

成果に正面から対峙して、自分の殻を破りたかった

Sansanの長期インターンシップに挑戦しようと思ったのは、なぜですか?

松 浦 :理由は、大きく2つありました。1つ目は、長期インターンシップの説明会で人事の方から伺った、「Sansanは、未来の当たり前を創造しようとしている」という点に興味を持ったためです。この組織に飛び込んで、「未来の当たり前を創造する」とは、どういうことなのか体感したいと思いました。二つ目は、自分自身の成長のためです。僕は、自分の考えを主張し、人を巻き込んで行動することに苦手意識を持っていました。長期インターンシップの説明会で「皆さん自身で考えて、成果を出してほしい」という言葉を聞き、その苦手意識を克服できるのでは、と感じました。

今回、松浦さんが3カ月間で取り組んだのは、どんな内容の仕事でしたか?

松 浦 :僕に与えられたミッションは、「Sansanとロボットを掛け合わせて、ロボットが名刺交換をする世界観を作ること。その第一歩目として、セミナー(Sansanが主催する)でロボットを活用すること」でした。具体的には、ミッション達成に向けたスケジュールの設計から始まり、情報収集のためにすでにロボットを活用しているセミナーに実際に足を運ぶこともしました。

このミッションを任せた背景には、どんなことがありましたか?

志 賀 :マーケティングとして、「Sansan=名刺管理」という認知は広く取れていると考えていますが、Sansanで名刺管理を行うことによって実現できる世界や、名刺というデータ自体にどのような価値が秘められているかについては、いまだ十分に知られていないという課題感を持っていました。だからこそ、Sansanの中で形成されるデータの価値を具体的に届けるようなコンテンツを作ることが必要だと、ずっと思っていました。
そのコンテンツを発信するシーンとして選んだのが、展示会です。展示会では、ブースを訪れたお客様へサービスの簡単な説明を差し上げたり、ニーズや課題などをヒアリングを行う機会があります。ただ、展示会のブースで応対する担当者は、すでに会社間で接点を持っていた場合であっても、必ずしもそのブースに来訪された企業を担当している担当者ではないわけです。展示会で名刺交換した際に、現段階でその会社と取引があるのか、あるいは案件として商談が進んでいるのか、社内の誰かと接点を持っているのか……など、そうした来訪された方の企業に関するさまざまな情報が即座に分かれば、より興味を引き出すこともできるかもしれませんし、お客様にとって有益な情報を提供できるかもしれない、と思ったのがきっかけです。応対する際に、お客様が目の前にいるにもかかわらず情報を検索しながら応対することは失礼と感じる方もいらっしゃると思いますが、例えばSansanをはじめとした、さまざまな顧客情報のデータをロボットに連携させておき、展示会でロボットに名刺交換させて来訪者の企業にひも付いた情報を呼び出し、最新のステータスを把握した上で会話をさせることで、ゼロからの説明やヒアリングすることなく、応対者によらない具体的かつ個別的な会話ができ、スピーディーにその後の商談へつなげられる可能性が出ると考えました。そうすることで、名刺交換という出会いに潜在する価値をその場でリアルに感じてもらうことができれば、潜在顧客層へ新たな価値が提供できる、と考えました。この仮説を検証するに当たっての最初の段階として、自社が主催するセミナーでのロボットの活用を検討することとなりました。

DSC 8628 - 自分の信念と行動が人を動かす

Sansanに蓄積されたデータとロボットを掛け合わせることで新たな価値を提供することできると、語る志賀。

答えのない問いに向き合う難しさ

松浦さんは、このミッションに取り組んでみて、どんなところが大変でしたか?

松 浦 :新しい取り組みであったため、どこから手を付ければ良いのか分からず、まず何をすべきかを考えることがとても大変でした。自分なりに企画しても欠点が見つかるばかりで成果に結び付かず、失敗の連続で気持ちを前向きに保つことも難しかったです。しかし、弱音を吐いてばかりでは前に進みませんので、企画を改善する糸口を見つけるために、志賀さんをはじめ、他部署の方にも何度もヒアリングを行って、泥臭く情報を取りにいきました。そういった試行錯誤を繰り返しながら、最終的にSansanが主催するセミナーでロボットに5分程度のプレゼンテーションをさせることができた時には、大きな達成感が得られました。

社員を巻き込みながら仕事を進めたのは素晴らしいですね。志賀さんには、松浦さんの苦労はどのように映っていましたか?

志 賀 :正直、想定したとおりでしたね(笑)。実際のビジネスを経験していない学生の段階で、顧客情報や取引先に関するデータがビジネスシーンにおいてどんな価値を発揮するのかをイメージすることは、かなり難易度が高いですから。「Sansanというプロダクトに蓄積されるデータに秘められた可能性」という抽象的なものについて企画を考えて、それを実行するというプロセスに苦労しているようでした。

自分自身で考えて、やり抜いてもらいたかった

苦労している松浦さんに対して、志賀さんはどんな距離感で接していたのですか?

志 賀 :最初は、彼の様子を見ていました。彼自身、自分で考えて行動して何かを生み出したいという目的意識を持っていました。その目的意識を生かして彼の成長を促したいと思っていたんです。もちろん、私が手取り足取り教えてあげることはできますが、それをしてしまうと、彼自身が企画内容を考え、手段を模索するプロセスが抜けてしまい、結果的に成長機会が失われると思いました。私は、実現したいゴール、世界観を繰り返し説明し、彼自身がどう考え、実行していきたいか問いかける一方で、チームのメンバーには松浦さんに積極的に声を掛けてもらい、行き詰まってないか、行き詰まっているのだとすれば具体的にどこで困っているのかフォローしてもらうことで、上手くバランスを取りました。また、分からない点に関してインプットが必要となったときにも、チームのメンバーはサポートしてくれていました。

役割分担をして、松浦さんとの距離感を意図的に変えていたんですね。メンターとの距離感の話が出ましたが、松浦さんにとって志賀さんはどんな存在でしたか?

松 浦 :Sansanのお母さんのような存在でした(笑)。少し離れたところにいるのですが、僕が本当に困ったときには手を差し伸べて下さったので、「成果を必ず残す」という目標に向けたモチベーションアップにつながりました。悩みすぎて地に足が付かず、目の前のことに集中できていなかったときに、散歩しながらミーティングを行っていただいたときには、精神的に助けられました。

DSC 8622 - 自分の信念と行動が人を動かす

屈託のない笑顔で志賀のことを「Sansanのお母さん」と、話す松浦さん。人の話を聞き、それを自分の糧に変える素直さが、彼の魅力です。

「Sansanのお母さん」と言われていますが、どうですか?

志 賀 :そうですね~。どちらかというと私は、背中で示すお父さんタイプだと思います(笑)。チームの他のメンバーたちが、面倒見の良いお母さんのような立場でしたね。

自分が正しいと思うことをまっとうする

志賀さん以外にも現場社員とコミュニケーションを図る機会は多かったと思うのですが、Sansanの社員から学んだことで印象的なことはありますか?

松 浦 :社員の方それぞれが自分の信念を持って働いているように感じました。特に新卒入社2年目の方から聞いた、「上司の指示に従って仕事をこなすだけでは意味がない。自分が正しいと思うことを発信し、違和感がある時には腹落ちしていないと言えることが大切」とアドバイスを頂いた時には目からうろこでした。それまでは周りから言われたことを愚直にやることばかりを考えていた自分でしたが、自分の考えに自信を持って、自分が違うと判断した際には勇気を持ってそれを周りに伝えていくようになりました。

志賀さんから見て、この3カ月で松浦さんはどんな成長を遂げたと思いますか?

志 賀 :言語化する力は、かなり磨かれたと思います。当初は、漠然とよく分からないと言っていて、どこまで分かっていて、何に行き詰まっているのかを明確に説明できていなかったように思います。私やメンバーのサポートを受けながら、自分が理解している範囲と理解できていない範囲を整理して、言語化していくことを繰り返すことで、最後には自分の納得できていない部分がどこなのかをきちんと言語化して、課題解決をスピーディーに行えるところまで成長したと思います。この力は、ビジネスの場面ではとても重要視されるものですし、自らに考えられる力を付けたいというのは、今回の長期インターンシップに参加した目的の1つでもあったと思いますから、その点で素晴らしい成長を果たしたと思います。また、実務面では、マーケティングの醍醐味を感じてもらえたとも思っています。顕在化していない価値を世の中に届けることがマーケティングの役割の一つです。まだ見ぬ価値だからこそ、誰にどうやって届けるのか、試行錯誤し続けることの難しさや面白さを体感してもらえたのではないかと思います。

DSC 8676 - 自分の信念と行動が人を動かす

松浦さんの3カ月間の成長を嬉しそうに話す志賀。その話に松浦さんと私もついつい嬉しくなってしまいました。

周りを巻き込むことで大きなことを成し遂げられる

松浦さんにとって、仕事に対する考えに変化はありましたか?

松 浦 :周りを巻き込むことの大切さを学びました。正直、自分一人の力だけでは何もできなかった、というのが本音です。そんな中で、自分から社員の方をランチに誘って、Sansanが持つデータの価値についての話を聞いたり、自分が担当している仕事についてディスカッションをしたりすることで、段々と周りの人が協力してくれるようになりました。困ったときにはアドバイスを頂くことができるようになり、自分が持っている1の力が10、100へと大きくなったような感覚がありました。成果を最大にするためには、自分の信念を持って人と接し、多くの人を巻き込むことが必要なことなのだと実感しました。

最後に、二人はどんな人にSansanの長期インターンシップをお勧めしますか?

松 浦 :挑戦心と目的意識を持った人です。新しいことに取り組みたい、世の中を変えることを体感したい、と前のめりの姿勢で飛び込んでいくことができる人であれば、その思いを形にできるフィールドはあると思います。インターンシップ期間中は、悩むことや心が折れそうになってしまうこともあるかもしれませんが、「なぜインターンシップに挑戦したのか」、自分の原点に立ち返って自問し続けながら、粘り強く取り組むことが大切だと思います。

志 賀 :パッションに尽きますね。「世の中を変える側に行きたい」。この気持ちをどこまで本気で思えるか。インターンシップでは、諦めずにやり続けることが何よりも大切で、苦しいときに踏ん張れるかどうかは、パッションの強さによって大きく差が出ます。イノベーションを起こしたいと強く思っている学生の方にぜひ挑戦してもらいたいです。

いかがでしたか? 今回は、インターン生とそのメンターへのインタビューを通して、長期インターンシップに参加した学生が3カ月間でどんな苦労を乗り越え、成果を出し、学びを得たのか、そしてメンターとして彼を支えた社員の声を紹介しました。これから長期インターンシップ先を検討している学生の皆さんにとって、今回の記事が参考になれば幸いです。

interview & text: 人事部 河野淳平
2018/02/01