astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

マーケティングとエンジニアとの関わりについて

はじめまして。 アスタミューゼで事業開発・マーケティングを担当しているボーダー☆キングと申します。開発部長の並河さんより、当ブログの執筆という大役を頂きました。緊張しています(笑)。

参考)この人形が執筆者に廻ってきます…。(通称:白い悪魔) f:id:astamuse:20180117185726j:plain

このブログはエンジニアとデザイナーのブログなので技術的なお話が多いと思うのですが、今回は趣向を変えて、企画からリリースまでのマーケティングとエンジニアの関わりや、ベンチャーならではの関わり方だなー、と思ったことについて記してみたいと思います。

1.簡単な略歴

その前に、私の経歴について触れておいた方が判りやすいですかね。
私はアスタミューゼが3社目の会社になります。

1社目:リクルート
リクルートでは、WEB商品を中心に新規商品の策定などを行っていました。割とヒットしたのは「街の不動産屋さんでも扱える、簡単CMSツール」というコンセプトで企画・開発した「ホームページサービス」でしょうか。担当した1年で年間売上1.5億の商品になりました。

例)ホームページサービス
https://business.suumo.jp/chintai/lineup/hpservice.html f:id:astamuse:20180117185921j:plain

【企画にあたり、主にやったこと】
・競合調査と商品優位性の規定
・Information Architectureとワイヤーフレーム作成
・営業とエンジニアの間に立っての仕様調整
・既存物件DBとの繋ぎこみ設計

2社目:カカクコム
カカクコムでは、商品比較サイト「価格.com」のコミュニティ担当としてサイト改善やリニューアルを担当していました。大きい仕事では「ランキングページの8年ぶりのリニューアル」ですかね。リリース後、ランキングページのUUを1.2倍まで持って行くことに成功しました。

例)ランキングページ
http://kakaku.com/kaden/lcd-tv/ranking_2041/ f:id:astamuse:20180117190035j:plain

【企画にあたり、主にやったこと】
・ユーザーヒアリングに基づいたコンセプト設計
・ワイヤーフレーム作成
・各画面の詳細仕様設計と策定
・エンジニアとの仕様調整

アスタミューゼでは「転職ナビ」というサービスを主に担当しています。
過去に企画で行ってきた作業をベースにしながら、顧客対応や各種有料集客施策といったフロントの部分から売り上げを最大化するための運用面まで幅広く見渡しながら日々過ごしています。

2.転職ナビとは

「転職ナビ」とは、様々な特許情報や技術情報を持っているアスタミューゼが、そこに携わる人材の支援もトータルで行いたい、という思想で生まれた転職サイトです。2010年のサービスを開始より、今では年間あたり3万人以上の登録を頂くサイトに成長しています。

indeedやDODAといった大手の総合型のサイトと異なる強みは何か、というと特定の技術分野に特化していることがひとつとして挙げられます。

例えばですが
 ・有機EL転職ナビ
 ・核融合転職ナビ
 ・Scala転職ナビ

f:id:astamuse:20180117192848j:plain
一例)Scala転職ナビ
といった、かなりニッチな(笑)サイトが400近くあります。
「転職ナビ」はScalaを開発言語で活用していますが、Scala転職ナビ経由で登録された方は確実にその言語に対する技術を持っていらっしゃるため、総合型サイトと比較しても格段のマッチング精度で募集することが出来る、いうことがプロダクトとしての強みだと思います。

3.転職ナビのビジネスモデル上の課題

次は、転職ナビのビジネスモデルとその課題についてご説明します。
転職ナビはサイト毎にパーソルキャリアやジェイエイシーリクルートメントなどの大手人材紹介会社と提携をしており、基本的にサイト毎の提携先に登録者を紹介させて頂いています。
ただし、紹介した方が既に他のルートで人材紹介会社に登録済みの場合、他の提携先に送客させて頂く場合があり、それは登録者全体の3割程度が該当します。
年間にすると1万人程度の人数となり、その方たちには他の提携先の求人状況やサービス範囲などの条件と照らし合わせて、最適な提携先を紹介する必要があります。
非常に重要な業務なのですが、多岐にわたる提携先の特徴を視野に入れながら、提携先も求職者も喜んでいただける紹介選定は職人芸に依るところが大きく、ナレッジの共有化と継続性、労働工数という観点で大きな課題となっていました。

イメージ)再送客先選定は一子相伝の職人芸 f:id:astamuse:20180117190413j:plain

