LoginSignup
2

More than 1 year has passed since last update.

posted at

updated at

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

この記事は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で話題の論理をわかりやすく解説 | ソフトウェア開発のギークフィード

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
What you can do with signing up
2