#TeachableMachine で夫婦喧嘩をイヌに食わせてみた🐶

## お悩み相談
### Q. 26歳女性。結婚して4か月、夫婦喧嘩が止まりません。
お互い仕事が忙しく余裕がないからか、ちょっとしたことで衝突してしまいます。仲直りしようと謝っても、
「**ごめんね**:rage:」
「**それはごめんと思っている人の言い方じゃない！！！**:japanese_ogre:」
という言い争いになってしまい、うまく仲直りできません。まだ結婚して半年もたっていないのに…先が思いやられます。どうしたらよいでしょうか。
（埼玉・C子）

### A. 客観的な視点からご自身の言動を振り返ってみましょう🐶
[夫婦喧嘩は犬も食わない](https://kotobank.jp/word/%E5%A4%AB%E5%A9%A6%E5%96%A7%E5%98%A9%E3%81%AF%E7%8A%AC%E3%82%82%E9%A3%9F%E3%82%8F%E3%81%AC-2079164)といえど、問題解決には客観的な視点も重要です。お二人は気づかないうちに言い方がきつくなってしまっているのかもしれません。夫婦円満のためにも、一度ご自身の謝り方を客観的な視点でチェックし、仲直りに役立ててみてはいかがでしょうか。

という世の夫婦のお悩みを解決するために作られたWebアプリはこちら:information_desk_person_tone1:

## 夫婦喧嘩食べる犬🐶
夫婦喧嘩をエサにするイッヌが、あなたの「**ごめんね**」の出来を判定します！
Webアプリはこちらからお使いいただけます:point_down:
- [夫婦喧嘩食べる犬🐶](https://fufu-genka-taberu-ken.netlify.app/)
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958610/c67a47cc-9a53-be19-77e4-a08728fa5018.png">

### つかいかた
- 「**エサをあたえる**」ボタンを押す
- ブラウザでマイクを許可
- 数秒待って「**ごめんね**」と言う
- イッヌ🐶があなたの「**ごめんね**」の出来をチェック！

:::note warn
**PCのブラウザ**で使用することを推奨します。私は**Chrome**を利用しています。
**Androidスマホ**ではうまく動作しない場合があります。**iPhoneは非対応**です。
:::

## つくりかた
### つかった技術
- HTML
- JavaScript
  - [ml5.js](https://ml5js.org/)・・・Webアプリケーション上で機械学習を手軽に行うことができる JSライブラリ
  - [Teachable Machine](https://teachablemachine.withgoogle.com/)・・・機械学習の独自モデルが作成できるWebアプリケーション
  - [WebSpeechAPI](https://developer.mozilla.org/ja/docs/Web/API/Web_Speech_API)・・・音声の認識・発話を行うことができるWeb標準の技術

### ①Teachable Machineでモデル作り
[Teachable Machine](https://teachablemachine.withgoogle.com/train)の音声プロジェクトを使用しました。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958610/b0337eaa-faf0-7d19-b350-1ffe448b0254.png">

作成した音声モデルはこちらです:information_desk_person_tone1:
https://teachablemachine.withgoogle.com/models/nwI4LEujG/

- 音声モデル作成手順
1. バックグラウンドノイズ：部屋の環境音を録音します
2. 謝ってる：心を込めた「**ごめんね**」をひたすら録音し続けます
3. 謝ってない：乱暴な「**ごめんね**」をひたすら録音し続けます

:::note info
「2. 謝ってる」と「3. 謝ってない」を録音するときは、「**1秒間録音する**」を選びましょう。1秒以内の「**ごめんね**」をできるだけ多く録音することが、判定の精度を上げるポイントです！
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958610/b562c775-23bc-8413-6e88-68a080407fa7.png">

:::

### ②コーディング
すべてのファイルを同じ階層に置く前提です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958610/77c44833-ae9f-af0f-7251-515502bdaa76.png)
<details><summary>HTMLコード</summary>

```HTML:index.html
<!DOCTYPE html>
<html lang="ja" >
<head>
  <meta charset="UTF-8">
  <title>夫婦喧嘩食べる犬🐶</title>
  <meta name="viewport" content="width=device-width, initial-scale=1"><link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css'>

</head>
<body>
<div class="container text-center text-primary">

  <div class="row my-3">
    <div class="col-sm-6 mx-auto"><h1>夫婦喧嘩食べる犬🐶</h1></div>
  </div>

  <div class="row my-3">
    <div class="col-sm-6 mx-auto">
      <h3 id="result">「ごめんね」って言ってみてワン！</h3>
    </div>
  </div>
  
  <img height="auto" width="200" src="./innu.png">
  
  <div class="row my-3">
    <div class="col-sm-6 mx-auto">
      <button class="btn btn-primary" onclick="start()">確認</button>
      <p>「確認」を押す⇒マイクを許可⇒数秒待って「ごめんね」って言おう</p>
    </div>
  </div>
  
</div>
<script src='https://unpkg.com/ml5@latest/dist/ml5.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.0/js/bootstrap.min.js'></script>
<script  src="./script.js"></script>

</body>
</html>
```

</details>

<details><summary>JavaScriptコード</summary>

```JavaScript:script.js
// 作成したモデルのURL
const soundModelURL = 'https://teachablemachine.withgoogle.com/models/nwI4LEujG/';
window.SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition;
var recognition = new webkitSpeechRecognition();

// 音声認識されたらエラーがerrに、結果配列がresultsに入れられて以下の関数が実行されます
async function recognized(err, results) {
    if (results[0] && results[0].label == '謝ってない') {
        console.log('それ、ちゃんと謝ってる？');
        document.getElementById("result").textContent = '＼もうひといき！／';
      　await readAloud(results[0].label);
    } else if (results[0] && results[0].label == '謝ってる') {
        console.log('OK！');
        document.getElementById("result").textContent = '＼完璧！／';
        await readAloud(results[0].label);
    } else {
        document.getElementById("result").textContent = '';
    }
}

// メインの関数（ここでは定義しているだけでボタンクリックされたら実行）
async function start() {

    // オプション：確度がどれぐらい以上なら認識したとみなすか
    const options = { probabilityThreshold: 0.7 };

    // Googleのサーバーにアップロードした自作モデルを読み込みにいきます
    const classifier = ml5.soundClassifier(soundModelURL + 'model.json', options, () => {
        // 読み込みが完了次第ここが実行されます
        console.log('モデルの読み込みが完了しました');

        // 認識を開始します
        // ここで認識開始を1度宣言すると、音声が検出され次第何度でも関数recognizedが実行されます
        classifier.classify(recognized);
    });
}

function readAloud(result) {
    // ブラウザにWeb Speech API Speech Synthesis機能があるか判定
    if ('speechSynthesis' in window) {
        // 発言を設定
        const uttr = new SpeechSynthesisUtterance();
        if (result == '謝ってない') {
            uttr.text = '深呼吸して落ち着くワン！'
        } else if (result == '謝ってる') {
            uttr.text = '反省してるワン！ゆるしてあげてワン。'
        }
        // 言語を設定
        uttr.lang = "ja-JP"
        // 速度を設定
        uttr.rate = 1
        // 高さを設定
        uttr.pitch = 1
        // 音量を設定
        uttr.volume = 1
        // 発言を再生
        window.speechSynthesis.speak(uttr)
    } else {
        alert('大変申し訳ありません。このブラウザは音声合成に対応していません。')
    }
}
```
</details>

<details><summary>イッヌ（innu.png）</summary>

![innu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958610/466cf10f-0e66-d2f8-691b-3bd548f811d3.png)
</details>

## 実践！
実際の夫婦喧嘩で使ってみました！
果たして、仲直りできるのか！？！？！？
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">【夫婦喧嘩食べる犬🐶】<br>「ごめんね😡」「それはごめんと思っている人の言い方じゃない👹」という罵り合いに終止符を。夫婦喧嘩をｲｯﾇが食います🍽<br>キッチンで夫と仲直り🫶<br>※音量注意<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/%E5%A4%AB%E5%A9%A6%E5%96%A7%E5%98%A9?src=hash&amp;ref_src=twsrc%5Etfw">#夫婦喧嘩</a> <a href="https://t.co/OJGCkHuyyP">pic.twitter.com/OJGCkHuyyP</a></p>&mdash; ちーろってぃ🐶通勤をハッピーに (@chiiirotty) <a href="https://twitter.com/chiiirotty/status/1665291368091070464?ref_src=twsrc%5Etfw">June 4, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

無事夫と仲直りできました:clap:
みなさんもぜひ、**夫婦喧嘩食べる犬**🐶で平和な夫婦生活を:kissing_heart: