Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lattice_memebers.Concept vs _common.Concept API #23

Open
mikulatomas opened this issue Dec 16, 2021 · 6 comments
Open

lattice_memebers.Concept vs _common.Concept API #23

mikulatomas opened this issue Dec 16, 2021 · 6 comments

Comments

@mikulatomas
Copy link
Contributor

Hi,

I found quite counter-intuitive (for me) API naming.

In case of _common.Concept we have

@property
def objects(self) -> typing.Tuple[str]:
    """The objects subsumed by the concept."""
    return self.extent.members()

In case of lattice_members.Concept we have

@property
def extent(self) -> typing.Tuple[str, ...]:
    """The objects subsumed by the concept.

    Example:
        >>> import concepts
        >>> lattice = concepts.Context.fromstring(concepts.EXAMPLE).lattice
        >>> lattice['+1',].extent
        ('1sg', '1pl')
    """
    return self._extent.members()

and Concept.objects works differently.

I would prefer to have same API, that is, Vector extent can be hidden in concept._extent property, public list of members names can be concept.extent or concept.objects and original concept.objects can be renamed.

@xflr6
Copy link
Owner

xflr6 commented Dec 16, 2021

Thanks.

For context: so far we did not expose the underlying bitsets and we are starting to to this with _common.Concept.

+1 that it's probably confusing that lattice_members.Concept.extent of lattice members does the same as _common.Concept.objects. Note that lattice_members.Concept.objects is something else viz. the objects introduced by the concept in the lattice (i.e. where the label for the object is attached in the visualization), so I don't think we can just rename that attribute. We might need to choose another name for the exposed bitset. Maybe extent_bitset?

All of this applies analogously for intent/properties.

@xflr6
Copy link
Owner

xflr6 commented Dec 16, 2021

See also:

>>> import concepts
>>> lattice = concepts.Context.fromstring(concepts.EXAMPLE).lattice
>>> concept = lattice['+1',]
>>> concept
<Concept {1sg, 1pl} <-> [+1 -2 -3] <=> +1>
>>> concept.index, concept.dindex
(7, 6)
>>> concept.objects, concept.properties
((), ('+1',))

@mikulatomas
Copy link
Contributor Author

I know that lattice_members.Concept.objects has different meaning, maybe i wasn't too explicit :) agree that renaming that can be problematic. The name extent_bitset seems to be ok.

Maybe in this context we can also think about #21, since I feel it can be useful to iterate over attribute bitset vectors and object bitset vectors which are present in the concept (maybe in the form of dict, since we want to access these vectors by object/attribute name).

Thanks!

@xflr6
Copy link
Owner

xflr6 commented Dec 16, 2021

I know that lattice_members.Concept.objects has different meaning, maybe i wasn't too explicit :)

Hehe, good. I actually had to look it up first.. :)

Re: #21, if we expose the bitsets, could that rather be a method on them (cf. e.g. .prime())?

For me it's a bit hard to wrap my head around this transformation (objects_vectors = the extents of each individual intent of a concept). Not sure if this is a common use case (maybe there is better naming, e.g. avoid exposing the term 'vector', which IIRC was more of an internal thing before; if we use it for type annotations, maybe we should use a better name).

This is about the similarity between the indivudual extent items and the indivudual intent items looking at the context table, right (I guess this might make less sense when using FCA for definitions of feature systems, which tend to be minimalistic, but more for real world data with all kinds of redundancies)?

@mikulatomas
Copy link
Contributor Author

mikulatomas commented Dec 16, 2021

Re: #21, if we expose the bitsets, could that rather be a method on them (cf. e.g. .prime())?

Not sure exactly what do you mean by that. But based on the following, you get the main idea right.

For me it's a bit hard to wrap my head around this transformation (objects_vectors = the extents of each individual intent of a concept). Not sure if this is a common use case (maybe there is better naming, e.g. avoid exposing the term 'vector', which IIRC was more of an internal thing before; if we use it for type annotations, maybe we should use a better name).

This is about the similarity between the indivudual extent items and the indivudual intent items looking at the context table, right (I guess this might make less sense when using FCA for definitions of feature systems, which tend to be minimalistic, but more for real world data with all kinds of redundancies)?

That is correct, for me, it is fine to have this as hidden API. It can be useful (as you mentioned) for calculating similarity of all extent items in given formal concept. I mainly need it for applications in fcapsy (for example cohesion and typicality) since i need to apply Jaccard similarity on two attribute bitsets (definition)

Naming wise, extent_bitset is one bitset which represets set of objects = extent. The mentioned above is iterable (or preferable key-value) of bitsets which represents the sets of attributes for all objects from the extent (dual for intent). I see that naming can be quite tricky here and agree the vector is probably not the right one.

@mikulatomas
Copy link
Contributor Author

mikulatomas commented Dec 16, 2021

In my old FCA library I have this method as part of formal context, called .filter() where you can put names of objects/attributes and it would filter the context bitsets accorting to the given names. Maybe this is the better approach?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants