확률 분포와 Python: 이산과 연속

배경.


다음과 같은 게시물을 포함하여 이 문서에서 다루는 개념의 배경이 될 수 있는 게시물이 몇 개 있습니다.



  • 할당


    이 문장에서 우리는 확률 분포를 소개할 것이다.이것은 광범위한 주제이기 때문에 우리는 일부 개념에 대해 샘플링을 해서 그것을 이해할 것이다.미국의 경험을 참고하여 우리는 우리의 의료 진단 결과를 그릴 것이다.
    모든 결과는 한 사람이 질병P(D)을 앓고 있는지와 질병P(not D)을 앓고 있는지의 조합이라는 것을 기억할 수 있을 것이다.그리고 진단 테스트를 받은 결과 양성P(P) 또는 음성P(not P)으로 나타났다.
    이것들은 이산의 결과이기 때문에 그들은 확률 질량 함수로 표시할 수 있으며 확률 밀도 함수가 아니라 후자는 연속 분포를 나타낼 수 있다.
    10명 중 1명이 질병을 앓고 있다고 가정해 보자. 진단 테스트의 진양성률은 95%, 진음성률은 90%다.양성 판정을 받은 사람이 실제로 병에 걸릴 확률은 46.50%다.
    다음은 코드입니다.
    from random import random, seed
    
    seed(0)
    pop = 1000  # 1000 people
    counts = {}
    for i in range(pop):
        has_disease = i % 10 == 0  # one in 10 people have disease
        # assuming that every person gets tested regardless of any symptoms
        if has_disease:
            tests_positive = True       # True Positive  95%
            if random() < 0.05:
                tests_positive = False  # False Negative 5%
        else:
            tests_positive = False      # True Negative  90%
            if random() < 0.1:
                tests_positive = True   # False Positive 10%
        outcome = (has_disease, tests_positive)
        counts[outcome] = counts.get(outcome, 0) + 1
    
    for (has_disease, tested_positive), n in counts.items():
        print('Has Disease: %6s, Test Positive: %6s, count: %d' %
              (has_disease, tested_positive, n))
    
    n_positive = counts[(True, True)] + counts[(False, True)]
    print('Number of people who tested positive:', n_positive)
    print('Probability that a test-positive person actually has disease: %.2f' %
          (100.0 * counts[(True, True)] / n_positive),)
    
    누군가가 병에 걸릴 확률(10분의 1)을 감안하면 베일스 용어에서도'이전'이라고 불린다.우리는 네 가지 상황을 시뮬레이션했는데, 그 중에서 사람들이 진단 테스트를 받았다.마찬가지로 이곳의 큰 가설은 사람들이 무작위 테스트를 받는다는 것이다.상기 진양성률과 진음성률에 따르면 결과는 다음과 같다.

    확률 질량 함수


    이러한 이산 이벤트를 지정하면 우리는 확률 품질 함수를 그릴 수 있다discrete density function라고도 부른다.우리는 확률 품질 함수를 그리기 위해 pandasDataFrames를 만드는 데 도움을 줄 matplotlib를 가져올 것입니다.
    우선 이벤트 수를 DataFrame로 바꾸고 열을 item_counts로 변경해야 합니다.그리고 우리는 계수를 가설 도시의 총인구(즉 인구:1000)로 나누어 모든 사건의 확률을 계산할 것이다.
    선택 사항: 테스트 결과의 약어로 다른 열을 생성합니다(True True에서 TT로 변경).우리는 이 칼럼을 item2라고 명명할 것이다.
    import pandas as pd
    import matplotlib.pyplot as plt
    
    df = pd.DataFrame.from_dict(counts, orient='index')
    df = df.rename(columns={0: 'item_counts'})
    df['probability'] = df['item_counts']/1000
    df['item2'] = ['TT', 'FF', 'FT', 'TF']
    
    다음은 지금까지 DellDataFrame입니다.

    너는 probability열의 숫자를 더하면 1.0이고 item_counts숫자는 우리가 양성자가 실제로 병에 걸릴 확률을 계산할 때의 상술한 계수와 같다는 것을 알게 될 것이다.
    우리는 간단한 스트라이프 그래프를 사용하여 진단 확률을 그릴 것이다. 이것이 바로 우리가 확률의 질량 함수인 모든 이산 사건의 확률을 어떻게 직관적으로 표시하는가이다.모든'이산 사건'은 조건이 있다(예를 들어 누군가가 질병을 앓고 있다고 가정하면 누군가의 검출이 양성일 확률-TT 또는 누군가가 질병이 없다고 가정하면 누군가의 검출이 음성일 확률-FF 등).

    다음은 코드입니다.
    df = pd.DataFrame.from_dict(counts, orient='index')
    df = df.rename(columns={0: 'item_counts'})
    df['probability'] = df['item_counts']/1000
    df['item2'] = ['TT', 'FF', 'FT', 'TF']
    plt.bar(df['item2'], df['probability'])
    plt.title("Probability Mass Function")
    plt.show()
    

    누적 분포 함수


    확률 품질 함수는 모든 이산 이벤트(즉 TT, FF, FT와 TF)의 확률을 알려줄 수 있지만 누적 분포 함수와 같은 정보를 나타낼 수 있다. 이 함수는 우리가 이벤트를 추가할 때 확률이 어떻게 변화하는지 볼 수 있도록 한다.
    누적 분포 함수는 aDataFrame의 앞 줄의 확률을 누적하는 방식으로 덧붙일 뿐이다. 열probability2처럼

    우리는 cumsum() 함수를 사용하여 cumsum 열을 만들었는데, 이 열은 item_counts 모든 연속 줄과 더하기만 하면 된다.우리가 상응하는 확률열probability2을 만들 때 1.0까지 커진다.
    다음은 차트입니다.

    이 도표는 TT와 FF(진, 진=진양성, 가짜, 가짜=진음성)를 동시에 획득할 확률이 88.6%로 11.4%(100-88.6) 동안 진단 테스트가 우리를 실망시킬 수 있음을 보여준다.

    정적 분포


    통상적으로, 당신은 연속 분포에 흥미를 느낄 것이며, 누적 분포 함수가 어떻게 작동하는지 더욱 잘 볼 수 있다.
    시계 곡선이나 정적 분포에 익숙하실 수도 있습니다. 평균치 mu 와 표준차 sigma 로만 정의됩니다.만약 확률치가 표준 정적 분포라면 평균치는 0이고 표준 편차는 1이다.

    코드:
    import math
    SQRT_TWO_PI = math.sqrt(2 * math.pi)
    
    def normal_pdf(x: float, mu: float = 0, sigma: float = 1) -> float:
        return (math.exp(-(x-mu) ** 2 / 2 / sigma ** 2) / (SQRT_TWO_PI * sigma))
    
    # plot
    xs = [x / 10.0 for x in range(-50, 50)]
    plt.plot(xs, [normal_pdf(x, sigma=1) for x in xs], '-', label='mu=0, sigma=1')
    plt.show()
    
    표준 정적 분포 곡선을 사용하면 평균 확률이 약 0.4인 것을 볼 수 있다.그러나 곡선 아래의 면적을 합치면 의학 진단의 예처럼 1.0을 받게 된다.
    만약 시계를 2로 나누고 왼쪽을 돌리면 누적 분포 함수를 얻을 수 있다.

    코드:
    import math
    
    def normal_cdf(x: float, mu: float = 0, sigma: float = 1) -> float:
        return (1 + math.erf((x - mu) / math.sqrt(2) / sigma)) / 2
    
    # plot
    xs = [x / 10.0 for x in range(-50, 50)]
    plt.plot(xs, [normal_cdf(x, sigma=1) for x in xs], '-', label='mu=0,sigma=1')
    
    이 두 가지 상황에서 표준 정적 분포와 누적 분포 함수의 곡선 면적은 1.0이기 때문에 모든 사건의 확률 총계는 1이다.
    이 글은 내가 Data Science from Scratch by Joel Grus를 통해 끊임없이 진전된 일부분이다.

    데이터 과학, 머신러닝, R, 파이톤, SQL 등에 관한 더 많은 내용.

    좋은 웹페이지 즐겨찾기