LoginSignup
8
4

More than 3 years have passed since last update.

ファジィ論理で振る舞いに"あいまいさ"を取り入れる

Last updated at Posted at 2020-12-25

この記事はGoodpatch Advent Calendar 2020 19日目の記事の逆行投稿です。

以前投稿した 今日から始めるCreative Coding環境3選 - Qiita の記事で @thi-ng/umbrella というTypeScriptのCreative Coding環境を紹介しました。thi.ng はフレームワークというより単独でも組み合わせても使える膨大なパッケージの集合体(developブランチには140個以上)で、現在も活発に開発が進んでいます。そのthi.ngに最近 @thi.ng/fuzzy というファジィ論理を扱うライブラリがα版として追加されました。家電やロボット制御などに応用されることの多いファジィ論理をCreative Codingのライブラリに取り入れるのは面白いなと思ったので、今回はそちらを簡単に紹介します。

ファジィ論理 (Fuzzy Logic)とは

ファジィ論理はコンピューターによる推論に「あいまいさ」を導入します。
ルールベースのロジック(いわゆるif文ですね)は一般に真(true)か偽(false)を推論結果として返しますが、ファジイ論理は真理値が0~1の間の値を取り、真偽の2つの値では表せないようなあいまいな推論を扱えます。

また「暑い」や「涼しい」、「苦い」や「甘辛い」など、人間の認知や言葉で変数を表現できることも特徴です。
定量的な入力値を言語学的変数(Linguistic variables, L-vars)にラベル付けして推論規則を考えることができます。

fuzzyはこうした推論を型付きの計算で簡単に取り使えるようなAPIを提供します。

fuzzyの使い方

thi-ng はモノレポで構成されているのでパッケージ単位でインストールできます。fuzzy と一緒に可視化を行うヘルパーライブラリの fuzzy-viz もセットでインストールしましょう。

$ yarn add @thi.ng/fuzzy @thi.ng/fuzzy-viz

ファジィ論理の典型的に使用される温度の例:

// L-varsの定義
const temp = variable(
  // 値(温度の取りうる値域)
  [-20, 40],
  {
    凍えそう: invSigmoid(0, 2),
    寒い: trapezoid(-1, 2, 16, 20),
    暖かい: trapezoid(15, 20, 30, 34),
    暑い: sigmoid(32, 2),
  }
);

具体的な入力値(= 18)をL-varsに適用

evaluate(temp, 18);
// {
//   凍えそう: 2.220446049250313e-16,
//   寒い: 0.5,
//   暖かい: 0.6,
//   暑い: 6.914400106935423e-13
// }

具体的な入力値(= 28)をL-varsに適用

evaluate(temp, 28);
// {
//   凍えそう: 0,
//   寒い: 0,
//   暖かい: 1,
//   暑い: 0.0003353501304664781
// }

候補の中で妥当な変数に分類

classify(temp, 28, 0.33));
// 暖かい

定義したL-varsの可視化:

import { varToSvg } from "@thi.ng/fuzzy-viz";

fs.writeFileSync("dist/temperature.svg", varToSvg(temp, { samples: 200 }));

temperature_svg_and_dist.png

推論ルールの定義

入力変数と出力変数を組み合わせて知識ベースの推論ルールを定義することができます。このルールにより、人間の認知ベースの意思決定をシミュレートすることができます。

const inputs = {
  食事: variable([0, 10], {
    まずい: invRamp(1, 3),
    美味しい: ramp(7, 9),
  }),
  サービス: variable([0, 10], {
    悪い: gaussian(0, 1.5),
    良い: gaussian(5, 1.5),
    素晴らしい: gaussian(10, 1.5),
  }),
};

const outputs = {
  チップ: variable([0, 30], {
    少なめ: triangle(0, 5, 10),
    普通: triangle(10, 15, 20),
    多め: triangle(20, 25, 30),
  }),
};

type I = typeof inputs;
type O = typeof outputs;

// ルール定義:
// 食事 が まずい か サービス が 悪い ならば チップ は 少なめ と推論
// サービス が 良い ならば チップ は 普通 と推論
// 食事 が 美味しい か サービス が 素晴らしい ならば チップ は 多め と推論
const rules = [
  or<I, O>({ 食事: "まずい", サービス: "悪い" }, { チップ: "少なめ" }),
  or<I, O>({ サービス: "良い" }, { チップ: "普通" }),
  or<I, O>({ 食事: "美味しい", サービス: "素晴らしい" }, { チップ: "多め" }),
];

defuzz(
  inputs,
  outputs,
  rules,
  // 入力値
  { 食事: 7.32, サービス: 7.83 }
);
// 推論結果 { チップ: 22.650000000000034 }

アプリケーションに応用するとしたら

制御系のシステムでなくても、一般的なアプリケーションの振る舞いとしてルールベースの分岐を入れている箇所はいろいろあると思います。ファジィ論理への置き換えでアイディエーションしてみると

  • ユーザーからの入力や、画面内の状態から振る舞い(戦略)を変える
    • インタラクション
    • 画面の表示
  • 画面内の表示コンポーネント数によるパフォーマンス調整
  • NPC的なアバターの操作
  • カーソル移動の加速度で傾き
  • ポップアップウインドウのちょうど良い配置
  • 近いエリア内のオブジェクト配置の密を避ける。近いと邪魔だから避けるような振る舞い

参考

  1. ファジィ論理 - Wikipedia
  2. あいまいさの効用 ー ファジィ理論とその周辺 ー (pdf)
  3. Fuzzy Logic (pdf)
  4. ファジィ理論を応用した魚ロボットの運動制御
  5. ファジー理論とは何か?AIで話題の論理をわかりやすく解説 | ソフトウェア開発のギークフィード
8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4