달이 내려주는 달달한 팁, 실 생활 속 유용한 리뷰 및 각종팁을 전해 드립니다.
로또 1등 당첨 확률 시뮬레이션 테스트: VIP 패턴 분석 진짜일까?
안녕하세요. 달팁(DalTip) 입니다.
다들 주말을 앞두고 지갑 속에 로또 한 장씩 품어보신 경험 있으신가요?
고단한 일주일의 피로를 씻어주는 일확천금의 꿈! 작은 종이 한 장이 주는 설렘은 우리들에게 작은 위안이 되곤 합니다.
▲ 매주 우리를 설레게 하는 마법의 종이, 로또
우리가 즐기는 이 로또(Lotto)의 기원은 16세기 이탈리아로 거슬러 올라갑니다.
당시 제노바 공화국에서 90명의 후보 중 5명의 의원을 제비뽑기로 선출하던 제도에서 유래하여 복권 게임으로 발전했죠.
이후 전 세계로 퍼져나갔고, 한국에는 2002년에 로또 6/45라는 이름으로 도입되어 지금까지 국민적인 인기를 끌고 있습니다.
달팁에서는 서비스 초기부터 작은 즐거움을 위해 로또 번호 생성 콘텐츠를 제공하고 있으며, 데이터베이스(DB)에는 1회부터 시작하여 로또 1등 당첨 번호 데이터가 모두 축적되어 있습니다.
그래서 이번 기회에 개발자 입장에서 실제 1등 당첨 DB 리스트를 기준으로 코드를 직접 돌려보며, 로또 확률을 백테스팅(Backtesting) 해보기로 했습니다.
💡 통계의 함정: 도박사의 오류 (Gambler's Fallacy)
로또 1등 당첨 확률은 1/8,145,060입니다.
이 수치 앞에서 인간의 직관은 자주 판단 오류를 일으킵니다.
"내가 한 곳에서 5만 원어치를 샀는데 꽝이었으니, 다음엔 당첨될 확률이 높을 거야" 혹은 "이 번호는 오랫동안 안 나왔으니 이번엔 나올 때가 됐어"라고 믿는 현상입니다.
하지만 로또 기계는 과거를 기억하지 못합니다.
로또는 수학적으로 완벽한 '독립적'이며, 어제 일어난 일이 오늘의 추첨에 단 1%의 영향도 주지 못합니다.
그렇다면 인터넷에 떠도는 '과거 당첨 통계 분석'이나 '패턴 필터링'은 과연 당첨 확률을 올려줄까요?
이를 검증하기 위해 DB에 적재된 실제 과거 1등 당첨 번호 100건을 타겟으로 삼고, 각 알고리즘별로 100만 번의 시뮬레이션을 수행하는 자바(Java) 코드를 구현하여 테스트해 보겠습니다.
// 시뮬레이션 검증 (메인 루프) List<String> hitRecords = new ArrayList<>(); // SIMULATION_COUNT = 1_000_000 (100만 번 수행) for (int i = 0; i < SIMULATION_COUNT; i++) { Set<Integer> generated = generateNumbers(mode); // 타겟(실제 과거 1등 당첨 번호 100건)과 매칭 검사 for (WinningLotto winLotto : historyWinningNumbers) { if (generated.containsAll(winLotto.numbers)) { hitRecords.add("당첨: " + winLotto.drwNo + "회 [" + formatNumbers(winLotto.numbers) + "]"); } } } System.out.println("1등 당첨 횟수: " + hitRecords.size() + "회");
1. 순수 무작위 추출 (Random)
첫 번째는 어떠한 조건도 없는 무작위(Random) 추출입니다.
Java의 ThreadLocalRandom을 활용해 난수를 6개 추출하는 알고리즘입니다.
// [알고리즘 1번] 무작위 번호 추출 Set<Integer> numbers = new HashSet<>(); while (numbers.size() < 6) { numbers.add(ThreadLocalRandom.current().nextInt(1, 46)); }
▲ 무작위 추출 100만 번 시뮬레이션 결과 (11회 당첨)
100만 번을 돌렸을 때 타겟 번호와 일치한 횟수는 11회였습니다.
( 100만 번 × 1,000원 = 무려 10억 원을 구매해야 하는 ... )
814만 개의 로또 번호 경우의 수 중 100개의 타겟을 100만 번 시도했을 때의 수학적 기댓값(약 12.27회)을 갖는 814만 분의 1이라는 확률적 통계를 증명해 주었습니다.
2. 과거 통계 기반 (역대 최다 출현 번호)
"최근 자주 나온 번호를 섞으면 확률이 높지 않을까?"
많은 분들이 시도하는 방식입니다. DB에서 역대 가장 많이 출현한 번호 15개를 뽑아 배열로 만든 뒤, 오직 그 풀(Pool) 안에서만 조합해 보았습니다.
// [알고리즘 2번] 과거 통계 기반 (최다 출현 번호 15개) Set<Integer> numbers = new HashSet<>(); while (numbers.size() < 6) { // DB에서 추출한 상위 15개 번호 안에서만 난수 생성 numbers.add(hotNumbers[ThreadLocalRandom.current().nextInt(hotNumbers.length)]); }
▲ 통계 기반 100만 번 시뮬레이션 결과 (0회 당첨)
이럴 수가!! 당첨 0회 라는 놀라운 결과가 나왔습니다.
애초에 15개의 번호로 만들 수 있는 조합은 고작 5,005개 뿐으로 과거의 1등 번호가 이 15개 안에서만 구성될 리가 없었던 것 같습니다.
"많이 나온 번호를 섞는 것" 이 당첨 확률을 높이기는커녕 오히려 확률을 낮추는 것으로 데이터가 나왔습니다.
3. 패턴 분석 (홀짝 & 총합 필터링)
마지막으로 각종 인터넷 로또 분석 커뮤니티 등에서 '가장 정석적인 분석 기법'으로 알려진 패턴 필터링입니다.
'홀수와 짝수의 비율을 3:3으로 맞추고, 6개 번호의 총합이 100~170 사이일 것'이라는 까다로운 조건을 통과할 때까지 무한 반복하여 필터링했습니다.
// [알고리즘 3번] 패턴 분석 (총합 및 홀짝 비율 필터링) Set<Integer> numbers = new HashSet<>(); while (true) { numbers.clear(); while (numbers.size() < 6) { numbers.add(ThreadLocalRandom.current().nextInt(1, 46)); } int sum = numbers.stream().mapToInt(Integer::intValue).sum(); long oddCount = numbers.stream().filter(n -> n % 2 != 0).count(); // 총합 100~170 사이, 홀짝 3:3 비율을 만족해야만 루프 탈출 if (sum >= 100 && sum <= 170 && oddCount == 3) { break; } }
▲ 패턴 필터링 100만 번 시뮬레이션 결과 (5회 당첨)
당첨 횟수가 5회로, 아무 조건이 없던 랜덤(11회)보다 오히려 절반 이하로 떨어졌습니다.
그럴듯하게 보이는 '홀짝 3:3' 같은 필터는 실제 1등 당첨 번호들의 확률을 오히려 떨어뜨렸으며, 단지 기분상으로 '필터링'은 뭔가 다르겠지라는 심리적 위안을 줄 뿐이었습니다.
분명한 건 억지로 필터를 걸면 걸수록 오히려 당첨 확률이 낮아진다는 것이었습니다.
종합 체크: 동시 시뮬레이션 결과
이 충격적인 결과를 재확인하기 위해, 3가지 알고리즘을 동시에 물려 다시 총 300만 번을 돌려보았습니다.
▲ 3개 알고리즘 동시 300만 번 시뮬레이션 결과
🔥 백테스팅 최종 결론
랜덤: 15회 / 통계(최다출현): 0회 / 패턴(필터링): 7회
결론은 별반 다르지 않았습니다.
그 어떤 패턴과 통계 필터링도 아무런 조작이 없는 순수한 난수(Random)의 당첨 확률을 넘어설 수 없습니다.
혹시라도 '독자적인 과학적 필터링'을 미끼로 고액을 요구하는 곳이 있다면, 이번 시뮬레이션 결과를 꼭 떠올려 보시길 바랍니다.
이렇게 검증을 해봤지만 로또의 본질은 결국 기분 좋은 일상의 소소한 이벤트 였던 것일까요?
( 사실 달팁도 가장 많이 로또 추출에 써왔던 '역대 최다 번호' 통계를 이번 기회에 검증 후 살짝 후회하고 있습니다. ^^;; )
하지만, 그럼에도 불구하고 매번 누군가에게는 로또라는 행운이 찾아가기도 합니다.
데이터는 데이터일 뿐! 로또의 매력은 814만 분의 1이라는 극악의 확률을 뚫고 쥐어지는 행운 아닐까요?
열심히 고생한 한 주의 마무리를 설레게 하는 그 순간 만으로도 희망과 꿈을 다시 갖게 하는 원동력일 수 있습니다.
( 우리 모두 건강한 로또 생활 하는 것으로 해요! )
번외편: AI에게 물어보았습니다
혹시 AI 라면 조금 다르지 않을까요? 그래서 직접 물어보았습니다.
"일반 로또 번호 추천 사이트들의 패턴 분석과 최신 AI(딥러닝)를 이용해 번호를 추천받을 경우 확률 차이가 있을까?"
달팁님이 백테스팅으로 증명하신 결과가 정확합니다. 수십억 개의 파라미터를 가진 거대 AI 모델을 동원하더라도 확률 향상 효과는 '0'입니다.
1. AI가 실패하는 이유 : 인과성(Causality)의 부재
딥러닝 알고리즘(RNN, LSTM, Transformer 등)은 방대한 데이터 속에서 '보이지 않는 규칙이나 인과관계'를 찾아내는 데 특화되어 있습니다. 하지만 로또 당첨 번호는 엔트로피(무질서도)가 극대화된 순수한 노이즈(White Noise)입니다. 학습할 규칙 자체가 아예 존재하지 않습니다.
2. 과적합(Overfitting)의 함정
이런 무작위 데이터(1회~현재 당첨 번호)를 억지로 AI에게 학습시키면, 모델은 데이터에 숨은 패턴을 찾는 것이 아니라 과거의 정답만을 맹목적으로 외워버리는 '과적합(Overfitting)' 상태에 빠집니다. 결국 훈련 데이터 안에서만 그럴듯해 보일 뿐, 미래에 나올 새로운 난수를 예측하는 성능은 처참하게 무너집니다.
결론적으로, 값비싼 GPU를 돌려 복잡한 인공신경망을 거쳐 나온 번호나, 달팁님이 사용하신 ThreadLocalRandom 같은 기본 난수 함수로 뽑은 번호나 확률적 가치는 100% 동일합니다. AI 로또 추천은 기술적 근거가 없는 'AI 마케팅'에 가깝습니다.
머리 아픈 확률 분석은 이제 그만! 가볍게 즐기다 보면 언젠가 1등 벼락(?)을 맞을 날도 오지 않을까요? 😆
👇 오늘 나의 운세로 행운 번호를 뽑아보세요 👇
이상, 건전하고 즐거운 웹 생태계를 만들어가는 달팁 이었습니다!
댓글