In the first part of this post, we explored the foundations of fuzzy sets and fuzzy graphs, and discussed how you can use FuzzPy, a general fuzzy mathematics library for python, to work with these types. Today, we will expand a bit on those foundations by learning about fuzzy numbers, and creating visualizations with FuzzPy.
Think of a fuzzy number as a number whose actual value is uncertain. We do not have its value, but we have a set of estimations, each with an associated degree of likelihood, or
grade. If you remember the definition of a fuzzy set, you will remember that the structure of a fuzzy set is very similar to what I just described, so it only makes sense to use a fuzzy set to represent what is known about a fuzzy number.
Effectively, a fuzzy number is a fuzzy subset of the real line , where the value of each member of the set is an estimated value of the fuzzy number, and the -value of the member is its grade.
One can represent the estimated values as well as their associated -values in the form of a Cartesian coordinate system, with the Y-axis representing -values, and the X-axis representing estimated values.
We can then see that certain patterns emerge in the shape of the visualization, and these patterns are used to distinguish between the different types of fuzzy numbers:
- Polygonal sets are represented by an arbitrary set of segments on the plane.
- Trapezoidal sets contain two kernels (estimations whose -value is exactly 1.0), and two X-intercepts.
- Triangular sets contain exactly one kernel, and two X-intercepts
- Gaussian sets have -values determined by a normal distribution, thus providing a smoother distribution.
There are a few additional types as well, but these are the four basic types, and are all supported out of the box by FuzzPy.
Because the points of interest in each type are different, instanciating a new
FuzzyNumber in FuzzPy is done differently depending on the type. Let’s instantiate objects for each of these types using FuzzPy, and we’ll play a bit with these objects in a moment. Make sure you have FuzzPy installed first (
easy_install -U fuzzpy) and save the following code in
import fuzz # Instantiating a PolynomialFuzzyNumber is done by providing # a list of (value, mu) tuple to the constructor: polygonal = [fuzz.PolygonalFuzzyNumber([(0.0, 0.0), \ (0.25, 1.0), (1.0, 0.5), (1.3, 1.0), (1.8, 0.0)])] polygonal += [fuzz.PolygonalFuzzyNumber([(0.0, 0.0), \ (1.0, 0.5), (3.0, 1.0), (4.0, 1.0), (6.0, 0.0)])] # A trapezoidal needs to be given a tuple containing the values # of the kernels (mu = 1.0) and a tuple containing the values # of the support (mu = 0.0) trapezoidal = [fuzz.TrapezoidalFuzzyNumber((1.0, 2.0), \ (0.3, 3.0))] trapezoidal += [fuzz.TrapezoidalFuzzyNumber((1.0, 6.0), \ (0.5, 10.0))] # A triangular set needs to be provided the value of the # kernel, and a tuple containing the values of the support. triangular = [fuzz.TriangularFuzzyNumber(1.0, (0.0, 3.0))] triangular += [fuzz.TriangularFuzzyNumber(4.0, (0.0, 4.5))] # Gaussian fuzzy sets simply need the mean, and standard # derivation for the estimated value. gaussian = [fuzz.GaussianFuzzyNumber(1.0, 0.2)] gaussian += [fuzz.GaussianFuzzyNumber(12.0, 1.0)]
We can now fire up the python interpreter and work with our objects:
>>> # Polygonal Union: ... print polygonal | polygonal PolygonalFuzzyNumber: kernel [(0.25, 0.25), (1.3, 1.3), \ (3.0, 4.0)], support [(0.0, 6.0)] >>> # Polygonal Intersection: ... print polygonal & polygonal PolygonalFuzzyNumber: kernel , support [(0.0, 6.0)] >>> # Trapezoidal Addition: ... print trapezoidal + trapezoidal TrapezoidalFuzzyNumber: kernel (2.0, 8.0), support (0.8000000\ 0000000004, 13.0) >>> # Gaussian Addition ... print gaussian + gaussian GaussianFuzzyNumber: kernel (13.0, 13.0), support (4.85663149\ 07018668, 21.143368509298135)
The class inheritance chain for FuzzPy’s FuzzyNumber derived classes looks like this:
FuzzPy ships with a small visualization framework that is able to create visualizations for almost all FuzzPy types, and encode them in a variety of formats. In most cases, creating and storing a visualization is a trivial operation:
from fuzzynums import * from fuzz.visualization import VisManager gaussian = fuzz.GaussianFuzzyNumber(1.0, 0.2) plugin = VisManager.create_backend(gaussian) (vis_format, vis_data) = plugin.visualize() with (open("visualization.%s" % vis_format, "wb")) as fp: fp.write(vis_data)
In this example, we passed our
FuzzyNumber instance to the
VisManager.create_backend() method, which is a plugin factory method, and it returned the first plugin it could find that can be used to create a visualization of our
visualize() method was called, and returned a tuple containing the file format of the visualization, and its payload. We then created a file using the returned format as extension, and stored the payload in that file.
You can also force the VisManager object to use a certain plugin if you do not want to rely on the default plugin picked for the type of object to visualize:
plugin = VisManager.create_backend(gaussian, 'num_gnuplot')
Similarly, a plugin’s
visualize() method can accept arguments to customize the final output. For example, the following code would tell the plugin to use the ‘gif’ image format:
(vis_format, vis_data) = plugin.visualize(format="gif")
Now that you know how to use all the FuzzPy types and how to create visualizations for your data, you can start using FuzzPy in your own project, or get involved in the development process. Check out the project’s GitHub page for more information.