Fuzzy Logic Example
Fuzzy logic example
Here we implement an example from Youtube where bankers can use fuzzy logic to evaluate the level of risk of someone according to his/her credit score.
Run the code
You can play with this using the same number used in the youtube video.
$ dotnet fsi fuzzy_logic_example.fsx
Enter credit score: 660
(bad, Trapezoidal (0.0, 0.0, 550.0, 650.0)) => 0
(neutral, Triangular (550.0, 650.0, 750.0)) => 0.9
(good, Trapezoidal (650.0, 750.0, 1000.0, 1000.0)) => 0.1
defuzzified value: 0.4607142857142857
Code
open System
module FuzzyLogic =
type FunctionShape =
of float * float * float
| Triangular of float * float * float * float
| Trapezoidal
let (|LessThanOrEqualTo|_|) k value = if value <= k then Some() else None
let (|GreaterThanOrEqualTo|_|) k value = if value >= k then Some() else None
let (|Between|_|) b e value = if value >= b && value <= e then Some() else None
let triangular a b c x =
match x with
0.0
| LessThanOrEqualTo a -> (x - a) / (b - a)
| Between a b -> (c - x) / (c - b)
| Between b c -> 0.0
| GreaterThanOrEqualTo c ->
let trapezoidal a b c d x =
match x with
0.0
| LessThanOrEqualTo a -> (x - a) / (b - a)
| Between a b -> 1.0
| Between b c -> (d - x) / (d - c)
| Between c d -> 0.0
| GreaterThanOrEqualTo d ->
let eval (f: FunctionShape) =
match f with
(a, b, c) -> triangular a b c
| Triangular (a, b, c, d) -> trapezoidal a b c d
| Trapezoidal
let area (f: FunctionShape) h =
match f with
(a, b, c, d) -> (b - a) * h / 2.0 + (c - b) * h + (d - c) * h / 2.0
| Trapezoidal (a, b, c) -> (c - a) * h / 2.0
| Triangular
type Centroid = float * float
let centroid (f: FunctionShape) h: Centroid =
match f with
(a, b, c, d) -> a + (0.25 - a) / 2.0, h / 2.0
| Trapezoidal (a, b, c) -> a + (c - a) * h / 2.0, h / 3.0
| Triangular
type CategoryName = string
type Category = CategoryName * FunctionShape
type FuzzyValue = float list
let fuzzyfy (categories: Category list) score : FuzzyValue =
categories .map (fun (_, f) -> eval f score)
|> Seq.toList
|> Seq
let defuzzyfy (categories: Category list) (fuzzy_value: FuzzyValue) : float =
let data =
fuzzy_value.zip categories
|> List.map (fun ((_, f), v) -> area f v, centroid f v)
|> List
let s1 = data |> List.sumBy (fun (a, (x, _)) -> x * a)
let sum_areas = data |> List.sumBy (fun (a, _) -> a)
s1 / sum_areas
let credit_according_to_banckers : FuzzyLogic.Category list =
[ "bad", FuzzyLogic.Trapezoidal (0, 0, 550, 650)
"neutral", FuzzyLogic.Triangular (550, 650, 750)
"good", FuzzyLogic.Trapezoidal(650, 750, 1000, 1000)]
let risk_according_to_bankers : FuzzyLogic.Category list =
[ "low risk", FuzzyLogic.Trapezoidal (0, 0, 0.25, 0.5)
"mid risk", FuzzyLogic.Triangular (0.25, 0.50, 0.75)
"high risk", FuzzyLogic.Trapezoidal (0.50, 0.75, 1, 1)
]
.Write ("Enter credit score: ")
Consolelet crips_credit_score = Console.ReadLine() |> float
let fuzzy_value_for_credit = FuzzyLogic.fuzzyfy credit_according_to_banckers crips_credit_score
fuzzy_value_for_credit .zip credit_according_to_banckers
|> List.iter (fun (n, v) -> Console.WriteLine ($"{n} => {v}") )
|> List
fuzzy_value_for_credit.defuzzyfy risk_according_to_bankers
|> FuzzyLogicfun v -> Console.WriteLine($"defuzzified value: {v}") |>