4.機械学習を活用した判定結果の導入

「こんなことで困っているんですよねー」
ある日飲み会の席で開発部長の並河さんに軽く相談したところ、「毎年3万人以上のデータが整っているのであれば、機械学習を活用すれば、ある程度判定を自動化することもできるんじゃないですかねー」と提案を頂きました。

イメージ)仕事のことも気軽に相談できる懇親会 f:id:astamuse:20180117190454j:plain

後日、提携先ごとに数千から数万存在する過去の判定結果(この人はカウンセリングの対象かどうか)を並河さんにお渡しし、数日経ったシミュレーションの結果がこちらになります。

参考)ある提携先のシミュレーション結果 f:id:astamuse:20180117190528j:plain

登録者の個人情報は「年齢」や「職種」など様々な要素で構成されていますが、ある提携先がカウンセリングしたくなる人は、どの項目と相関性が強いかを表しています。
(クリーム色に網掛けしてある部分が相関性の強い構成要素の組み合わせになります)

こうした試行錯誤をしていく中で、企画とエンジニアの「こうした要素の関連が強いのではないか」というやり取りを頻繁に行い、結果として「年齢」「都道府県」「職種小分類」を活用したものを採択しました。

実際の運用としては、既存登録者の個人情報を機械学習の判定プログラムにかけると、それぞれの人にスコアと判定がついて戻ってきます。

例えば
Aさん…スコア:0.6 判定:○
Bさん…スコア:0.3 判定:×
というような形です。

このプログラムのスコア0.6で「○」が付いたAさんは99.6%以上の確率でカウンセリングへと繋がることが分かっているため、この提携先に紹介すれば良いですし、同様にBさんは98.6%の確率でカウンセリングに繋がらないので、他に適した提携先を紹介すれば良いことになります。

参考)スコアと○×の正解率一覧表
f:id:astamuse:20180117190558j:plain

こうして確実に、スピーディーに新しい提携先に登録者を紹介することが可能となりました。
以前はこの運用に毎日150分という時間をかけていましたが、30分で終了できるようになり、提携先の信頼を担保しながら、大幅な運用工数の削減をすることができました。

また、現在はこの考え方を活用して、過去に登録した方に対して再登録を促すメール送信する対象者を選定するなど、様々な施策への応用を行っています。

5.おわりに

ある案件を参考に、マーケティングと開発の関わりを簡単ですが記してみました。
過去に経験した2社はいずれも大手企業に属する会社だと思いますが、最後にそれらとアスタミューゼの違いみたいなものを書いておきたいと思います。

a.コミュニケーションコストが低くて済む
私がいたころのリクルートは、開発といえば丸投げで、開発会社が膨大なコミュニケーションコストをかけて内容をキャッチアップする、という構図でした。営業サイドもITに明るい人が少なかったため、ものすごくコミュニケーションに時間を割いていました。アスタミューゼは基本自社開発ですので、プロダクトのことを熟知した方が多く、阿吽の呼吸で物事を進めることができるのは心地良いと思います。

b.まずやってみる、という気軽さ
カカクコムは一つのサイトが巨大すぎて影響範囲を確認するだけでも大変で、企画から承認まで6カ月くらいかかることがザラでした。今回採り上げたお話しもそうですが、エンジニアの課題解決力と新しい技術への好奇心から「まずやってみる」、というフットワークの軽さがあるのはベンチャー企業ならではではないでしょうか。

8年以上続く成熟した自社プロダクトを持ちながら、ベンチャーならではの足回りの速さを持ち合わせている開発現場だからこそ、マーケティングやエンジニアやデザイナーも日々様々な挑戦が出来ているのではないかなー、と思います。

最後になりましたが、 アスタミューゼでは現在、エンジニア・デザイナーに限らず幅広い職種を募集中です。 興味のある方はぜひ採用サイトからご応募ください。

採用情報|アスタミューゼ株式会社

ではまた。

CoreNLPを使ってみる(2) API編

山縣です。

新年明けましておめでとうございます。

弊社の年末年始休暇は例年になく長く11連休となりました。おかげでかなりリフレッシュできました。 まだちょっと休みボケも残っていますが頑張っていきたいと思います。

本年も弊社と当ブログをよろしくお願いします。

今回も CoreNLP について書きたいと思います。 前回 CoreNLP を CLI から使う方法やサーバとして起動してAPI経由で使う方法について書きました。 今回は API の方を見ていきたいと思います。 CoreNLP では Java の API が提供されているので、これを Scala から使ってみます。

1. Stanford CoreNLP API

サンプルコードとその実行

CoreNLP のサイトでAPI についてはこちらで説明されています。 このサイトを参考に Scala から API を使ってみます。

Scala の環境ということでビルドツールに SBT (1.0.4) を使います。

$ cat project/build.properties
sbt.version=1.0.4

build.sbt は以下のとおりです。

lazy val root = (project in file(".")).
  settings(
    organization := "example",
    scalaVersion := "2.11.12",
    version      := "0.1.0-SNAPSHOT",
    name := "Example1",
    libraryDependencies ++= Seq(
      "edu.stanford.nlp" % "stanford-corenlp" % "3.8.0",
      "edu.stanford.nlp" % "stanford-corenlp" % "3.8.0" classifier "models-english",
      "org.slf4j" % "slf4j-simple" % "1.7.12"
    ),
    fork in run := true,
    outputStrategy := Some(StdoutOutput),
    javaOptions in run += "-Xmx8G"
  )

corenlp は maven 上にパッケージがあるのでそれを利用します。 英語のモデルデータを取得するため、追加で classifier "models-english" を指定した依存関係も記述します。 また slf4j-simple を追加しています。このパッケージがないとcorenlp のログメッセージが出力されません。

サンプルのプログラムをサイトのサンプルを元に書いてみました。

package example1
import java.util

import scala.collection.JavaConverters._
import edu.stanford.nlp.ling.CoreAnnotations._
import edu.stanford.nlp.ling.CoreLabel
import edu.stanford.nlp.pipeline._
import edu.stanford.nlp.util.{CoreMap, PropertiesUtils}

import scala.collection.mutable


object Example1 {
  def main(args: Array[String]): Unit = {
    val props = PropertiesUtils.asProperties(
      "annotators", "tokenize, ssplit, pos, lemma, ner",
      "tokenize.language", "en"
    )
    val pipeline = new StanfordCoreNLP(props) //定義したプロパティ propsで Annotator である StanfordCoreNLP を生成

    val text = "Stanford University is located in California. It is a great university."
    val document: Annotation = new Annotation(text) //サンプルテキスト(String) で Annotation を生成

    pipeline.annotate(document) // アノテートする

    printResult(document)
  }

  def printResult(document:Annotation):Unit = {
    val sentences: mutable.Seq[CoreMap] = document.get(classOf[SentencesAnnotation]).asScala
    val tokens: mutable.Seq[CoreLabel] = sentences.flatMap(s => s.get(classOf[TokensAnnotation]).asScala)
    tokens.foreach{ t =>
      val txt: String = t.get(classOf[TextAnnotation])
      val pos: String = t.get(classOf[PartOfSpeechAnnotation])
      val lemma: String = t.get(classOf[LemmaAnnotation])
      val ner: String = t.get(classOf[NamedEntityTagAnnotation])
      println((txt,pos,lemma, ner))
    }
  }

実行すると以下のような出力が表示されます。

sbt:Example1> run
...
[info] Running (fork) example1.Example1
[main] INFO edu.stanford.nlp.pipeline.StanfordCoreNLP - Adding annotator tokenize
[main] INFO edu.stanford.nlp.pipeline.StanfordCoreNLP - Adding annotator ssplit
[main] INFO edu.stanford.nlp.pipeline.StanfordCoreNLP - Adding annotator pos
[main] INFO edu.stanford.nlp.tagger.maxent.MaxentTagger - Loading POS tagger from edu/stanford/nlp/models/pos-tagger/english-left3words/english-left3words-distsim.tagger ... done [0.8 sec].
...
(Stanford,NNP,Stanford,ORGANIZATION)
(University,NNP,University,ORGANIZATION)
(is,VBZ,be,O)
(located,JJ,located,O)
(in,IN,in,O)
(California,NNP,California,LOCATION)
(.,.,.,O)
(It,PRP,it,O)
(is,VBZ,be,O)
(a,DT,a,O)
(great,JJ,great,O)
(university,NN,university,O)
(.,.,.,O)
[success] Total time: 18 s, completed Dec 26, 2017 3:59:03 AM```
アノテーションの実行

上記のサンプルでトークナイズなどの一通りの処理(アノテーシ ョン)を実行する部分は以下になります。

    val props = PropertiesUtils.asProperties(
      "annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref",
      "tokenize.language", "en"
    )
    val pipeline = new StanfordCoreNLP(props)

    val text = "Stanford University is located in California. It is a great university."
    val document: Annotation = new Annotation(text)

    pipeline.annotate(document)

コードを少し細かく見ていきます。

    val props = PropertiesUtils.asProperties(
      "annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref",
      "tokenize.language", "en"
    )
    val pipeline = new StanfordCoreNLP(props) 

上記の部分では props に処理内容を記述しアノテータである StanfordCoreNLP を生成しています。

    val text = "Stanford University is located in California. It is a great university."
    val document: Annotation = new Annotation(text) 

次に処理したいテキストを用意します。 Annotation クラスのインスタンスdocumentとして定義します。

以上で準備が整ったので実際にアノテーションを実行します。

    pipeline.annotate(document)

annotate を呼ぶことでアノテーションの処理が実行され処理結果が document に保存されます。

処理結果の取得

次に処理された結果の表示について見ていきます。表示は printResult(..) メソッドにまとめています。

  def printResult(document:Annotation):Unit = {
    val sentences: mutable.Seq[CoreMap] = document.get(classOf[SentencesAnnotation]).asScala
    val tokens: mutable.Seq[CoreLabel] = sentences.flatMap(s => s.get(classOf[TokensAnnotation]).asScala)
    tokens.foreach{ t =>
      val txt: String = t.get(classOf[TextAnnotation])
      val pos: String = t.get(classOf[PartOfSpeechAnnotation])
      val lemma: String = t.get(classOf[LemmaAnnotation])
      val ner: String = t.get(classOf[NamedEntityTagAnnotation])
      println((txt,pos,lemma, ner))
    }
  }

まず下記のコードでセンテンスのリストを取得しています。

    val sentences: mutable.Seq[CoreMap] = document.get(classOf[SentencesAnnotation]).asScala

document.get() でアノテーションクラスのClass型インスタンスを渡すことで対応するデータを取得しています。 SentencesAnnotation を渡すと List[CoreMap] が返されます。(上記の場合 asScala で Scala のコレクション mutable.Seq に変換されています。)

各センテンスの情報は CoreMap インタフェースの実装クラスに保存されています。CoreMapはCoreNLP ライブラリの独自の Map インタフェースを定義しています。

次にセンテンスからトークンを取得します。

    val tokens: mutable.Seq[CoreLabel] = sentences.flatMap(s => s.get(classOf[TokensAnnotation]).asScala)

センテンスからトークンのリストを取得しているのは "s.get(classOf[TokensAnnotation])" です。 こちらも get() でトークンのアノテーションクラスのClass型インスタンスを渡すことで結果を取得しています。 get() で返ってくるのは List[CoreLabel] です。(例によって asScala で Scala のコレクション mutable.Seq に変換されています。) flatMap 使うことで Seq のネストを解消して mutable.Seq[CoreLabel] にしています。

各トークンに対してトークンのテキスト、品詞、レンマ、固有表現抽出の結果を出力しているのが下記の部分になります。

    tokens.foreach{ t =>
      val txt: String = t.get(classOf[TextAnnotation])
      val pos: String = t.get(classOf[PartOfSpeechAnnotation])
      val lemma: String = t.get(classOf[LemmaAnnotation])
      val ner: String = t.get(classOf[NamedEntityTagAnnotation])
      println((txt,pos,lemma, ner))
    }

CoreLabel は一つのトークンおよびアノテータにより付加されたアノテーション情報を保存するクラスです。 CoreLabel.get() において引数で指定されたClass型インスタンスに対応した値を返します。上記では各 トークン(CoreLabel) に対して TextAnnotation, PartOfSpeechAnnotation, LemmaAnnotation, NamedEntityTagAnnotation のそれぞれのアノテーションの情報(この場合はいずれもString型)を取得して表示しています。 以上のようにデータを取得するには各段階で get(classOf[...] ) というメソッドを呼び出しますが、コードが見づらい印象を受けます。 CoreLabel では代わりにそれぞれのアノテーションを簡易に取得するメソッドも提供されており上記の部分は、下記のように書くこともできます。

    tokens.foreach{ t =>
      val txt: String = t.word()
      val pos: String = t.tag()
      val lemma:String = t.lemma()
      val ner: String = t.ner()
      println((txt,pos,lemma, ner))
    }

こちらのほうが簡潔に書けて良いですね。

2. Simple CoreNLP API

以上のように Stanford CoreNLP API の使用方法を見てきましたが、少々まどろっこしい感じも受けますね。CoreNLP の API には前述の API とは別に Simple CoreNLP API というものも提供されており、より簡潔な記述で CoreNLP を利用する方法もありますので、ここではそれを見ていきたいと思います。

package example2

import scala.collection.JavaConversions._
import edu.stanford.nlp.simple._

import scala.collection.mutable


object Example2{
  def main(args: Array[String]): Unit = {
    val text = "Stanford University is located in California. It is a great university."
    val doc = new Document(text)
    val tokens: mutable.Seq[Token] = doc.sentences.flatMap(_.tokens())
    tokens.foreach{ t =>
      val txt: String = t.word()
      val pos: String = t.tag()
      val lemma:String = t.lemma()
      val ner: String = t.ner()
      println((txt,pos,lemma, ner))
    }
  }
}

上記は先程の Example1 と同じ内容の処理になります。 実際に実行して確認してみます。

sbt:Example1> runMain example2.Example2
[warn] Multiple main classes detected.  Run 'show discoveredMainClasses' to see the list
[info] Running example2.Example2
[run-main-0] INFO edu.stanford.nlp.tagger.maxent.MaxentTagger - Loading POS tagger from edu/stanford/nlp/models/pos-tagger/english-left3words/english-left3words-distsim.tagger ... done [1.0 sec].
...
(Stanford,NNP,Stanford,ORGANIZATION)
(University,NNP,University,ORGANIZATION)
(is,VBZ,be,O)
(located,JJ,located,O)
(in,IN,in,O)
(California,NNP,California,LOCATION)
(.,.,.,O)
(It,PRP,it,O)
(is,VBZ,be,O)
(a,DT,a,O)
(great,JJ,great,O)
(university,NN,university,O)
(.,.,.,O)
[success] Total time: 17 s, completed Dec 25, 2017 3:34:25 AM

同じ結果が返ってきています。

Simple API を使用するには "edu.stanford.nlp.simple._" を import します。

コードの書き方について Stanford API と比較すると、一番大きな違いは Stanford API で行っていた、アノテータ(StanfordCoreNLP) の生成と annotate() の実行が無いことです。これらの処理は隠蔽されています。

    val doc = new Document(text)
    val tokens: mutable.Seq[Token] = doc.sentences.flatMap(_.tokens())

処理したいテキストで クラスDocument を生成します。上記の "doc.sentences はメソッドでこのメソッドの中で tokenize, ssplit に対応するアノテータが実行されています。

    tokens.foreach{ t =>
      val txt: String = t.word()
      val pos: String = t.tag()
      val lemma:String = t.lemma()
      val ner: String = t.ner()
      println((txt,pos,lemma, ner))
    }

こちらのコードでは、各アノテーションを取得しています。 例えば POS(PartOfSpeach) 情報を取得する tag() メソッドでは内部で pos に対応するAnnotator を実行します。このように Simple API ではデータが実際に必要になったときにはじめて処理が呼び出される遅延実行をすることで無駄な処理が実行されないようにしています。

ドキュメントでは Simple API のメリットとして以下が上げられています。

  • 直感的なシンタックス
  • Lazy computation (必要になるまで処理が実行されない)
  • ヌルポが起きない(nullを返さない)
  • 高速で頑健なシリアライゼーション(protocol buffers を使用)
  • スレッドセーフ

一方で、カスタマイズがしづらいこと、処理が決定的でない(呼ばれる処理の順番によって使用されるアルゴリズムが異なったりすることで結果が常に同じにはならない)などをデメリットとして上げています。

3. Stanford CoreNLP API と Simple CoreNLP APIの性能比較

Stanford API と Simple API について性能面で違いがあるのか比較してみました。 基本的には上記までの Example1, Example2 と同じ処理(pos, lemma, ner) を大きなテキストデータについて実行し、実行時間を計測してみました。 データは社内にあるデータ (英文)1000件、約2MBのデータになります。 環境は 私の作業用のノートPC(Win10, WSL) 上です。

sbt:Example1> runMain example3.Example3 simple
...
[success] Total time: 154 s, completed Dec 26, 2017 7:35:20 AM

上記のように引数 simple をつけた場合 Simple API をそうでない場合は Stanford API を実行するようにし、3回実行して平均を取りました。

Stanford API Simple API
1回目  168 160
2回目  154 154
3回目  155 150
平均  159.0 154.7

結果を見ると Simple API のほうが少し速いようですが、あまり厳密なテストでもないですし、ほとんど変わらないと考えて良いのでは無いかと思います。

次に少し処理を変えてみます。

Stanford API/ Simple API それぞれのデータを取得するメソッドは以下のようになっています。

Standford API:

  def getResult(document:Annotation):Seq[Result] = {
    val sentences: mutable.Seq[CoreMap] = document.get(classOf[SentencesAnnotation]).asScala
    val tokens: mutable.Seq[CoreLabel] = sentences.flatMap(s => s.get(classOf[TokensAnnotation]).asScala)
    tokens.map(t => Result(t.word(), t.tag(), t.lemma(), t.ner())).toSeq
  }

Simple API:

  def getResult(document:Document):Seq[Result] = {
    val tokens = document.sentences.asScala.flatMap(x => x.tokens().asScala)
    tokens.map(t => Result(t.word(), t.tag(), t.lemma(), t.ner())).toSeq
  }

Result はアノテーションの結果を保存する case class で、以下のように定義されています。

case class Result(txt:String, pos:String, lemma:String = "", ner:String = "")

先程までは pos, lemma, ner という3つのアノテーション結果を取得していましたが、lemmaとnerは使わなかったので pos だけを取得しようとコードを変えたとします。 Stanford API/ Simple API それぞれ

    tokens.map(t => Result(t.word(), t.tag(), t.lemma(), t.ner())).toSeq

となっている部分を

    tokens.map(t => Result(t.word(), t.tag())).toSeq

として 品詞の結果だけを取得するように変更します。修正点はここだけになります。 このように変更したコードを使って再度処理を実行してみます。

Stanford API Simple API
1回目  155 17
2回目  160 16
3回目  157 16
平均  157.3 16.3

今回は結果が大きく異なり Simple API は大幅に速くなりました。 一方 Stanford API は、前とほとんど変わりません。

これは Stanford API の場合 プロパティ "annotators" で処理内容を決めており、データを取得する、取得しないにかかわらず annotate() を実行した時点でこれらの処理がすべて実行されてしまうからです。一方で Simple API ではアノテーション取得時に対応するアノテータがオンデマンドで実行されるので呼び出さなければその処理が実行されないため大幅に処理時間を短縮できています。

もちろん Stanford API でも必要としていない lemma, ner を annotators から抜けば同じような処理時間で処理をすることが可能です。ですが、ついうっかり忘れてしまうと無駄に処理時間がかかってしまいます。

おわりに

以上、Stanford API と Simple API について見てみました。 どちらを使うのかは好みの問題とは思いますが、CLI と同じように使いたい、細かいカスタマイズがしたいなら Stanford API を、あまり細かいところは良いのでとにかく手軽に処理がしたいのなら Simple API という感じでしょうか。また NLP の処理は重いので不必要な処理は実行しないようにしないと無駄に処理時間がかかってしまうので気をつけたほうが良いと思います。

ちょっと時間がなくなってしまったので Spark での CoreNLP の使用については次回に書きたいと思います。

システムテスト自動化カンファレンス2017に登壇しました

f:id:astamuse:20171213181216j:plain

こんにちは。nishikawaです。

12月10日 日曜日に行われたシステムテスト自動化カンファレンスにて、弊社の転職ナビチームの事例紹介をしてまいりましたので、レポートも含めてご報告させていただきます。

資料配布

会場の雰囲気

会場には自動テストに課題のある方や、コミュニティの方など色々な方がおり、質疑応答なども含め白熱したイベントでした。

発表、そして登壇を終えての感想

そんな中、弊社の転職ナビチームがやっているテストや課題などの事例紹介を発表させていただきました。

f:id:astamuse:20171213181132j:plain

始まる前は人生初登壇ということもあり、とても緊張しておりましたが、発表が始まった後は会場の皆様と一緒になって冗談を交えながら楽しく発表することができ、なんとか終わらせることができました。

質疑応答でも、弊社の事例について沢山ご質問いただき、初めての登壇にしては成功だったなと満足することができました。

今後について

今後も転職ナビチームでは、システムの自動化を推進し効率良く開発できるように邁進したいと思います。

そうした努力の末、転職ナビの品質を向上させ、より良い転職ができるサービスという形で様々な方にお返しできればと思います。

それでは。

Copyright © astamuse company, ltd. all rights reserved.