Есть ли лучший способ рассчитать совместную вероятность?

После долгой борьбы я завершил проект Наследственность «Введение в искусственный интеллект CS50». Однако мне кажется, что мое решение было не самым достойным.

Итак, для этой конкретной функции, над которой я работал, цель состоит в том, чтобы вычислить совместную вероятность того, что произойдет множество событий, например, у одного человека есть 2 гена, но нет признака, а у другого человека есть 1 ген и проявляется признак.

Моя завершенная функция ниже расскажет вам, как она работает. Обычно, если у человека нет в списке родителей, я просто использую PROBS словарь, чтобы получить вероятность, а если у человека есть родители, я использую информацию родителей, чтобы найти информацию о ребенке.

Пример people было бы это:

{
  'Harry': {'name': 'Harry', 'mother': 'Lily', 'father': 'James', 'trait': None},
  'James': {'name': 'James', 'mother': None, 'father': None, 'trait': True},
  'Lily': {'name': 'Lily', 'mother': None, 'father': None, 'trait': False}
}

И PROBS выглядит так:

PROBS = {

    # Unconditional probabilities for having gene
    "gene": {
        2: 0.01,
        1: 0.03,
        0: 0.96
    },

    "trait": {

        # Probability of trait given two copies of gene
        2: {
            True: 0.65,
            False: 0.35
        },

        # Probability of trait given one copy of gene
        1: {
            True: 0.56,
            False: 0.44
        },

        # Probability of trait given no gene
        0: {
            True: 0.01,
            False: 0.99
        }
    },

    # Mutation probability
    "mutation": 0.01
}

И one_gene, two_genes, и have_trait представляют собой просто наборы, содержащие строки имен людей.

Мой вопрос: в моем решении используется CHILD_PROB словарь, который я вычислил. Есть ли у меня способ динамически вычислить вероятность гена ребенка без этого словаря, просто выполняя вычисления с вероятностью мутации и информацией о родительском гене? Если да, будет ли оно более или менее элегантным, чем мое текущее решение?

См. Эту ссылку для получения дополнительной информации о проекте: https://cs50.harvard.edu/ai/2020/projects/2/heredity/

def joint_probability(people, one_gene, two_genes, have_trait):
    """
    Compute and return a joint probability.

    The probability returned should be the probability that
        * everyone in set `one_gene` has one copy of the gene, and
        * everyone in set `two_genes` has two copies of the gene, and
        * everyone not in `one_gene` or `two_gene` does not have the gene, and
        * everyone in set `have_trait` has the trait, and
        * everyone not in set` have_trait` does not have the trait.
    """
    return_prob = 1
    mut = PROBS["mutation"]
    # Probability for child given parent tuple
    CHILD_PROB = {
        (2, 2): (mut**2, 2*mut*(1-mut), (1-mut)**2),
        (2, 1): (0.5*mut, 0.5, (1-mut)*0.5),
        (2, 0): (mut*(1-mut), (1-mut)**2 + mut**2, (1-mut)*mut),
        (1, 1): (0.25, 0.5, 0.25),
        (1, 0): (0.5*(1-mut), 0.5, 0.5*mut),
        (0, 0): ((1-mut)**2,    2*mut*(1-mut),   mut**2)
    }

    for person in people.keys():
        # Figure out how many genes person should have
        if person in one_gene:
            genum = 1
        elif person in two_genes:
            genum = 2
        else:
            genum = 0

        if people[person]["father"] == None:
            # Use PROBS if person's parents aren't listed
            return_prob *= PROBS["gene"][genum]
        else:
            parent_genes = {"mother": 0, "father": 0}
            # Get parents' genes
            for parent_str in parent_genes.keys():
                parent = people[person][parent_str]
                if parent is not None:
                    parent_genes[parent_str] = 1 if parent in one_gene else 2 if parent in two_genes else 0
            # Try both tuple orders
            try:    
                return_prob *= CHILD_PROB[(parent_genes["mother"], parent_genes["father"])][genum]
            except KeyError:
                return_prob *= CHILD_PROB[(parent_genes["father"], parent_genes["mother"])][genum]

        # Get person's trait probability
        if person in have_trait:
            return_prob *= PROBS["trait"][genum][True]
        else:
            return_prob *= PROBS["trait"][genum][False]
                                
    return return_prob
```

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *