AllenDowney / ThinkBayes2

Text and code for the forthcoming second edition of Think Bayes, by Allen Downey.
http://allendowney.github.io/ThinkBayes2/
MIT License
1.8k stars 1.49k forks source link

Two small ideas from the first chapter #34

Open ricardoV94 opened 4 years ago

ricardoV94 commented 4 years ago

First of all, Great work!

I was reading the first chapter where you introduce the basic concepts of probability and I really liked what you did with the Pandas example and the conditional function.

I think this might be too much of an overhead for new readers, but I thought that it would be nice to overload the __or__ operator ( | ) to compute the conditional of two variables. This, however, requires a new class as the Pandas Series already uses the __or__ operator. Here is a minimal example:

class Prob:
    def __init__(self, series):
        self.series = series

    def __or__(self, other):
        if isinstance(other, Prob):
            return Prob(self.series[other.series])
        else:
            raise TypeError("unsupported operand type(s) for | : '{}' and '{}'".format(self.__class__, type(other)))

    def __and__(self, other):
        if isinstance(other, Prob):
            return Prob(self.series & other.series)
        else:
            raise TypeError("unsupported operand type(s) for & : '{}' and '{}'".format(self.__class__, type(other)))

    def mean(self):
        # So that it works with the prob function
        return self.series.mean()

This is how it looks in practice:

liberal = Prob(gss['polviews'] <= 3)
old = Prob(gss['age'] >= 65)

prob(liberal | old)
prob(liberal & old)

And you can now write the Bayes Formula almost without change:

prob_liberal_given_old = prob(old | liberal) * prob(liberal) / prob(old)

Anyway, I understand that this might be too much complexity for something that is probably not even relevant in the next chapters. My second suggestion was just to change the conditional function to have the second operator named given:

def conditional(A, given):
    """Conditional probability of A given "B".

    A: Boolean series
    given: Boolean series

    returns: probability
    """
    return prob(A[given])

This might make it easier to read the examples in the text, and understand exactly what is being conditioned on what:

conditional(liberal, given=female)
AllenDowney commented 4 years ago

Thanks for these suggestions. I agree with your conclusion that overriding the | operator might be going too far, but I like the idea of renaming the second argument of conditional.

Thank you!

On Wed, Sep 2, 2020, at 5:53 AM, ricardoV94 wrote:

First of all, Great work!

I was reading the first chapter where you introduce the basic concepts of probability and I really liked what you did with the Pandas example and the conditional function.

I think this might be too much of an overhead for new readers, but I thought that it would be nice to overload the __or__ operator ( | ) to compute the conditional of two variables. This, however, requires a new class as the Pandas Series already uses the __or__ operator. Here is a minimal example:

`class Prob: def init(self, series): self.series = series

def __or__(self, other):
    if isinstance(other, Prob):
        return Prob(self.series[other.series])
    else:
        raise TypeError("unsupported operand type(s) for | : '{}' and '{}'".format(self.__class__, type(other)))

def __and__(self, other):
    if isinstance(other, Prob):
        return Prob(self.series & other.series)
    else:
        raise TypeError("unsupported operand type(s) for & : '{}' and '{}'".format(self.__class__, type(other)))

def mean(self):
    # So that it works with the prob function
    return self.series.mean()

`

This is how it looks in practice:

`liberal = Prob(gss['polviews'] <= 3) old = Prob(gss['age'] >= 65)

prob(liberal | old) prob(liberal & old) `

Anyway, I understand that this might be too much complexity for something that is probably not even relevant in the next chapters. My second suggestion was just to change the conditional function to have the second operator named given:

`def conditional(A, given): """Conditional probability of A given "B".

A: Boolean series
given: Boolean series

returns: probability
"""
return prob(A[given])

`

This might make it easier to read the examples in the text, and understand exactly what is being conditioned on what:

conditional(liberal, given=female)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/AllenDowney/ThinkBayes2/issues/34, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOLP3MIX3ZCFMFMVER33BTSDYI3BANCNFSM4QSZ4CIQ.