paint-brush
복권 번호를 알아보세요~에 의해@alexthoughts
20,674 판독값
20,674 판독값

복권 번호를 알아보세요

~에 의해 Alex6m2023/10/01
Read on Terminal Reader
Read this story w/o Javascript

너무 오래; 읽다

복권은 예측 불가능성에 관한 것이지만 커튼 뒤를 들여다보고 이러한 게임의 특징을 탐색하는 것도 재미있습니다. 당신이 플레이어이든 아니면 단지 호기심 많은 관찰자이든, 숫자의 세계에는 항상 한두 가지 놀라움이 숨어 있습니다.
featured image - 복권 번호를 알아보세요
Alex HackerNoon profile picture


우리 나라에는 참가자들이 37개 풀에서 6개 숫자를 선택하고 7개 풀에서 다른 숫자를 선택하는 주간 로또 게임이 있습니다. 게임의 첫 번째 부분에 집중하고 풀에서 추가 숫자 하나를 선택하는 것은 무시하겠습니다. 7.


k/N 형식의 복권에 대해(여기서 k는 N개 숫자(이 경우 37개) 총 풀 중에서 원하는 선택 항목의 수(이 경우 6개)임) 일반적인 질문은 각 복권이 다음 중 어느 것인지 여부입니다. 이 숫자는 승리 조합의 일부가 될 확률이 동일합니다.


이 질문을 조사해 봅시다.


나는 그들의 웹사이트에서 2009년부터 2023년까지 1609개의 그림에 대한 통계를 수집했습니다.


그런 다음 CSV 파일의 데이터를 객체로 변환했습니다.

 { '09/09/2023': [13, 17, 24, 30, 35, 37], '07/09/2023': [7, 17, 19, 25, 35, 37], '05/09/2023': [2, 3, 5, 9, 36, 37], '02/09/2023': [4, 12, 22, 27, 30, 34], '29/08/2023': [6, 8, 15, 19, 26, 31], '26/08/2023': [6, 7, 14, 21, 25, 34], '22/08/2023': [2, 6, 10, 23, 24, 29], ... }


개체의 키는 추첨 날짜에 해당하며 관련 값은 해당 특정 추첨에서 우승 조합으로 나타난 숫자 배열입니다.


그런 다음 그림에서 얻은 모든 숫자를 포함하는 배열을 만들었습니다.

 numbers = np.array(list(lotto.values())).flatten() [13, 17, 24, 30, 35, 37, 7, 17, 19, 25, 35, 37, 2, 3, 5, 9, 36, ...]


그런 다음 배열 내의 각 값에 대한 발생 횟수(빈도)를 계산했습니다.

 count = np.bincount(numbers)[1:] [268, 256, 257, 242, 255, 273, 247, 277, 260, 267, 289, 294, 271, 239, 254, 255, 263, 243, 246, 271, 265, 254, 252, 243, 291, 271, 258, 264, 275, 258, 251, 244, 263, 256, 267, 251, 264]


이 결과는 숫자 1이 268번 그려졌고, 숫자 2가 256번 그려졌음을 나타냅니다.


복권 결과의 숫자 분포는 비교적 균일한 것으로 보입니다. 이를 추가로 확인하기 위해 분포의 균일성을 검증하는 테스트를 수행할 수 있습니다.


N개의 개별 숫자의 등가성을 테스트하려면 다음 접근 방식을 따를 수 있습니다.


  • n번의 복권 추첨에서 각 숫자 i = 1, ..., N이 발생하는 관찰 빈도(Oi)를 계산합니다.


  • Ei = (nk) / N 공식을 사용하여 각 숫자에 대한 예상 개수(Ei)를 계산합니다. 여기서 n은 총 복권 추첨 횟수이고, k는 각 추첨에서 선택한 숫자의 수(이 경우 6)입니다. N은 가능한 숫자의 총 개수입니다(이 경우 37).


  • Pearson 통계 또는 카이제곱 통계를 사용하여 관측 카운트(Oi)와 기대 카운트(Ei)를 비교합니다. Pearson 통계의 공식은 다음과 같이 표현되는 경우가 많습니다.

  • 관측된 개수와 기대 개수를 사용하여 카이제곱 통계량을 계산합니다.


  • 계산된 카이 제곱 값이 통계적으로 유의한지 확인하려면 카이 제곱 검정과 같은 통계 검정을 수행하십시오. 이는 숫자의 분포가 등확률 하에서 예상되는 것과 크게 다른지 여부를 평가하는 데 도움이 됩니다.


계산된 카이 제곱 값이 통계적으로 유의하지 않은 경우 숫자가 합리적으로 균등하게 분포되어 있음을 의미하며 등가 가설을 뒷받침합니다. 그러나 X^2 값이 중요하면 등가성에서 벗어났음을 나타냅니다.


숫자의 등확률에 대한 카이제곱 테스트를 수행하는 함수를 만들어 보겠습니다.

 def chi2(data, size, expect, p_value = 0.05): pl = size * 1/expect df = expect - 1 x2_crit_1 = stats.chi2.ppf(p_value, df) x2_crit_2 = stats.chi2.ppf(1 - p_value, df) x2 = 0 for i in range(expect): x2 += ((data[i] - pl) ** 2)/pl accepted = x2_crit_1 < x2 < x2_crit_2 if x2_crit_1 < x2_crit_2 else x2_crit_2 < x2 < x2_crit_1 return x2, accepted


