[GRASS-user] r.fuzzy.system help with defuzzification

Ken Mankoff mankoff at gmail.com
Wed Sep 2 04:44:55 PDT 2020


Hi GRASS List,

Following up on the previous message regarding fuzzy logic and GRASS - The scikit-fuzzy toolbox https://pythonhosted.org/scikit-fuzzy/ is very easy to use and it looks like it supports a super-set of the functionality provided by the GRASS addon. The GRASS addon does appear to have some issues, but thanks to grass-session and the general ease of getting GRASS data into Numpy arrays, it's easy to work with scikit-fuzzy instead.

Pro's to scikit-fuzzy: maintained, more complete, simpler interface, better documentation.

Cons: Must leave GRASS, Orders of magnitude slower.

  -k.

On 2020-08-31 at 12:12 -07, Ken Mankoff <mankoff at gmail.com> wrote...
> Hello,
>
> https://grass.osgeo.org/grass78/manuals/addons/r.fuzzy.system.html
>
> I'd like to use the =r.fuzzy.system= addons for GRASS, but am having
> trouble understanding the output. I'm concerned there is a bug. Below
> is a minimum example I've created to demonstrate the issue. If anyone
> on this list has experience with these modules or interest in helping
> getting their documentation improved so that they are easier to use, I
> can take the lead but would benefit from some help with this.
>
> I have already improved some of the incorrect docs for these addons
> (see https://github.com/OSGeo/grass-addons/pull/175 ) but am now
> returning to a bug I opened a few months ago here
> https://github.com/OSGeo/grass-addons/issues/176
>
> I'm not 100 % certain there is a bug - I could be using or
> interpreting the results incorrectly. I hope that is the case and this
> is a simple fix. If code changes are required, I will try to implement
> them, but would be grateful for pointers about what/where if someone
> else sees something I have not yet noticed. I am open to including
> collaborators as co-authors on a paper I'm writing if the effort
> needed to get this working and the contribution are significant.
>
> Here (and the GitHub issue above) is the best way I can demonstrate
> the issue:
>
>
> * GRASS Fuzzy Code Test
>
> + Four-cell raster map foo = [1, 2, 3, 4]
>   + Foo is "low" when 1, "hi" when 4, and linear change between +
>   foo_lo = [1, 0.66, 0.33, 0] + foo_hi = [0, 0.33, 0.66, 1]
> + Output is "sad" when foo is "lo", "happy" when foo is "hi", and
> linear between
>   + Expected output:
>     + out values = [1, 0.66, 0.33, 0] + out label: [sad=1 happy=0;
>     sad=0.66 happy=0.33; sad=0.33 happy=0.66; sad=0 happy=1]
>
> ** Summary
>
> Results from #+BEGIN_SRC bash r.fuzzy.system -m maps=fuzzy.maps
> rules=fuzzy.rules output=out res=10 r.stats -1l out #+END_SRC
>
> Are:
>
> #+RESULTS:
> | 0.63636363 | sad=1.00 | happy=1.00 | 0.54545456 | sad=1.00 |
> | happy=1.00 | 0.36363637 | sad=1.00 | happy=1.00 | 0.27272728 |
> | sad=1.00 | happy=1.00 |
>
> I can see that I've encoded sadness, presumably because that was
> listed first in the fuzzy.maps __OUTPUT__ (that file contents is shown
> below), but both sad=1.0 and happy=1.0 seems incorrect to me.
>
>
> ** Set up domain and helper functions
>
> #+BEGIN_SRC bash :results verbatim grass -c ./G_fuzzy
>
> export GRASS_OVERWRITE=1 export GRASS_VERBOSE=0 g.region w=0 s=0 e=4
> n=1 res=1 -pa -s #+END_SRC
>
> ** Define data
>
> #+BEGIN_SRC bash r.mapcalc "foo = float(col())" r.stats -1 foo
> #+END_SRC
>
> #+RESULTS:
> | 1 | 2 | 3 | 4 |
>
>
> ** Set up rules
>
> #+BEGIN_SRC conf :tangle fuzzy.maps % foo $ lo {right; 1,4; linear; 0;
> 1} $ hi {left; 1,4; linear; 0; 1}
>
> % _OUTPUT_ $ sad {left; 0,1; linear; 0;1} $ happy {right; 0,1; linear;
> 0;1} #+END_SRC
>
> #+BEGIN_SRC conf :tangle fuzzy.rules $ happy { foo = hi } $ sad { foo
> = lo } #+END_SRC
>
> ** Run the fuzzy system with pixel-level debug output
>
> #+BEGIN_SRC bash :results verbatim r.fuzzy.system -m maps=fuzzy.maps
> rules=fuzzy.rules output=out res=10 coors=0.5,0.5 echo " "
> r.fuzzy.system -m maps=fuzzy.maps rules=fuzzy.rules output=out res=10x
> coors=3.5,0.5 #+END_SRC
>
> #+RESULTS: #+begin_example ANTECEDENT happy: 0.000 ANTECEDENT sad:
> 1.000 RESULT (defuzzified): 0.636 UNIVERSE,happy,sad,AGREGATE
> 0.000,0.000,0.000,0.000 0.091,0.000,0.091,0.091
> 0.182,0.000,0.182,0.182 0.273,0.000,0.273,0.273
> 0.364,0.000,0.364,0.364 0.455,0.000,0.455,0.455
> 0.545,0.000,0.545,0.545 0.636,0.000,0.636,0.636
> 0.727,0.000,0.727,0.727 0.818,0.000,0.818,0.818
> 0.909,0.000,0.909,0.909
>
> ANTECEDENT happy: 1.000 ANTECEDENT sad: 0.000 RESULT (defuzzified):
> 0.273 UNIVERSE,happy,sad,AGREGATE 0.000,1.000,0.000,1.000
> 0.091,0.909,0.000,0.909 0.182,0.818,0.000,0.818
> 0.273,0.727,0.000,0.727 0.364,0.636,0.000,0.636
> 0.455,0.545,0.000,0.545 0.545,0.455,0.000,0.455
> 0.636,0.364,0.000,0.364 0.727,0.273,0.000,0.273
> 0.818,0.182,0.000,0.182 0.909,0.091,0.000,0.091 #+end_example
>
>
> ** Run the fuzzy system to get raster output
>
> #+BEGIN_SRC bash r.fuzzy.system -m maps=fuzzy.maps rules=fuzzy.rules
> output=out res=10 #+END_SRC
>
> #+RESULTS:
>
> Test the intermediate result from =-m= flag.
>
> #+BEGIN_SRC bash r.stats -1 out_sad #+END_SRC
>
> #+RESULTS:
> |          1 | 0.66666669 | 0.33333334 |
> |          0 |
>
> #+BEGIN_SRC bash r.stats -1 out_happy #+END_SRC
>
> #+RESULTS:
> |          0 | 0.33333334 | 0.66666669 |
> |          1 |
>
> Now inspect the final result
>
> #+BEGIN_SRC bash :results verbatim r.stats -1l out #+END_SRC
>
> #+RESULTS: : 0.63636363 sad=1.00 happy=1.00 : 0.54545456 sad=1.00
> happy=1.00 : 0.36363637 sad=1.00 happy=1.00 : 0.27272728 sad=1.00
> happy=1.00
>
> + The intermediate results, =out_sad= and =out_happy= make sense, but
> the final result does not. + This suggests there is an issue with the
> defuzzification step. Let's try other methods.
>
> #+BEGIN_SRC bash :results verbatim r.fuzzy.system -m maps=fuzzy.maps
> rules=fuzzy.rules output=out res=10 defuz=bisector imp=minimum r.stats
> -1l out #+END_SRC
>
> #+RESULTS: : : 0.63636363 sad=1.00 happy=1.00 : 0.54545456 sad=1.00
> happy=1.00 : 0.36363637 sad=1.00 happy=1.00 : 0.27272728 sad=1.00
> happy=1.00
>
> Expected results:
>
> Output value = [1,0.6, 0.3, 0] # can achieve close to 1 if we increase
> =res= option to =r.fuzzy.system= Output label = [sad=1 happy=0; sad=0
> happy=1]
>   Optionally, output label = [sad=<near 1> happy=<near 0>; sad=<near
>   0> happy=<near 1>]
>
>
> Any suggestions will be greatly appreciated.
>
> Regards,
>
>   -k.



More information about the grass-user mailing list