Files
lottery-picker/lottery_picker/blueball_optimizer.py
T

444 lines
16 KiB
Python

"""
蓝球算法专项优化
目标:将蓝球命中率从6%提升至15%+
技术:深度学习 + 强化学习 + 组合优化
"""
import numpy as np
import random
from collections import Counter, defaultdict
from typing import List, Dict, Tuple
import math
class BlueBallOptimizer:
"""蓝球算法优化器"""
def __init__(self, lottery_type: str, persistence):
self.lt = lottery_type
self.p = persistence
self.blue_max = 16 if lottery_type == "ssq" else 12
# 历史数据
self.training_history = []
# 模型参数
self.markov_chain = defaultdict(lambda: defaultdict(float))
self.pattern_memory = [] # 记忆最近模式
self.reward_history = [] # 奖励历史
self.learning_rate = 0.1
print(f"[蓝球优化] 初始化 {lottery_type} (范围: 1-{self.blue_max})")
def load_blue_data(self) -> List[List[int]]:
"""加载蓝球历史数据"""
data = self.p.history(self.lt)
if not data:
return []
blue_sequences = []
for record in data[:100]: # 最近100期
blues = record["blue"] if isinstance(record["blue"], list) else [int(record["blue"])]
blue_sequences.append(blues)
return blue_sequences
def analyze_patterns(self, sequences: List[List[int]]) -> Dict:
"""分析蓝球模式"""
if len(sequences) < 20:
return {"status": "insufficient_data"}
# 1. 基础频率分析
all_blues = [num for seq in sequences for num in seq]
freq_counter = Counter(all_blues)
total = len(all_blues)
# 2. 奇偶模式
odd_even_patterns = []
for seq in sequences:
# 统计奇偶组合
odd_count = sum(1 for n in seq if n % 2 == 1)
pattern = f"O{odd_count}_E{len(seq)-odd_count}"
odd_even_patterns.append(pattern)
# 3. 大小分区
size_patterns = []
mid_point = self.blue_max // 2
for seq in sequences:
big_count = sum(1 for n in seq if n > mid_point)
pattern = f"B{big_count}_S{len(seq)-big_count}"
size_patterns.append(pattern)
# 4. 热号冷号分析
hot_numbers = [n for n, count in freq_counter.most_common(5)]
# 冷号(最近20期未出)
recent_numbers = [num for seq in sequences[-20:] for num in seq]
cold_numbers = [n for n in range(1, self.blue_max+1) if n not in recent_numbers]
# 5. 间隔分析
interval_analysis = self._analyze_intervals(sequences)
return {
"status": "analyzed",
"total_samples": len(sequences),
"frequency_dist": dict(freq_counter.most_common()),
"hot_numbers": hot_numbers,
"cold_numbers": cold_numbers[:5],
"odd_even_patterns": Counter(odd_even_patterns),
"size_patterns": Counter(size_patterns),
"interval_stats": interval_analysis,
"most_likely_pattern": Counter(odd_even_patterns).most_common(1)[0][0] if odd_even_patterns else ""
}
def _analyze_intervals(self, sequences: List[List[int]]) -> Dict:
"""分析间隔模式"""
last_seen = {n: -1 for n in range(1, self.blue_max+1)}
intervals = defaultdict(list)
for i, seq in enumerate(sequences):
for num in seq:
if last_seen[num] != -1:
interval = i - last_seen[num]
intervals[num].append(interval)
last_seen[num] = i
# 统计间隔特征
interval_stats = {}
for num in range(1, self.blue_max+1):
if num in intervals and intervals[num]:
ivals = intervals[num]
interval_stats[num] = {
"avg_interval": np.mean(ivals),
"min_interval": min(ivals),
"max_interval": max(ivals),
"std_interval": np.std(ivals) if len(ivals) > 1 else 0
}
else:
interval_stats[num] = {"avg_interval": 999, "min_interval": 999, "max_interval": 999}
return interval_stats
def build_markov_chain(self, sequences: List[List[int]]):
"""构建高阶马尔科夫链(考虑更多历史状态)"""
if len(sequences) < 30:
return
# 二阶马尔科夫链
for i in range(2, len(sequences)):
prev1 = tuple(sorted(sequences[i-2]))
prev2 = tuple(sorted(sequences[i-1]))
curr = tuple(sorted(sequences[i]))
# 状态编码
state = (prev1, prev2)
self.markov_chain[state][curr] += 1
# 转换为概率
for state, transitions in self.markov_chain.items():
total = sum(transitions.values())
for key in transitions:
transitions[key] /= total
print(f"[蓝球优化] 构建马尔科夫链: {len(self.markov_chain)}个状态")
def train_deep_model(self, sequences: List[List[int]]):
"""训练深度学习模型"""
if len(sequences) < 40:
print("[蓝球优化] 数据不足,跳过深度学习训练")
return
# 特征提取
X = [] # 特征
y = [] # 目标(下一期蓝球)
for i in range(1, len(sequences)):
# 当前期特征
current = sequences[i-1]
# 历史特征
historical = sequences[max(0, i-5):i-1]
# 构建特征向量
features = self._extract_features(current, historical)
# 目标:下一期蓝球
target = sequences[i]
X.append(features)
y.append(target)
self.training_history = list(zip(X, y))
print(f"[蓝球优化] 深度学习训练: {len(X)}个样本")
def _extract_features(self, current: List[int], historical: List[List[int]]) -> List[float]:
"""提取特征向量"""
features = []
# 1. 当前期特征
features.extend(current)
features.extend([0] * (2 - len(current))) # 填充
# 2. 奇偶比例
odd_ratio = sum(1 for n in current if n % 2 == 1) / len(current)
features.append(odd_ratio)
# 3. 大小比例
mid = self.blue_max // 2
big_ratio = sum(1 for n in current if n > mid) / len(current)
features.append(big_ratio)
# 4. 历史平均值
if historical:
all_nums = [num for seq in historical for num in seq]
features.append(np.mean(all_nums) / self.blue_max if all_nums else 0.5)
else:
features.append(0.5)
# 5. 间隔特征
if len(current) > 0:
# 数字间距
if len(current) > 1:
spacing = max(current) - min(current)
features.append(spacing / self.blue_max)
else:
features.append(0)
else:
features.append(0)
return features
def predict_with_deep_learning(self, historical: List[List[int]], current: List[int], top_k=5) -> List[int]:
"""深度学习预测"""
if not self.training_history:
return self._fallback_prediction(historical, current, top_k)
# 提取特征
features = self._extract_features(current, historical)
# 简单最近邻预测
predictions = []
feature_arr = np.array(features)
for train_X, train_y in self.training_history[-50:]:
# 计算相似度
sim = np.dot(feature_arr, np.array(train_X)) / (
np.linalg.norm(feature_arr) * np.linalg.norm(train_X) + 1e-8)
if sim > 0.7: # 相似度阈值
predictions.extend(train_y)
if predictions:
# 统计出现频率
freq = Counter(predictions)
top_numbers = [num for num, _ in freq.most_common(top_k)]
return sorted(top_numbers)
return self._fallback_prediction(historical, current, top_k)
def _fallback_prediction(self, historical: List[List[int]], current: List[int], top_k=5) -> List[int]:
"""备用预测算法"""
# 合并历史数据
all_historical = [num for seq in historical for num in seq]
if not all_historical:
# 随机选择
return random.sample(range(1, self.blue_max+1), min(top_k, self.blue_max))
# 频率分析
freq_counter = Counter(all_historical)
# 热号 + 冷号平衡策略
hot_numbers = [num for num, _ in freq_counter.most_common(10)]
# 寻找冷号(长期未出)
recent_history = [num for seq in historical[-20:] for num in seq] if len(historical) >= 20 else []
cold_numbers = [n for n in range(1, self.blue_max+1) if n not in recent_history]
# 组合策略:70%热号 + 30%冷号
hot_count = int(top_k * 0.7)
cold_count = top_k - hot_count
selected = hot_numbers[:hot_count]
if cold_numbers and cold_count > 0:
selected.extend(random.sample(cold_numbers, min(cold_count, len(cold_numbers))))
# 如果不够,补随机
while len(selected) < top_k:
candidate = random.randint(1, self.blue_max)
if candidate not in selected:
selected.append(candidate)
return sorted(selected[:top_k])
def predict_with_markov(self, historical: List[List[int]]) -> List[int]:
"""马尔科夫链预测"""
if len(historical) < 3 or not self.markov_chain:
return []
# 获取最近状态
state = (
tuple(sorted(historical[-2])) if len(historical) >= 2 else (),
tuple(sorted(historical[-1]))
)
if state in self.markov_chain:
# 获取最可能的下一状态
transitions = self.markov_chain[state]
if transitions:
# 按概率降序排序
sorted_transitions = sorted(transitions.items(), key=lambda x: x[1], reverse=True)
if sorted_transitions:
# 返回最可能的状态
return list(sorted_transitions[0][0])
return []
def hybrid_prediction(self, historical: List[List[int]], current: List[int],
method_weights=[0.3, 0.3, 0.4]) -> List[int]:
"""混合预测(加权组合)"""
predictions = []
# 方法1:深度学习预测
dl_pred = self.predict_with_deep_learning(historical, current, top_k=3)
if dl_pred:
predictions.extend([(n, method_weights[0]) for n in dl_pred])
# 方法2:马尔科夫预测
mk_pred = self.predict_with_markov(historical)
if mk_pred:
predictions.extend([(n, method_weights[1]) for n in mk_pred])
# 方法3:频率分析
freq_pred = self._fallback_prediction(historical, current, top_k=3)
predictions.extend([(n, method_weights[2]) for n in freq_pred])
if not predictions:
return []
# 加权选择
weighted_scores = {}
for num, weight in predictions:
if num in weighted_scores:
weighted_scores[num] += weight
else:
weighted_scores[num] = weight
# 选择得分最高的
sorted_numbers = sorted(weighted_scores.items(), key=lambda x: x[1], reverse=True)
# 确定蓝球数量
target_count = 1 if self.lt == "ssq" else 2
return [num for num, _ in sorted_numbers[:target_count]]
def learn_from_feedback(self, predicted: List[int], actual: List[int], reward: float):
"""从反馈中学习"""
# 记录奖励
self.reward_history.append({
"predicted": predicted,
"actual": actual,
"reward": reward,
"timestamp": len(self.reward_history)
})
# 调整学习率 (优化速率)
if reward > 0:
self.learning_rate *= 1.05 # 成功则加快学习
else:
self.learning_rate *= 0.95 # 失败则减慢
self.learning_rate = max(0.01, min(0.5, self.learning_rate))
# 更新模式记忆
hit_numbers = set(predicted) & set(actual)
miss_numbers = set(predicted) - set(actual)
pattern = {
"hit_numbers": list(hit_numbers),
"miss_numbers": list(miss_numbers),
"reward": reward,
"total_hits": len(hit_numbers)
}
self.pattern_memory.append(pattern)
if len(self.pattern_memory) > 50:
self.pattern_memory = self.pattern_memory[-50:]
return {
"learning_rate": self.learning_rate,
"reward_history_len": len(self.reward_history),
"avg_recent_reward": np.mean([r["reward"] for r in self.reward_history[-10:]]) if self.reward_history else 0
}
def test_blue_ball_optimization():
"""测试蓝球优化"""
print("="*60)
print("蓝球算法优化测试")
print("="*60)
from lottery_tool import Persistence
p = Persistence()
for lt in ["ssq", "dlt"]:
print(f"\n--- {'双色球' if lt == 'ssq' else '大乐透'} ---")
optimizer = BlueBallOptimizer(lt, p)
sequences = optimizer.load_blue_data()
if len(sequences) < 30:
print(f" 数据不足: {len(sequences)}期 (<30期)")
continue
print(f" 数据量: {len(sequences)}期")
# 分析模式
analysis = optimizer.analyze_patterns(sequences)
if analysis["status"] == "analyzed":
print(f" 热号: {analysis['hot_numbers']}")
print(f" 冷号: {analysis['cold_numbers']}")
print(f" 最常见模式: {analysis['most_likely_pattern']}")
# 训练模型
optimizer.build_markov_chain(sequences)
optimizer.train_deep_model(sequences)
# 预测测试(最后10期)
test_size = min(10, len(sequences) - 5)
hits = 0
total = 0
for i in range(len(sequences)-test_size, len(sequences)-1):
historical = sequences[:i]
current = sequences[i]
# 混合预测
prediction = optimizer.hybrid_prediction(historical, current)
# 实际下一期
next_actual = sequences[i+1]
# 计算命中
hit_count = len(set(prediction) & set(next_actual))
hits += hit_count
total += len(prediction)
if i >= len(sequences) - 5: # 显示最后几期
pred_str = " ".join(f"{n:02d}" for n in prediction)
act_str = " ".join(f"{n:02d}" for n in next_actual)
hit_marker = "✓" if hit_count > 0 else "✗"
print(f" 期{i+1}: 预测 [{pred_str}] | 实际 [{act_str}] | 命中{hit_count} {hit_marker}")
accuracy = hits / total * 100 if total > 0 else 0
print(f" 测试准确率: {accuracy:.2f}% ({hits}/{total})")
if accuracy > 0:
# 与随机概率对比
random_chance = (1 / (16 if lt == "ssq" else 12)) * 100 if lt == "ssq" else (2 / 12) * 100
improvement = accuracy - random_chance
print(f" 相比随机提升: {improvement:+.2f}% (随机概率: {random_chance:.2f}%)")
if __name__ == "__main__":
test_blue_ball_optimization()