이 함수는 카이제곱 통계와 확률 1 - 2 * p-value 로 허용되는 등확률, 즉 이산 균등분포의 극단값이 낮은 확률을 갖는 결과로 구성된 튜플을 반환합니다.


 N = 37 chi2(count, len(numbers), N) (25.183136523720748, True)


확실히 SciPy 라이브러리의 내장 기능을 사용하여 등확률에 대한 카이제곱 테스트를 수행할 수 있습니다.

 from scipy import stats chi2_statistic, p_value = stats.chisquare(count) (25.18313652372074, 0.9115057832606053)


쌍으로 시작하여 이러한 숫자의 조합을 살펴보겠습니다.

 from itertools import combinations pairs = list(combinations(range(1, N), 2))


이 단계에 따라 이러한 쌍의 발생을 추적하는 2D 행렬을 구성합니다.

 pairs_count = np.zeros([N] * 2, dtype=int) for pair in pairs: for draw in lotto.values(): if pair[0] in draw and pair[1] in draw: pairs_count[pair[0]][pair[1]] += 1 pairs_count = pairs_count[1:, 1:] 



이는 쌍 (a, b)와 (b, a)가 동일하다는 사실을 설명하고 쌍 (a, b)의 발생만을 집계하므로 삼각 행렬을 형성합니다.


내 기능은 다음을 산출합니다.

 counts = pairs_count.flatten() counts = counts[counts > 0] chi2(counts, sum(counts), len(counts)) (589.2721893491138, True)


SciPy는 다음을 제공합니다.

 chi2_statistic, p_value = stats.chisquare(counts) (589.2721893491124, 0.8698507423203673)


세 쌍둥이를 고려해 보는 것은 어떻습니까?

 comb3 = list(combinations(range(1, N), 3)) comb3_count = np.zeros([N] * 3, dtype=int) for comb in comb3: for draw in lotto.values(): contains = comb[0] in draw and comb[1] in draw and comb[2] in draw if contains: comb3_count[comb[0]][comb[1]][comb[2]] += 1 comb3_count = comb3_count[1:, 1:, 1:] counts = comb3_count.flatten() counts = counts[counts > 0] chi2(counts, sum(counts), len(counts)) (6457.575829383709, False)


행렬의 높은 희소성으로 인해 문제가 발생했습니다. 카이 제곱 값은 하한 임계 카이 제곱 임계값 아래로 떨어집니다.

 6457.575829383709 < 6840.049842653838


그러나 SciPy를 사용하면 결과는 다음과 같습니다.

 chi2_statistic, p_value = stats.chisquare(counts) (6457.575829383886, 0.9999997038479482)


이제 가장 자주 추첨된 숫자를 식별해 보겠습니다.

 count.argmax() or list(count).index(max(count)) 11


아직 성급하게 결론을 내리지는 말자. 우리는 이 숫자가 수년에 걸쳐 어떻게 변화했는지 조사할 수 있습니다.

 year_result = dict() for year in range(2009, 2024): new_dict = {k:v for (k,v) in lotto.items() if str(year) in k} year_result[year] = np.bincount(np.array(list(new_dict.values())).flatten())[1:].argmax() { 2009: 16, 2010: 10, 2011: 11, 2012: 24, 2013: 32, 2014: 34, 2015: 21, 2016: 25, 2017: 5, 2018: 10, 2019: 24, 2020: 11, 2021: 12, 2022: 14, 2023: 11 }


또는 시간에 따른 누적 변화를 분석할 수도 있습니다.

 year_result = dict() arr = [] for year in range(2009, 2024): new_dict = {k:v for (k,v) in lotto.items() if str(year) in k} arr += list(np.array(list(new_dict.values())).flatten()) year_result['2009 - ' + str(year) if year > 2009 else str(year)] = np.bincount(arr)[1:].argmax() { '2009': 16, '2009 - 2010': 10, '2009 - 2011': 11, '2009 - 2012': 20, '2009 - 2013': 20, '2009 - 2014': 20, '2009 - 2015': 34, '2009 - 2016': 20, '2009 - 2017': 10, '2009 - 2018': 10, '2009 - 2019': 10, '2009 - 2020': 10, '2009 - 2021': 10, '2009 - 2022': 24, '2009 - 2023': 11 }


마지막으로 동일한 도면이 발생했는지 여부도 조사할 수 있습니다.

 lotto_counts = {} for k, v in lotto.items(): v_str = str(v) if v_str in lotto_counts: lotto_counts[v_str] += [k] else: lotto_counts[v_str] = [k] result = {k: v for k, v in lotto_counts.items() if len(lotto_counts[k]) > 1} { '[13, 14, 26, 32, 33, 36]': ['16/10/2010', '21/09/2010'] }


이러한 일이 거의 연속적으로 발생했다는 점은 재미있습니다.


복권 데이터의 세계로의 여정을 마무리하면서 숫자와 확률을 헤쳐나가는 험난한 여정을 마무리했습니다. 우리는 쌍과 세 쌍에서 가장 인기 있는 숫자를 찾는 것까지 몇 가지 흥미로운 정보를 발견했습니다.


복권은 예측 불가능성에 관한 것이지만 커튼 뒤를 들여다보고 이러한 게임의 특징을 탐색하는 것도 재미있습니다. 당신이 플레이어이든 아니면 단지 호기심 많은 관찰자이든, 숫자의 세계에는 항상 한두 가지 놀라움이 숨어 있습니다.