{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "# tsfreshを用いた特徴量自動生成と分類\n",
        "\n",
        "ToyCar編\n"
      ],
      "metadata": {
        "id": "uj7jI2g5cZlt"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from google.colab import drive\n",
        "drive.mount('/content/drive')"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "v9p3BxzUPgSg",
        "outputId": "b226f7f1-1b87-4681-fe72-acad164a50fe"
      },
      "execution_count": 1,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Mounted at /content/drive\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## tsfreshのインストール"
      ],
      "metadata": {
        "id": "Hdqe-M98ckxa"
      }
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "h7K_4Xvt8Vrp",
        "outputId": "f7207e8e-4320-49f5-97c2-e189755f16b5"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Requirement already satisfied: tsfresh in /usr/local/lib/python3.12/dist-packages (0.21.1)\n",
            "Requirement already satisfied: requests>=2.9.1 in /usr/local/lib/python3.12/dist-packages (from tsfresh) (2.32.4)\n",
            "Requirement already satisfied: numpy>=1.15.1 in /usr/local/lib/python3.12/dist-packages (from tsfresh) (2.0.2)\n",
            "Requirement already satisfied: pandas>=0.25.0 in /usr/local/lib/python3.12/dist-packages (from tsfresh) (2.2.2)\n",
            "Requirement already satisfied: statsmodels>=0.13 in /usr/local/lib/python3.12/dist-packages (from tsfresh) (0.14.6)\n",
            "Requirement already satisfied: patsy>=0.4.1 in /usr/local/lib/python3.12/dist-packages (from tsfresh) (1.0.2)\n",
            "Requirement already satisfied: pywavelets in /usr/local/lib/python3.12/dist-packages (from tsfresh) (1.9.0)\n",
            "Requirement already satisfied: scikit-learn>=0.22.0 in /usr/local/lib/python3.12/dist-packages (from tsfresh) (1.6.1)\n",
            "Requirement already satisfied: tqdm>=4.10.0 in /usr/local/lib/python3.12/dist-packages (from tsfresh) (4.67.3)\n",
            "Requirement already satisfied: stumpy>=1.7.2 in /usr/local/lib/python3.12/dist-packages (from tsfresh) (1.13.0)\n",
            "Requirement already satisfied: cloudpickle in /usr/local/lib/python3.12/dist-packages (from tsfresh) (3.1.2)\n",
            "Requirement already satisfied: scipy>=1.14.0 in /usr/local/lib/python3.12/dist-packages (from tsfresh) (1.16.3)\n",
            "Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.12/dist-packages (from pandas>=0.25.0->tsfresh) (2.9.0.post0)\n",
            "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.12/dist-packages (from pandas>=0.25.0->tsfresh) (2025.2)\n",
            "Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.12/dist-packages (from pandas>=0.25.0->tsfresh) (2025.3)\n",
            "Requirement already satisfied: charset_normalizer<4,>=2 in /usr/local/lib/python3.12/dist-packages (from requests>=2.9.1->tsfresh) (3.4.6)\n",
            "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.12/dist-packages (from requests>=2.9.1->tsfresh) (3.11)\n",
            "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.12/dist-packages (from requests>=2.9.1->tsfresh) (2.5.0)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.12/dist-packages (from requests>=2.9.1->tsfresh) (2026.2.25)\n",
            "Requirement already satisfied: joblib>=1.2.0 in /usr/local/lib/python3.12/dist-packages (from scikit-learn>=0.22.0->tsfresh) (1.5.3)\n",
            "Requirement already satisfied: threadpoolctl>=3.1.0 in /usr/local/lib/python3.12/dist-packages (from scikit-learn>=0.22.0->tsfresh) (3.6.0)\n",
            "Requirement already satisfied: packaging>=21.3 in /usr/local/lib/python3.12/dist-packages (from statsmodels>=0.13->tsfresh) (26.0)\n",
            "Requirement already satisfied: numba>=0.57.1 in /usr/local/lib/python3.12/dist-packages (from stumpy>=1.7.2->tsfresh) (0.60.0)\n",
            "Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in /usr/local/lib/python3.12/dist-packages (from numba>=0.57.1->stumpy>=1.7.2->tsfresh) (0.43.0)\n",
            "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.12/dist-packages (from python-dateutil>=2.8.2->pandas>=0.25.0->tsfresh) (1.17.0)\n"
          ]
        }
      ],
      "source": [
        "!pip install tsfresh"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## ライブラリのインポート"
      ],
      "metadata": {
        "id": "9C81BMEmcuAI"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n",
        "import pathlib\n",
        "import glob\n",
        "\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "\n",
        "import tensorflow as tf\n",
        "\n",
        "from sklearn.model_selection import train_test_split\n",
        "\n",
        "import matplotlib.pyplot as plt"
      ],
      "metadata": {
        "id": "sjJBSdZO-ZUO"
      },
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "tsfresh関連のライブラリのインポート"
      ],
      "metadata": {
        "id": "zRQS4qo2g59R"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from tsfresh.examples.robot_execution_failures import download_robot_execution_failures, load_robot_execution_failures\n",
        "from tsfresh import select_features\n",
        "from tsfresh.utilities.dataframe_functions import impute\n",
        "from tsfresh import extract_features\n",
        "\n",
        "#毎回同じ結果になるように、乱数のseedを固定\n",
        "seed = 0\n",
        "tf.random.set_seed(seed)\n",
        "np.random.seed(seed)"
      ],
      "metadata": {
        "id": "ibgmPJMm8XS9"
      },
      "execution_count": 4,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "## ToyCarデータの読み込み"
      ],
      "metadata": {
        "id": "xnwRI0sWcxBG"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "#展開した音データのディレクトリ(ファイルの展開で指定したディレクトリ)\n",
        "data_dir = pathlib.Path(\"/content/drive/MyDrive/Anomaly_Detection/dataset/ToyCar\")"
      ],
      "metadata": {
        "id": "QNdp9aw8g1ec"
      },
      "execution_count": 5,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# 学習とテストに使うデータの読み込み\n",
        "# case4以外を使う場合はこの部分を変更\n",
        "data_normal = glob.glob(str(data_dir) + '/test/normal_id_04_*')\n",
        "print(\"データ（正常）の数：\", len(data_normal))\n",
        "data_anormaly = glob.glob(str(data_dir) + '/test/anomaly_id_04*')\n",
        "print(\"データ（異常）の数：\", len(data_anormaly))"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "sDBJn4KJ46IK",
        "outputId": "7da33ab9-19e9-48b0-ca7a-9a23e4c14c01"
      },
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "データ（正常）の数： 350\n",
            "データ（異常）の数： 265\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "#ラベルのリストを作っておく\n",
        "label_names = [\"Normal\",\"Anormaly\"]\n",
        "data_normal_id = [0]*len(data_normal)\n",
        "data_anormaly_id = [1]*len(data_anormaly)"
      ],
      "metadata": {
        "id": "ikq_NgJX46Fd"
      },
      "execution_count": 7,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "## 学習データとテストデータの分割"
      ],
      "metadata": {
        "id": "d0COhJcev5OM"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "#訓練、テストデータに分ける\n",
        "train_data, test_data, train_labels, test_labels= train_test_split(data_normal+data_anormaly,data_normal_id + data_anormaly_id, test_size=0.2, random_state=seed)  #\n",
        "#訓練、検証データに分ける\n",
        "train_data, valid_data, train_labels, valid_labels= train_test_split(train_data,train_labels, test_size=0.25, random_state=seed)  #\n",
        "print(\"訓練データの数：\", len(train_data))\n",
        "print(\"検証データの数：\", len(valid_data))\n",
        "print(\"テストデータの数：\", len(test_data))"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "NnXoFJBY459T",
        "outputId": "8c0ff61d-9444-4bd3-886a-81a785bc88f9"
      },
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "訓練データの数： 369\n",
            "検証データの数： 123\n",
            "テストデータの数： 123\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "def makeData(data, labels, n=20):\n",
        "  df_data = pd.DataFrame(columns=['id','value'])\n",
        "  df_label = pd.Series()\n",
        "  for i in range(len(data)):\n",
        "    filename = data[i]\n",
        "    labelname = labels[i]\n",
        "    example_file = tf.io.read_file(filename)\n",
        "    example_audio, sampling_rate = tf.audio.decode_wav(contents=example_file)\n",
        "    df_data0 = pd.DataFrame(example_audio.numpy(),columns=['value'])\n",
        "    fn = filename.split('/')[-1]\n",
        "    df_data0.insert(0, 'id', fn)\n",
        "    df_data = pd.concat([df_data,df_data0[0:1024]], ignore_index=False)\n",
        "  #  df_label.loc[fn] = labelname\n",
        "    if labelname:\n",
        "      df_label.loc[fn] = True\n",
        "    else:\n",
        "      df_label.loc[fn] = False\n",
        "  return df_data, df_label.sort_index(ascending=True)"
      ],
      "metadata": {
        "id": "auZEP2sk5WlU"
      },
      "execution_count": 9,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "df_data_train, df_label_train =makeData(train_data,train_labels)\n",
        "df_data_test, df_label_test =makeData(test_data,test_labels)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Fn6jqvME5Wia",
        "outputId": "9e47bda9-77cd-4815-b835-22464827541b"
      },
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/tmp/ipykernel_11169/3987751654.py:12: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n",
            "  df_data = pd.concat([df_data,df_data0[0:1024]], ignore_index=False)\n",
            "/tmp/ipykernel_11169/3987751654.py:12: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n",
            "  df_data = pd.concat([df_data,df_data0[0:1024]], ignore_index=False)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## 特徴量の抽出"
      ],
      "metadata": {
        "id": "4H66zUDNwF4w"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from tsfresh import extract_features\n",
        "extracted_features_train = extract_features(df_data_train, column_id=\"id\")\n",
        "extracted_features_test = extract_features(df_data_test, column_id=\"id\")\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "84TFXL1w5Wfm",
        "outputId": "84158a29-0d5d-4502-e3e6-a39f982231c7"
      },
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "WARNING:tsfresh.feature_extraction.settings:Dependency not available for matrix_profile, this feature will be disabled!\n",
            "Feature Extraction: 100%|██████████| 369/369 [07:49<00:00,  1.27s/it]\n",
            "WARNING:tsfresh.feature_extraction.settings:Dependency not available for matrix_profile, this feature will be disabled!\n",
            "Feature Extraction: 100%|██████████| 123/123 [02:37<00:00,  1.28s/it]\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## すべてが0であったり、値がなかったりする特徴量を削除"
      ],
      "metadata": {
        "id": "OJyGEhsIwPu8"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "\n",
        "extracted_features_train_impute = impute(extracted_features_train)\n",
        "extracted_features_test_impute = impute(extracted_features_test)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "eFWrrtgt86Ac",
        "outputId": "12e1e115-9f98-4c96-bf81-a902e456fe2a"
      },
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.12/dist-packages/tsfresh/utilities/dataframe_functions.py:198: RuntimeWarning: The columns ['value__query_similarity_count__query_None__threshold_0.0'] did not have any finite values. Filling with zeros.\n",
            "  warnings.warn(\n",
            "/usr/local/lib/python3.12/dist-packages/tsfresh/utilities/dataframe_functions.py:198: RuntimeWarning: The columns ['value__query_similarity_count__query_None__threshold_0.0'] did not have any finite values. Filling with zeros.\n",
            "  warnings.warn(\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## すべての特徴量を使ってランダムフォレストにより分類テスト\n",
        "\n",
        "テストデータでは約50%となり、分類で規定に事がわかる"
      ],
      "metadata": {
        "id": "IcoycMpAwXGm"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from sklearn.ensemble import RandomForestClassifier\n",
        "from sklearn.model_selection import cross_val_score\n",
        "clf = RandomForestClassifier(random_state=0)\n",
        "clf.fit(extracted_features_train_impute, df_label_train)\n",
        "result_train = clf.predict(extracted_features_train_impute)\n",
        "#print(np.sum(result_train==df_label_train.to_numpy()))\n",
        "result_test = clf.predict(extracted_features_test_impute)\n",
        "#print(np.sum(result_test==df_label_test.to_numpy()))\n",
        "print(\"訓練スコア: {:.3f}\".format(clf.score(extracted_features_train, df_label_train.to_numpy())))\n",
        "print(\"テストスコア:{:.3f}\".format(clf.score(extracted_features_test, df_label_test.to_numpy())))"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Z1PwrFxz5WdR",
        "outputId": "14a77d26-00b9-47ff-b3dd-218ce333b15f"
      },
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "訓練スコア: 1.000\n",
            "テストスコア:0.512\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## すべての特徴量を使ってSVM（サポート・ベクタ・マシン）により分類テスト\n",
        "\n",
        "テストデータでは約50%となり、分類で規定に事がわかる"
      ],
      "metadata": {
        "id": "VnmjcMDHwiHF"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from sklearn.svm import SVC\n",
        "clf = SVC(kernel='rbf', gamma='auto', random_state=0)\n",
        "\n",
        "clf.fit(extracted_features_train_impute, df_label_train)\n",
        "pred_train = clf.predict(extracted_features_train_impute)\n",
        "print(\"訓練スコア: {:.3f}\".format(clf.score(extracted_features_train_impute, df_label_train.to_numpy())))\n",
        "pred_test = clf.predict(extracted_features_test_impute)\n",
        "print(\"テストスコア:{:.3f}\".format(clf.score(extracted_features_test_impute, df_label_test.to_numpy())))"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "5k_d9Pcb5WbD",
        "outputId": "dd5b2d4d-3476-48d5-9097-4dfa75c06e18"
      },
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "訓練スコア: 1.000\n",
            "テストスコア:0.545\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "X_d3Ggr45WYl"
      },
      "execution_count": 14,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "7W7Zul1JkQJx"
      },
      "execution_count": 14,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "P4tV-SZ0kQLp"
      },
      "execution_count": 14,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "-iB0s_I2Qh4Z"
      },
      "execution_count": 14,
      "outputs": []
    }
  ]
}