hirapi's blog

ちゃんとしたふりをする

(社内LT資料)ユニットテスト:ちょっとしたDI

週1回、朝会後に簡単なLTをやることにした。
(残りの4日間は広告業界・アドテク分野のニュースを適当にひっぱってみんなで眺める会)

ひとつのテーマで2〜3人がしゃべる形式。
記念すべき第1回のテーマは「ユニットテスト」。

あえて少し外して、むかし先輩に教えてもらったDIと絡めて話してみた。
併せて見せたサンプルコードは下に。
(普段ユニットテストPHPUnit使って書いてるけど今回はライブラリにフォーカスしたくなかったので自前で)

ちょっとしたDI - slideship.com

サンプルコード

悪い例

改修前

<?php

// コントローラ

$team = new Team();
echo $team->doAsakai(); // 今日も一日がんばりましょう


// モデル

class Team {

    private $leader;

    public function __construct() {
        // リーダーは事業マネージャー
        $this->leader = new ServiceManager();
    }

    public function doAsakai() {
        return 'リーダーより:' . $this->leader->sayAsakaiMessage();
    }
}

class ServiceManager {

    public function sayAsakaiMessage() {
        return '今日も一日がんばりましょう';
    }
}


// テスト

class TeamTest {

    public function execute() {
        $team = new Team();

        echo 'doAsakai()のテスト';

        if ($team->doAsakai() === 'リーダーより:今日も一日がんばりましょう') {
            echo 'OK!!';
        } else {
            echo 'NG!!';
        }
    }
}

改修後

<?php

// コントローラ

$team = new Team();
echo $team->doAsakai(); // にゃーん


// モデル

class Team {

    private $leader;

    public function __construct() {
        // リーダーはエンジニアマネージャー
        $this->leader = new EngineerManager(); // <- 改修
    }

    public function doAsakai() {
        return 'リーダーより:' . $this->leader->sayAsakaiMessage(); // <- 出力が変わった
    }
}

class ServiceManager {

    public function sayAsakaiMessage() {
        return '今日も一日がんばりましょう';
    }
}

class EngineerManager {

    public function sayAsakaiMessage() {
        return 'にゃーん';
    }
}


// テスト

class TeamTest {

    public function execute() {
        $team = new Team();

        echo 'doAsakai()のテスト';

        if ($team->doAsakai() === 'リーダーより:にゃーん') { // <- テストも変える
            echo 'OK!!';
        } else {
            echo 'NG!!';
        }
    }
}

すこし良い例

改修前

<?php

// コントローラ

$leader = new ServiceManager(); // リーダーは事業マネージャー
$team = new Team($leader);
echo $team->doAsakai();


// モデル

class Team {

    private $leader;

    public function __construct($leader) {
        // リーダーは誰でもいい
        $this->leader = $leader;
    }

    public function doAsakai() {
        return 'リーダーより:' . $this->leader->sayAsakaiMessage(); // leader の sayAsakaiMessage() と同じ挙動であればOK
    }
}

class ServiceManager {

    public function sayAsakaiMessage() {
        return '今日も一日がんばりましょう';
    }
}


// テスト

// sayAsakaiMessage() を持ったモッククラス
class ManagerMock {
    public function sayAsakaiMessage() {
        return '私は sayAsakaiMessage() メソッドを持っています';
    }
}

class TeamTest {

    public function execute() {
        $leader = new ManagerMock();
        $team = new Team($leader);

        echo 'doAsakai()のテスト';

        if ($team->doAsakai() === 'リーダーより:私は sayAsakaiMessage() メソッドを持っています') {
            echo 'OK!!';
        } else {
            echo 'NG!!';
        }
    }
}

改修後

<?php

// コントローラ

$leader = new EngineerManager(); // リーダーはエンジニアマネージャー <- 改修はここだけ
$team = new Team($leader);
echo $team->doAsakai();


// モデル

class Team {

    private $leader;

    public function __construct($leader) {
        // リーダーは誰でもいい
        $this->leader = $leader;
    }

    public function doAsakai() {
        return 'リーダーより:' . $this->leader->sayAsakaiMessage();
    }
}

class ServiceManager {

    public function sayAsakaiMessage() {
        return '今日も一日がんばりましょう';
    }
}

class EngineerManager {

    public function sayAsakaiMessage() {
        return 'にゃーん';
    }
}


// テスト

// sayAsakaiMessage() を持ったモッククラス
class ManagerMock {
    public function sayAsakaiMessage() {
        return '私は sayAsakaiMessage() メソッドを持っています';
    }
}

class TeamTest {

    public function execute() {
        $leader = new ManagerMock();
        $team = new Team($leader);

        echo 'doAsakai()のテスト';

        if ($team->doAsakai() === 'リーダーより:私は sayAsakaiMessage() メソッドを持っています') { // <- テストも変わらない
            echo 'OK!!';
        } else {
            echo 'NG!!';
        }
    }
}

良い例

改修前

<?php

// コントローラ

$leader = new ServiceManager(); // リーダーは事業マネージャー
$team = new Team($leader);
echo $team->doAsakai();


// インタフェース

interface Manager {
    public function sayAsakaiMessage();
}


// モデル

class Team {

    private $leader;

    public function __construct(Manager $leader) { // <- インタフェースで型宣言
        // リーダーは誰でもいい
        $this->leader = $leader;
    }

    public function doAsakai() {
        return 'リーダーより:' . $this->leader->sayAsakaiMessage(); // Managerインタフェースの実装クラスは必ずsayAsakaiMessage()を持っている
    }
}

class ServiceManager implements Manager { // <- Managerインタフェースを実装

    public function sayAsakaiMessage() {
        return '今日も一日がんばりましょう';
    }
}


// テスト

// sayAsakaiMessage() を持ったモッククラス
class ManagerMock implements Manager { // <- Managerインタフェースを実装
    public function sayAsakaiMessage() {
        return '私は sayAsakaiMessage() メソッドを持っています';
    }
}

class TeamTest {

    public function execute() {
        $leader = new ManagerMock();
        $team = new Team($leader);

        echo 'doAsakai()のテスト';

        if ($team->doAsakai() === 'リーダーより:私は sayAsakaiMessage() メソッドを持っています') {
            echo 'OK!!';
        } else {
            echo 'NG!!';
        }
    }
}

改修後

<?php

// コントローラ

$leader = new EngineerManager(); // リーダーはエンジニアマネージャー
$team = new Team($leader);
echo $team->doAsakai();


// インタフェース

interface Manager {
    public function sayAsakaiMessage();
}


// モデル

class Team {

    private $leader;

    public function __construct(Manager $leader) { // <- インタフェースで型宣言
        // リーダーは誰でもいい
        $this->leader = $leader;
    }

    public function doAsakai() {
        return 'リーダーより:' . $this->leader->sayAsakaiMessage(); // Managerインタフェースの実装クラスは必ずsayAsakaiMessage()を持っている
    }
}

class ServiceManager implements Manager { // <- Managerインタフェースを実装

    public function sayAsakaiMessage() {
        return '今日も一日がんばりましょう';
    }
}

class EngineerManager implements Manager { // <- Managerインタフェースを実装

    public function sayAsakaiMessage() {
        return 'にゃーん';
    }
}


// テスト

// sayAsakaiMessage() を持ったモッククラス
class ManagerMock implements Manager { // <- Managerインタフェースを実装
    public function sayAsakaiMessage() {
        return '私は sayAsakaiMessage() メソッドを持っています';
    }
}

class TeamTest {

    public function execute() {
        $leader = new ManagerMock();
        $team = new Team($leader);

        echo 'doAsakai()のテスト';

        if ($team->doAsakai() === 'リーダーより:私は sayAsakaiMessage() メソッドを持っています') {
            echo 'OK!!';
        } else {
            echo 'NG!!';
        }
    }
}

Conference on Computer Science for Enterprise 2018メモ

ccse2018

に行ってきた。 スライド公開されるだろうからあんまり意味は無いけどせっかく書いたメモを残す場所が無いので貼っておく。

広告クリエイティブ制作と機械学習

CA AILab

CAアドテク

  • クリエイティブ
  • 広告効果
  • 経済への影響

クリエイティブチーム

  • 分析基盤整備
  • 静止画クリエイティブ制作支援
  • 配信最適化
  • 技術検証

広告自動生成

データ基盤の整備・統計分析

  • 現状
    • 素材 @クリエイター手動管理
    • 編集データ @〃
    • 入稿データ @制作管理システム
    • 配信データ @配信管理システム
  • 理想 ↑↑を最初から最後まで一括管理、統計分析へ
  • クリエイティブグラフ
    • 素材 → 編集データ の中で、効果の高い技法を探る
  • レイヤーの統計分析
    • 素材の自動分類

広告効果の予測

  • DeepCTR(Chen, 2016)をベースに、様々な素性からCTR予測 バナー画像、テキスト、ユーザー属性
  • 顕著性の可視化 CTR予測に最も影響した画像領域 画像のどこにどういう特徴があるのか

静止画の制作支援

  • 単配置予測:オブジェクトと背景が与えられたとき、どこに置くか → デザイナーの作業効率化 新しい素材が置かれる確率をドットで表示
  • ざっくりした配置から自動でバナーを生成(研究中) デザイナーにインスピレーションを与えるきっかけとしては十分つかえる

Q & A

  • 研究のきっかけ トップダウンボトムアップ両方
  • プロダクションへのゴーサイン マイルストーンのひとつとして「論文化して発表」 あとは試しにプロダクションにのせてみてる
  • デザイナーとの業務分掌 たまにミーティングをもって、時間がかかっているプロセスを吸い上げている

プライバシーに配慮したコンピュータビジョンの社内導入

楽天 R & D Request, R & D proposal

社内カフェテリアの動画分析

1万2,000人以上の社員 → 混雑 → 監視カメラの動画分析から、混雑度を算出 → 社内テレビやポータルサイトに表示

プライバシーの問題

  • 個人情報保護法を守りましょう
    • セキュリティ以外の事情で取得する場合は本人に通知する義務
    • 国のガイド
      • 消してほしいときに連絡できること
      • 撮られる側のメリット
      • 個人情報が含まれるか
      • 保存方法・提供先を明示
  • 専門家に聞きましょう
  • 責任の所在を明らかにしておきましょう
    • 経営層? 研究所?
    • 経営層からリクエストがあったら:
      • プライバシーの問題が発生しない代替案を提示
      • やることになったら法務部へ
  • やることになったら、社内の友達に話してみましょう
    • 「なんで?」「え?」とネガティブなリアクションだったら、説明不足 → もう一回考え直そう

楽天カフェテリアではポスターやポータルサイトで社内告知、連絡先も明示 → その後の調査で満足度98%

研究中

  • 顔を改変して個人を特定できなくする技術を開発中

Q & A

  • 98%の満足となると2%の人は? 残りの2%の不満は今回のプロジェクトと関係ないところの不満だったw
  • 社内ゴーサインの基準 不満・議論があれば真摯にやり取りをするしかない。
  • 社内だからできたと思うけど、公共の場でも対応可能なの ちゃんと告知する、いきなり大規模にやらないでおく、連絡先を明記する

インタラクティブな属性操作が可能なファションアイテム検索

スタートトゥデイ テクノロジー

ZOZO town以外にもECやろうということで設立

ファッションアイテムの検索システム

  • テキストベース
    • pros:細かい検索条件
    • cons:検索ノイズ、前処理の手間
  • 画像ベース

    • 画像特徴量と類似度評価関数で実現
    • pros:直感的なクエリ
    • cons:検索結果をコントロールできない
  • Attribute manipulation 「オレンジのワンピース」の画像で検索したとき、「赤」という属性を足して 「似た形をした赤いワンピース」を出すことができる。 どれくらい赤くするかを操作できる

    • VAE・GAN encoder, decoderに属性情報
    • anchor, positive(正解), negative(不正解) の画像を教師データとする
  • RoI pooling manipulationの適用範囲を指定

Q & A

  • 社内でのアノテーション ZOZO以外でのデータを使っている、足りないときは他社と協力している

メルカリR4D

メルカリ

R4D

Research for Design / Development / Deployment / Disruption

テクノロジーを社会実装しdisruptionを実現

Partner → mercari R4D → services 基礎研究・応用研究 → 研究開発・実装 → 活用

energy, optics, Quantum Computing, AI/ML, Networt, robotics, XR, Blockchain 東京大学東北大学、京王、京都造形芸術大学、Pixie Dust Technologies

これから

sustainable Development goalsに取り組む

公式サイトあるので見てね! (VR面接してるけど最後は会う。課題である

学会をゲームに

Unity 情報処理学会ECシンポジウム オーガナイズドゲームの取り組み entertainment computing

学会あるある

  • いつも同じ集団で会話している 会話に入れない、学生が交流してくれない
  • いつも同じ人が質問している 質問したいのに怖い

エンターテイメントを研究しているのだからエンターテイメントで解決するべき

2014

  • 3日間の学会で犯人探しゲーム
  • 学会用の名札に意味ありげなヒントをばらまく → 会話のきっかけ
  • インパクトのある楽しい時間

まさかの情報処理技術なし

2015

  • 名札のQRコードを読み取ってパーティを組む。
  • 各メンバーの能力パラメタは非表示、敵と戦ってみないとわからない
  • 負けたら強制解散。パーティ組み直し → 仮説検証プロセス

最後は全員で魔王と戦う パーティ組んでる人は組んだまま、じゃない人は1人でダメージを与えていく

いちばんつよい組み合わせを見つけるゲーム

2016

  • 学生に論文を書かせたら研究費が増える
  • 学生にもパラメタがある → 能力の低い学生は就職させる、能力の高い学生を残して論文を書かせる
  • 思いもしなかった展開も → D3になると自動で卒業するので、能力が高い学生をM2のまま論文を書かせるのが最善手だった

これから

  • 消極性研究会 shygames
  • ゲームなんかしなくても楽しい、のがいい
  • 消極的な人でも生きていける社会 shy-hack

料理動画サイネージシステム

cookpad TV

開発フロー

  • 通常:ウォーターフロー 端末は一回置いたら置き換えが難しいので、一般的にはウォーターフロー
  • cookpadアジャイル 展開後もサイクルを回す

価値検証

  • ハードウェア選定 1から作る? サイネージ用端末を使う? 量産品のタブレット
  • ソフトウェアアップデート Mobile Device Management(MDM) → アップデート時に自動更新、自動起動、アプデ直前の動画を自動で再生
  • 安定稼働 コードフリーズ後、耐久検証期間を設け、チーム全員で動作確認

検証結果分析

store TV redshift → tableau で誰でもすばやく状況を確認できる

自動電源ON/OFF

ユーザー、欲求、課題、特徴

スーパーの売場責任者は、毎日サイネージを稼働させたいが、
従業員がサイネージを付け忘れるので、自動で電源がONになる機能に価値がある
スーパーの売場責任者は、どんな商品でもサイネージを利用したいが、
利用できる動画がないので、多くの動画があることに価値がある

施策 → 利用率分析

まとめ

  • 初めて作るサイネージサービスでも「素早く価値を提供する」を重視
  • 素早く価値を提供する基盤を整えることで、サービス改善フローが高速に

Q & A

  • 店舗へのアプローチ 小規模で検証してから、横展開
  • 実際に売上あがるの? 置くだけじゃ駄目だった、関連食材とセットの売り場を作ると効果アリ
  • 店舗のほうは積極的? 設置できない環境だとだめだけど、配布に行くと8〜9割くらい置いてくれる
  • サービスの需要は伸びていくの? これから改善を繰り返して伸ばしていきたい
  • ユーザーのどんな振る舞いを想定している? (買い物客ですよね?) 従来は頭の中にあるレシピだった → 「こんなのも作れるんだ」 集合展開の軸にしてほしい。

MLシステムの自動化

メルカリ (SRE

  • MLプラットフォーム 内製。くばねたすベース OSSで公開予定(たぶん

メルカリML利用事例

  • 感動出品
  • 違反出品検知
  • 価格サジェスト
  • ウエイトサジェスト

1日に数千万のprediction

Training & Serving

(スライド見たほうがいいかも)

Training

  1. githubへのpush → training起動
  2. trainingされたmodelはmodel registoryにアップされる

Serving

  1. model registoryを監視してコンテナイメージに取り込む
  2. 自動でテスト、serving

課題

  • 違反検知システムのpython実装部分がメモリを食う sklearnの前処理部分が問題らしい → forkする前にmodelをロードしcopy on writeを活用するなど賢くつかう

  • MLは継続的なメンテナンスが必要 → 大幅な自動化が必須(開発中)

    • 社内のデータから特徴抽出する実装をコンポーネント化 → 再利用
    • 学習し直し・デプロイ等を自動化

まとめ

  • MLは特殊なインフラが必要、ベストプラクティスはまだみえない
  • 基本的なフローは全て大掛かりな自動化が必須

Q & A

  • 再学習はどれくらいの頻度で? ものによる。違反検知は週1くらい
  • 再学習時に新たな学習データがいると思うが、再生成のフローは ある。誤った学習結果は修正されるようにしている
  • KPIを決めていくのは? エンジニアの関わり方は PMと開発者が相談して決めていく

Unity Labsの研究成果

Unity https://unity3d.com/labs

いろんな拠点・グループがある XRだけでなくビッグデータ分析もアツい

グローバル企業の中で変化を仕掛ける 楽天技術研究所の挑戦

楽天

  • 事業とは独立した戦略的R&D組織
  • 研究者が研究を推進、研究者による評価
  • 7割がCSのPhD, 8割が日本以外の国籍

研究領域

  • power
  • intelligence
  • reality

アプローチ

最初からビジネスサイドと協力して立案・遂行 → グループ企業内では発想に限界

→ アカデミアとの連携

広告業界

  • コンサル業界がなだれ込んでいる SNS等の拡散を通して、想定した層以外にも届いてしまうようになった 単にコンテンツ、クリエイティブの問題ではなくなっている → 組織自体を変えて、グローバルな魅力をつけていく必要がある

Q & A

  • 接客が機械ボイスだったのは 天の声的な。お客さんのファッションをdisったときに受け入れやすい
  • お客さんは裏に人間がいることを知っている? 知っている

コーディネート整合性を考慮したカテゴリ間推薦

スタートトゥデイ

推薦システム

「ユーザーに選択肢を提示し、意思決定を支援する」

ファッション:アイテムは複数同時に利用される (映画・音楽:個別に利用される → 相性 = コーディネート整合性(compatibility)の問題が発生する

  • カテゴリ間推薦 カテゴリAのアイテムを入力 → カテゴリBのアイテムを出力

先行研究

  1. 特徴抽出ステップ → 共通空間に埋め込み
  2. 近傍探索ステップ → 一番近いアイテム

Siamese CNNによる特徴抽出 Contrastive損失 → 正例の場合、ペアが近づくように学習。負例の場合、ペアが遠ざかるように学習

  • 問題点
    • Amazonの同時購入データセット(同時に購入された = コーディネート整合性が高い? ← 教師データとして正しいか微妙
  • 解決
    • ファッションSNSのデータ IQON ← オシャレに関心のあるユーザーが、コーディネートを想定して、「着たい服」で作成

実験

  • 特徴抽出:inception V3
  • 損失関数:Contrastive損失
  • 特徴数:1,000

結果

  • トップス → ボトムス
  • トップス → バッグ

学習前は似た色や柄のアイテムが選ばれていたが、学習後は改善。 一見ではよくありそうな組み合わせに

Q & A

  • 「コーディネート」の定量的な評価 わからない。やるとしたらユーザーにアンケートか。
  • アンケートは必要か 論文として出すなら必要。ビジネスで言えば必ずしも必要ではない。
  • トレンドの変化 ファッションアイテムは価値がすごい速さで減少する。 今はまだ考慮できていない。

データサイエンスによる物流プロセスの最適化

楽天

物流の最適化

  • 倉庫内オペレーション最適化
    • ピックパスの最適化
    • ロボット化
  • 配達効率
    • 不在者予測
    • 受け取り方法の多様化

ピックパス

複数のオーダーを1つにまとめ(→ バッチ)てピッカーに振る どうまとめるのが1番いいか

  • オーダーにはピック難易度がある
    • 難:ニッチな本を何冊も
    • 易:アイドルのCD大量買い
  • ピッカーの総歩行距離の最小化
  • 階層型クラスタリングアルゴリズム

不在者予測

  • 現在:不成功確率19.0%
  • 最適な配送時間帯を推定

    • 成功:手渡し、宅配box、
    • 失敗:不在、営業時間外、住所不明
  • 項目

    • 住所、宛名、会員データ、注文データ、配送日情報 → 会社? 配達ボックスある? 既婚? 子供いる? 休日?

単純に最適化するとほとんど「深夜・早朝がベスト」となる → 現実的でない

  • 単位時間あたりに配達できる荷物容量には上限がある。。。 → 大きな荷物は確率の高い時間帯に、小さい荷物はそれ以外で確率の高い時間帯に

Q & A

  • アイテムは変わると思うが 本棚の配置自体はランダム。ベストセラーと予測されるものはまとめておくくらい。

ReactiveExtensionsを用いた映像機器向けモバイルアプリの制御とキャッシュの最適化

IO DATA

背景・課題

モバイルアプリと他の機器(レコーダーなど)で通信

  • P2Pで通信するためNAT越えが必要。ユーザーの設置環境も様々。
  • モバイルアプリ向けの機器APIの最適化がされていない

Reactive Extensions for JVM

データフローを定義して、インタラクティブにviewに反映させる

CAのアカデミックへのアプローチ

CyberAgent アドテクスタジオ

研究テーマ

  • 対話エージェント
  • クリエイティブ制作支援
  • 広告の因果効果

大学との共同研究、外部発表、社内向け研究論文紙(社内有志で査読もある)

研究インターン

  • D生向け
  • 3つのテーマから選択
  • 報酬月額50万〜
  • トップカンファに通ると渡航費・参加費をサポート

ゼミ精度

c.f. 20%ルール

  • 業務時間の一部をつかって研究活動が可能

よりよい機械学習のためのアノテーション機械学習

ABEJA

今日のお話、詳しくはブログで

アノテーション機能

  • 教師データ作成
  • 作成データのレビュー
  • アノテーター管理
  • アノテーター教育
  • アノテーターの品質可視化
  • アノテーター毎の精度のばらつきの解消

なぜいまアノテーションなのか

収集 → アノテーション → 学習 → 評価 → 運用

  • 半教師あり学習(SSL) 少量の教師ありデータと、大量の教師なしデータ

とはいえ、やはり完全な教師あり学習のほうが精度はいい → クリーンなアノテーション

  • 顔認証 精度向上に対しては、モデル改善よりデータ整備のほうが効いた githubface net

アノテーションを改善する

  • ノイズ:

    • ワイルドなデータ マスク、サングラス
    • 本質的に難しいタスク 年齢、「どちらが好きか」
  • 実験

    • モデル
    • データ:MNIST, cifar
    • 内容:誤ったデータでモデルを作る
  • アノテーションノイズを検知する

    • EM-algorithm 同一データを複数のアノテータに割り振り、結果の一貫性をもとに アノテーター毎のアノテーション傾向を推定

論文化・特許化・実用化の高速なイテレーションの実現

Cygames Research https://research.cygames.co.jp

慶應で准教授をしていたら当時の学生がCygamesに入ってヘッドハンティングされた

UI

video check-in

  • 静止画、動画にカメラをかざすとポイントがたまる リアルタイムに放送しているアニメの映像をスマホにかざす
    • スケーラビリティ:同時接続30〜40万、秒間10万
    • 映像処理技術:さまざまな視聴環境に対応
  • ポスターも、貼られている場所も認識
    • 完全に同じポスターでも、場所の違いがわかる 枠に全て収まったときに認証完了 → ポスター周辺を撮っている アニメイト? マック? どことのコラボのポスターなのか → 実際に貼られているポスターであることを確認
  • MR リアル物体をキャラクターが認識して触る → リアル物体をメッシュ化。あとは通常のゲームと同様

メッセージ

  • オレオレ技術からの脱却 トップカンファでの論文発表 = 経営者が監査を受けるのと同じ
  • ユーザー企業が技術開発の主体になる

Q & A

  • ある研究に対してエンジニアをどれくらい投入している? 研究者がライブラリまで作り込んで「これで使えるよ」まで持っていくことが重要。 開発者はそれを使ってフィードバック。 リサーチャーがjsやpythonでざっくり書く → 専任エンジニアがライブラリ化・Unityにのせるなど → 開発エンジニアが使用する エンジニアはリサーチャーの倍いる。
  • 3ヶ月でイテレーションを回す 研究・開発・特許・論文化を同時に進める。 1人の研究者に3〜4人のエンジニアを付けて開発のイテレーション
  • 論文を書かないサイクルになると何に陥る? その技術が客観的に良い/悪いを判断するのがリサーチャーだけになってしまう
  • 「プロダクトに乗せる」というのがフィードバックになるのでは? ユーザーに研究成果をデバッグさせることになる。 研究コミュニティ内でデバッグは完結するべきである。

対話エージェントの積極的な介入による関係性の構築

CyberAgent 阪大・石黒先生と共同研究

研究内容

  • テキストメッセージ
    • 複数人対話
    • 選択式対話
    • 個性・キャラクタ生成
  • 音声メッセージでの↑↑実現
  • 実店舗での↑↑使用

ビジョン

対話エージェントとヒトが当たり前に共存する世界 (今はまだ「イベントかな」と思ってしまう

「私のためにやってくれている」感 → 対話エージェントからユーザーにアクションを起こす

ヒトと同調するチャットボット

  • 理不尽なクレームをあきらめさせよう CSとの二者間対話では対立。複数人対話を形成して理不尽さを理解してもらう(社会的劣勢におく 途中までエージェントが一緒に怒ってくれる → 途中で折れる → ユーザーもあきらめる → エージェントに対して味方感を感じ、オペレータの評価も上がった
  • ホテルにおけるホスピタリティ向上 スキマ時間のお声掛け(c.f.リッツカールトンの人の本 → 客の反応として、迷惑じゃなく、半公共空間ではむしろ楽しい

まとめ

  • 積極的な介入によって、味方感・楽しさ → 関係性構築に重要な感覚
  • 「嫌がられるかも」「ウザがられるかも」はインタラクション設計次第で解決できる

Q & A

  • サポート中のエージェントの存在自体に違和感は 一次受けがエージェント。途中からオペレータが追加される。ほとんどの人は違和感なし。
  • ターン数は増える? 増える。が、もともとどうしようもない問い合わせへの対応なので、相手が納得してくれればそれで。
  • 「私のためにやってくれている」感のきっかけ 実体験から。相手を信頼するきっかけは相手からの声かけ(「○○様、いつもありがとうございます」
  • クレーマー対応、応答を気をつけないとユーザーの不快感をあおってしまう エージェントはオペレータの発話を見て返答している。実はオペレータが会話を誘導している

錯覚で無限にまっすぐ歩ける廊下を作る

Unity

VRゲーム

VR Jump Tour

  • Magic Pot 円筒形のものを触っているのに、ARで花瓶型のものを見ていると、花瓶型のものを触っているように知覚される
    • 古典的な感覚モデル:五感が独立して知覚、それぞれがそのまま認知
    • クロスモダリティ:五感からの情報を総合して認知
  • 無限廊下
    • ヘッドセットをつけて、円型の壁に手を当てて外周をぐるぐる歩く
    • 映像ではまっすぐ歩いているように見えている
    • 実際には円周をぐるぐるなのに、感覚的にはずっとまっすぐに感じられる

青森県立美術館7/20 - 9/2

スタートトゥデイ研究所

スタートトゥデイ

「世界中をカッコよく、世界中に笑顔を」 → 実際は、オシャレ好きにしか届いていない

感覚的に語られてきた「ファッション」を科学的に解明、数値化

3つの取組み

  • 「採寸」の研究
  • 「服作り」の研究
    • 課題:あらゆるサイズ/パターンをオンデマンドで作る、形・柄をカスタマイズできるインタフェース
  • 「似合う」の研究

AI Labにおける広告配信技術の研究開発について

CyberAgent

  • Response prediction 人に何かを与えたときの反応を予測する

RTB

  • レスポンス予測・予算制約を元に入札価格を算出
  • CTR予測値を元に配信する広告を選択

100msで実現されている

  • データ
    • RTB:
      • SSPからの情報
      • 広告主の情報
    • 広告選択:
      • クリエイティブの情報
      • RTBからの情報

Response prediction

  • ロジスティック回帰
  • field-aware Factorization Machines
  • Bandit Algorithm

  • 課題:Counterfactual

    • 配信した広告はユーザーからのフィードバック(Click or NOT)を得る
    • 配信できなかった広告はフィードバックを得ることができない 従来と異なる方針を取ったときの評価ができない
  • 解決:

    • Inverse Probability Weighting 直感的には「出現確率が高い → 評価が低い」「出現確率が低い → 評価が高い」
    • オフラインで評価したアルゴリズムで、RCTを実施、評価
  • 要研究

    • オフラインでの評価 実際のA/Bテストなどを行わずにアルゴリズムを評価する方法

スマートフォンから遠隔操作可能なデジタルサイネージの開発・応用

楽天

デジタルサイネージの課題

静的(ポスター) → 動的(デジタルディスプレイ) → インタラクティブ(タッチパネル)

  • 課題①:ゴールしない 何かを持ち帰らせるのが難しい
    • チラシ受け取る
    • webサイトを見る
    • 友達と共有する
    • 商品を購入する
  • 課題②:画面前がprivateになってしまう
    • 誰かがやっているとその人が専有する
    • 個人情報の入力ができない
    • 人前でいろいろやりたくない
  • 課題③:複数人で利用しにくい
    • 誰かがやってると入れない

インタラクティブスマホ

Wallshop - それぞれのスマホから画面操作 - カーソルを当てた商品の詳細情報がサイネージに表示される - しばらくカーソルを当て続けるとその人のスマホに情報が表示される - ディスプレイ・スマホともにwebブラウザ上で動作 - スマホの設定言語に合わせてコンテンツを翻訳

応用

野球場でやってみた → 画面遠い、そもそも楽天見る? → 画面でボートレース。勝敗予想、タップで応援

Q & A

  • 上限人数は? 負荷試験では100〜200人つなげられる。 実際問題としてそんなに画面に詳細情報出せない。

メルカリにおける画像認識の応用

メルカリ

保有データ

  • 売る側
    • 画像データ
    • 商品データ
  • 買う側
    • 属性データ
    • 検索・購入データ

Team AI

メルカリのアプリケーションにだけコミット。他はR4D

画像認識、NLP、MLシステム、量子アニーリング

MLシステム基盤整備、データエンジニアリングチーム:データ収集 ↓ Team AI(画像認識・NLP):要件定義、モデル作成/評価 ↓ プロジェクトのCRE, UX, growth, US/UK

  • データサイエンティスト vs データエンジニア サイエンティスト1人に対してエンジニア2〜3人必要(ぐぐれば記事が出る

画像認識プロジェクト

  • 感動出品/出品改善 写真撮った瞬間、画像がメルカリのサーバーへ → ブランド、商品特徴が自動入力される
  • 不正出品
    • 100万件以上/日
    • image + text をあわせて不正検知
    • image:CNN text:TF-IDF, MLP
  • 今後
    • すべての出品に対応する類似画像検索
    • 特徴抽出、次元削減、データ持ち方、検索。。。どうする??

Q & A

  • 組織体制はどういう経緯で 元々SREに基盤を任せていたのを、MLチーム内でということで受け持った
  • 様々なチームからの要求にどう優先順位つけるのか 全社的に優先事項が決まって、共有されている
  • 「感動出品」の成功はどうはかる? 出品完了率。出品が面倒だったら途中でやめちゃう。 感動出品プロジェクトでその数値は上がった。
  • 不正検知にマルチモーダル分析は必要? 悪意のあるユーザーは画像かテキストか、どちらか正しいのでは 実際は発送状況など様々な情報を加味している。 悪意のあるユーザーの不正は防げていない。悪意の無いユーザーの誤出品を防いでいる。 詳しくはブログで!

Scrapboxが自分用メモにちょうどいい件

scrapbox.io

友達に教えてもらったScrapboxがとてもちょうどよかったので誰にともなくおすすめしておく。

個人で何かつくったり人前でしゃべったりするとき、アイデアとか設計とかの構想を紙にいろいろ書いたあとマークダウンでまとめることが多いんだけど、残す場所が無かった。
Evernoteは見た目からして面倒そうで使いたくない、タスク管理するわけではないからbacklogとかもオーバースペック(?)で、仕方なくAtomで書いてAtom内のビューワーで見てた。

ニーズとしては「簡単な内容を構造化されたメモとして残せて、きれいに表示できればそれでいい」という感じ。
スマホから何かをメモすることも私の場合は無いから、連携は別にいらない。

Scrapboxがめっちゃちょうどいい(大事なことなので何度も言う)。
もしかしたら本来はチーム内とかいんたねっととかで共有するものなのかもしれないけど知らない。

良いところは:

  • Googleアカウントで使える
  • 入力しながらそのまま整形されて表示される
    ライブエディタとでも呼ぶのかなあ、入力欄・表示欄と分かれていなくて、入力がそのまま整形されて表示される。
  • 記法が簡単かつ豊富、シンタクスハイライトもある
    記法 - Scrapbox ヘルプ
  • エンターキーで(半角スペース無しで)普通に改行できる
  • ハッシュタグで整理できる
  • プロジェクト毎に公開範囲を決められる/知り合いと共有できる
  • 複数人で編集している間、全員の入力がリアルタイムに反映される(Google Docs的な)

こんなところか。
ちなみに今日使ったのはこういう作業メモ↓↓
箇条書きにするとき普通 - だけど、scrapboxでは行頭に半角スペース入れる。
半角スペースを複数個打つと階層付きの箇条書きにしてくれる。

[** やったこと]
 GAEでプロジェクト作成
  GAEでチュートリアル(デプロイされてしまった)
  いったんファイアウォールで全IPアクセス拒否
 開発環境
  [https://cloud.google.com/appengine/docs/standard/go/download Download the Cloud SDK  |  App Engine standard environment for Go  |  Google Cloud]
  SDKインストール
   上記画面からダウンロード & `install.sh` 実行
  `goapp` インストール
   [http://tweeeety.hateblo.jp/entry/2018/05/03/190537 【GAE】goappコマンドについて簡単にまとめてみた - tweeeetyのぶろぐ的めも]
   `$ gcloud components install app-engine-go`
   `google-cloud-sdk/platform/google_appengine/` 以下にインストールされるため、パスを通す
   `google-cloud-sdk/platform/google_appengine/goapp` に実行権限をつける
 Echo
  [https://echo.labstack.com/cookbook/google-app-engine Google App Engine Recipe | Echo - High performance, minimalist Go web framework]
 Twitter APIクライアントライブラリ
  [https://github.com/dghubble/go-twitter dghubble/go-twitter: Go Twitter REST and Streaming API v1.1]

f:id:chmv:20180505020326p:plain

見やすい!!!
メモする手間も全然無いしブログにまとめ直すときにも見返しやすい。
会社でも使いたいなあ、業務開発なりなんなりのあれこれをここにメモれたら捗りそう。。。
(GAEのやつ、明後日で動くとこまで持っていきたいな)

こまごまとしたちょこちょこ(2018年4月)

まとまったことを書く必要は別に無いんじゃないかと思い直して、最近ちょこちょこ見たものを書いてみる。
色々あって最近はがっつりした開発は担当していなくて、こまかいバグ対応とかちょっとした調査をやっているので、そのあたり。

redash

相変わらず。 作ってって言われた表に複数のデータソース(MySQLとTreasureData)に持っている情報が混在していて最初うげってなったけど、Pythonであっさり作れた。
execute_query(data_source_name_or_id, query) の第一引数をMySQLだったりTreasureDataだったりにするだけ、あとは結果をよしなに紐付けて表示させればOK。
噂では直接JOINできるらしいけど、クエリ結果をデータソースとして扱う感じか?

Re:dashで異なるData Sourceのクエリ結果をJOINできるようになったので試してみた - Query Results (Alpha) - Gunosyデータ分析ブログ
(2016年……)

負荷テストツール

初めて見た。 といってもちゃんとシナリオ組んだ負荷テストをやったわけではなく、ただ攻撃したかった()
tsungとJMeterを入れてみたけどどっちもhomebrewで入るし(JMeterは別途JDKを入れる必要がある)設定も楽だし、負荷ってこんなにあっさりかけられるんだと。
tsungのテスト設定はXMLで、JMeterGUIで作る。ただしJMeterで実際の負荷テストをやるときはGUIからではなくコマンドラインから実行せよとのことらしい。
tsungをOS Xから動かすときはこれをひな形にするとよいそうな、tsungのバージョンがXMLに直書きされてるのだけ直せば動いた。
GitHub - kurebio/mac-tsung

クローリング

社内の勉強会でRuby + nokogiriを一瞬やったことあるけど、ちゃんとしたのは初。 casprejsとphantomjsなるものを触った。
といってもスクレイピングしたかったわけではなく、埋め込んだjsタグから別のプログラムがちゃんと呼ばれてるかを確認したくて、jsタグだけ貼ったページにばこばこアクセスして結果取ってきた感じ。
curlだと返されたjsが実行されなくて困った → ここを見てphantomjsで。どっちもまたhomebrewで入って便利。
各種スクレイピングのために、レンダリング後(JavaScript実行後)のHTMLを出力するAPIを作る - Qiita

PHP + smarty

自社開発の管理画面で使ってるけどあんまりさわる機会無くてド初心者。 なんだか文字が表示されないところがある、とのことで調べた。
直接の原因は先輩に教えてもらったけど、 htmlspecialchars() の引数が正しく設定されていなかったらしい。

string htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = ini_get("default_charset") [, bool $double_encode = TRUE ]]] )

PHP: htmlspecialchars - Manual

ここの第三引数が実際のプログラムでは省略されていて、デフォルト(のUTF-8)として扱われていた。
ファイル見るとEUC-JPだったので第三引数を追加してあげて解決。

[PHP]htmlspecialchars()を使うと文字が消える? | PHP Archive

Paiza Cloud

ちょっと話はそれるけど便利だった!
jupyterで配布されてた資料を見たかったんだけど手元に環境なくてめんどくせーとか思ってたら、ここで最初からjupyter整備されてるサーバー借りられた。
よく見たら有料プランだと公開もできるらしい。
無料プランだと途中で接続切れたりするけどまあストレスたまったら手元に立てることにする。

PaizaCloud Cloud IDE - Browser-based web development environment for Ruby on Rails, PHP, Java, Django, Node.js...

なんか器用貧乏感が増してるしそろそろちゃんとひとつの言語勉強してまともなエンジニアになりたい、と思い始めてPyQでもやろうかしらんというのが最近のあれ。
あと『[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識』を読み終えた。通勤読書でぜんぜん試してないおかげで半分くらいの理解だけど、とっかかりとしてはちょうどよかったんではないかと! 今すぐ何かに使えるというよりは次にもうちょっと詳しい本を読んでみる土台が出来た感じかな。

https://www.amazon.co.jp/dp/B079YJS1J1/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

jsだけレスポンスヘッダで文字コードを設定する @Apache

Apacheでjsが文字化けした。

ファイルの文字コードも無茶苦茶だしApacheよくわかんないしあーあーしてたら先輩が解決してくれた、自力で見つけられなくて悔しかったから書いとく。

直接の原因はjsファイルはUTF-8だったのにレスポンスヘッダを見るとEUC-JPが指定されていたこと(PHPのファイルがEUC-JPだったから?

というわけでjsはUTF-8で開いてほしい → .htaccess があったからそれにこう書いて終わり。

AddCharset utf-8 .js

今回言われるがままに .htaccess に追記したけど積極的に使うべきものではないのかな↓↓

Apache チュートリアル: .htaccess ファイル - Apache HTTP サーバ バージョン 2.4

一般的に、サーバの主設定ファイルにアクセスできない場合を除いて、 .htaccess ファイルの使用は極力避けてください。

複数のユーザーがどうしても自分の好きに設定したいときに各人作るものらしい。
リクエストのたびに .htaccess のファイル探すコストがかかるのと、ユーザーがwebサーバーの設定をいじくれる状態はよくないのと、というところだそう。

というかApache + PHP、どこで何が起きてるのかわからなすぎて苦手。nginxのほうがまだがんばれる。。。

ネットワーク調査あれこれメモ①

会社でなんか変だぞーって調べてたときに打ったやつとか参考にした記事とか、何度か同じこと調べてるので残しておく。
誰の利にも別にならないことを書いておけるのは個人ブログの良いとこだと思う。
予定は無いけど②とか③とか生まれる気がするから①(YAGNI!!)

状態ごとの接続数

[hirapi@server ~]$ netstat -tan | awk '{print $6}' | sort | uniq -c
      4 CLOSE_WAIT
     88 ESTABLISHED
      1 FIN_WAIT2
      1 Foreign
     12 LISTEN
   2598 TIME_WAIT
      1 established)

規定時間以上残っているTIME_WAIT

[hirapi@server ~]$ netstat -nato|egrep -c 'timewait. *\(0.00'
2001

TIME_WAITに関する話

半分以上わからなかったけどこちらのスライドありがたかった、kernel 3.Xだとうまく回収してくれないのね。。。

ついでにカーネルのバージョン確認は

[hirapi@server ~]$ cat /proc/version
Linux version 2.6.32-358.el6.x86_64 (mockbuild@c6b8.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) ) #1 SMP Fri Feb 22 00:31:26 UTC 2013

[hirapi@server ~]$ yum list installed | grep kernel
dracut-kernel.noarch               004-409.el6_8.2            @updates
kernel.x86_64                      2.6.32-358.el6             @anaconda-CentOS-201303020151.x86_64/6.4
kernel.x86_64                      2.6.32-696.18.7.el6        @updates
kernel-devel.x86_64                2.6.32-642.4.2.el6         @updates
kernel-devel.x86_64                2.6.32-696.18.7.el6        @updates
kernel-firmware.noarch             2.6.32-696.18.7.el6        @updates
kernel-headers.x86_64              2.6.32-696.18.7.el6        @updates

(開発環境だから……)

recycleとreuse

net.ipv4.tcp_tw_recycle は廃止されました ― その危険性を理解する - Qiita

ロードバランサの配下にある通信ではパケットに振られるタイムスタンプ(の前後関係)が実時間と一致しているかわからないため、タイムスタンプで新旧を判断するrecycleを有効にすると意図しない切断が起こる可能性がある、とのこと?

TCP関連のカーネルの設定ファイル

/etc/sysctl.conf
変更はこれ書き換えてから # sysctl -p

ローカルポートを広げる

接続数多すぎてなんか止まっちゃった、という時はローカルポートを使い切っている可能性を疑う。変更は↑↑の設定ファイルのここ

net.ipv4.ip_local_port_range = 20000 65500

ローカルポートを食いつぶしていた話 - ダウンロードたけし(寅年)の日記

サーバーとかネットワークとかぜんぜんわからずにアプリケーション書くと最後はこういうとこで詰まってお手上げになる。
平気で6万回もMySQLサーバーに繋ぐ画面なんて作らないでよ過去の人……。
とはいえちょっとだけ低レイヤー(?)に興味を持てた、Linuxとかネットワークとかちょこちょこ読書中。

redashの入力フォームで「特定の値 -> 無指定」として扱いたいときのSQL

redash.io

こんなテーブルがあったとして、

mysql> SELECT * FROM users;
+----+-----------+------+----------+
| id | name      | age  | group_id |
+----+-----------+------+----------+
|  1 | hirapi    |   25 |        1 |
|  2 | someone   |  100 |        1 |
|  3 | young man |    6 |        2 |
+----+-----------+------+----------+

redashの入力フォームに「対象グループID」を入力して、そのグループの人の名前を取ってきたいとする。 redashは {{フォーム名}} で入力値を取れるので、普通に書くと

SELECT name FROM users WHERE group_id = {{対象グループID}}

となる。

ここで、例えば「グループ関係無くみんなの名前も取れるようにしたい、クエリは分けたくない」みたいなこと言われたら、 「入力フォームに 0 を入れたらグループ無指定ということで全員の名前を取ってくる」というのはどうだろうということになる。

pythonでif文はさんでクエリ作るのもアリといえばアリだけど面倒くさいなあと思った結果↓↓

SELECT name FROM users WHERE {{対象グループID}} = 0 OR group_id = {{対象グループID}}

対象グループID が0だったら

mysql> SELECT name FROM users WHERE 0 = 0 OR group_id = 0;
+-----------+
| name      |
+-----------+
| hirapi    |
| someone   |
| young man |
+-----------+

対象グループID が1だったら

mysql> SELECT name FROM users WHERE 1 = 0 OR group_id = 1;
+---------+
| name    |
+---------+
| hirapi  |
| someone |
+---------+

クエリチューニングの面から見たら良くないかもしれないけどさくっと作れたし今回はおっけー。
別にredashに限った話ではないけど入力値をそのままクエリに突っ込むのがredashくらいしかなかった。