first commit
This commit is contained in:
commit
dbbf968f41
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Dairo Carrasquilla
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
69
README.md
Normal file
69
README.md
Normal file
@ -0,0 +1,69 @@
|
||||
# 🎰 Miloto AI - Lottery Prediction System
|
||||
|
||||
`Miloto AI` es un sistema de predicción de números de lotería basado en redes neuronales. Usa modelos LSTM con múltiples salidas para intentar predecir combinaciones ganadoras de un archivo histórico de resultados.
|
||||
|
||||
⚠️ Este proyecto **no garantiza resultados reales ni premios**, pero es una excelente herramienta de aprendizaje sobre redes neuronales, modelos multi-salida y entrenamiento de modelos con Keras/TensorFlow.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Getting Started
|
||||
|
||||
### 📁 Requisitos
|
||||
|
||||
* Python 3.8+
|
||||
* TensorFlow 2.x
|
||||
* NumPy
|
||||
* [art](https://pypi.org/project/art/) (para generar banners ASCII)
|
||||
|
||||
### 📦 Instalación
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 📄 Formato del archivo `data.txt`
|
||||
|
||||
Debes tener un archivo llamado `data.txt` en el mismo directorio, con este formato:
|
||||
|
||||
```
|
||||
5,12,18,23,35
|
||||
8,10,14,21,39
|
||||
...
|
||||
```
|
||||
Cada línea representa una combinación de números ganadores, separados por comas. Asegúrate de que el archivo no tenga encabezados ni otros caracteres.
|
||||
El formato debe ser **exactamente** así para que el script funcione correctamente.
|
||||
Si no tienes un archivo de datos, puedes crear uno manualmente o usar un generador de números aleatorios.
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Ejecución
|
||||
|
||||
```bash
|
||||
python miloto_ai.py
|
||||
```
|
||||
|
||||
El script:
|
||||
|
||||
1. Limpia la consola.
|
||||
2. Muestra una pantalla de bienvenida.
|
||||
3. Carga y valida los datos.
|
||||
4. Construye y entrena un modelo LSTM multi-output.
|
||||
5. Muestra una barra de progreso animada por época.
|
||||
6. Genera una predicción de una nueva combinación de números.
|
||||
|
||||
---
|
||||
|
||||
## 📌 Disclaimer
|
||||
|
||||
Este proyecto es **puramente educativo** y no tiene ninguna capacidad mágica para adivinar resultados de lotería reales.
|
||||
|
||||
* No está afiliado a ningún sistema de lotería oficial.
|
||||
* No garantiza ningún tipo de premio.
|
||||
* Usar esto para apuestas reales es bajo tu **propio riesgo** (y probablemente mala idea).
|
||||
|
||||
---
|
||||
|
||||
## 🤖 Créditos
|
||||
|
||||
Desarrollado por Dairo Carrasquilla.
|
||||
Inspirado en la idea absurda pero divertida de predecir el azar con redes neuronales.
|
10
data.txt
Normal file
10
data.txt
Normal file
@ -0,0 +1,10 @@
|
||||
1,8,22,37,38
|
||||
5,15,17,21,25
|
||||
4,13,14,21,31
|
||||
13,23,26,30,36
|
||||
4,16,27,29,32
|
||||
2,5,13,17,26
|
||||
12,21,22,37,39
|
||||
10,20,28,29,38
|
||||
2,18,28,33,38
|
||||
7,8,10,29,31
|
150
miloto_ai.py
Normal file
150
miloto_ai.py
Normal file
@ -0,0 +1,150 @@
|
||||
from tensorflow import keras
|
||||
from keras import layers
|
||||
from art import text2art
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
import socket
|
||||
import sys
|
||||
|
||||
# Bloquear el acceso a Internet
|
||||
socket.socket = lambda *args, **kwargs: (_ for _ in ()).throw(Exception("Internet access is disabled"))
|
||||
|
||||
# === Callback Personalizado para Salida Estilizada de Entrenamiento ===
|
||||
class CustomTrainingCallback(tf.keras.callbacks.Callback):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.total_epochs = None
|
||||
self.bar_length = 40
|
||||
|
||||
def on_train_begin(self, logs=None):
|
||||
self.total_epochs = self.params['epochs']
|
||||
print("\033[1;36m" + "=" * 60 + "\033[0m")
|
||||
print("\033[1;35mTraining Progress:\033[0m")
|
||||
|
||||
def on_epoch_end(self, epoch, logs=None):
|
||||
current = epoch + 1
|
||||
percent = current / self.total_epochs
|
||||
filled_len = int(self.bar_length * percent)
|
||||
bar = '█' * filled_len + '·' * (self.bar_length - filled_len)
|
||||
sys.stdout.write(f"\r\033[1;34m[Epoch {current}/{self.total_epochs}] [{bar}] {percent*100:.1f}%\033[0m")
|
||||
sys.stdout.flush()
|
||||
|
||||
if current == self.total_epochs:
|
||||
print("\n\033[1;36m" + "=" * 60 + "\033[0m\n")
|
||||
|
||||
# === Funciones de Interfaz ===
|
||||
def print_banner():
|
||||
print("\033[1;34m" + text2art("Miloto AI", font="block"))
|
||||
print("\033[1;33m" + "Lottery Prediction Artificial Intelligence".center(60) + "\033[0m")
|
||||
print("\033[1;36m" + "=" * 60 + "\033[0m")
|
||||
|
||||
def print_status(message):
|
||||
print(f"\033[1;34m[•]\033[0m \033[1;37m{message}\033[0m")
|
||||
|
||||
def print_intro():
|
||||
print_banner()
|
||||
print_status("Starting LotteryAI Prediction System...")
|
||||
print("\033[1;36m" + "=" * 60 + "\033[0m")
|
||||
|
||||
# === Funciones de Carga y Entrenamiento ===
|
||||
def load_data():
|
||||
try:
|
||||
if not tf.io.gfile.exists('data.txt'):
|
||||
raise FileNotFoundError("data.txt not found")
|
||||
|
||||
data = np.genfromtxt('data.txt', delimiter=',', dtype=int)
|
||||
if data.size == 0:
|
||||
raise ValueError("data.txt is empty")
|
||||
|
||||
data[data == -1] = 0
|
||||
|
||||
train_size = int(0.8 * len(data))
|
||||
if train_size == 0:
|
||||
raise ValueError("Dataset too small to split")
|
||||
|
||||
train_data = data[:train_size]
|
||||
val_data = data[train_size:]
|
||||
max_value = np.max(data)
|
||||
|
||||
return train_data, val_data, max_value
|
||||
except Exception as e:
|
||||
print(f"\033[1;31mError loading data: {str(e)}\033[0m")
|
||||
sys.exit(1)
|
||||
|
||||
def create_model(num_features, max_value):
|
||||
try:
|
||||
model = keras.Sequential([
|
||||
layers.Embedding(input_dim=max_value+1, output_dim=32),
|
||||
layers.LSTM(64, return_sequences=False),
|
||||
layers.Dense(num_features, activation='softmax')
|
||||
])
|
||||
model.compile(
|
||||
loss='categorical_crossentropy',
|
||||
optimizer='adam',
|
||||
metrics=['accuracy']
|
||||
)
|
||||
return model
|
||||
except Exception as e:
|
||||
print(f"\033[1;31mError creating model: {str(e)}\033[0m")
|
||||
sys.exit(1)
|
||||
|
||||
def train_model(model, train_data, val_data):
|
||||
try:
|
||||
callback = CustomTrainingCallback()
|
||||
history = model.fit(
|
||||
train_data,
|
||||
train_data,
|
||||
validation_data=(val_data, val_data),
|
||||
epochs=100,
|
||||
verbose=0, # Desactiva la salida estándar
|
||||
callbacks=[callback]
|
||||
)
|
||||
return history
|
||||
except Exception as e:
|
||||
print(f"\033[1;31mError training model: {str(e)}\033[0m")
|
||||
sys.exit(1)
|
||||
|
||||
def predict_numbers(model, val_data, num_features):
|
||||
try:
|
||||
predictions = model.predict(val_data)
|
||||
indices = np.argsort(predictions, axis=1)[:, -num_features:]
|
||||
predicted_numbers = np.take_along_axis(val_data, indices, axis=1)
|
||||
return predicted_numbers
|
||||
except Exception as e:
|
||||
print(f"\033[1;31mError predicting numbers: {str(e)}\033[0m")
|
||||
sys.exit(1)
|
||||
|
||||
def print_predicted_numbers(predicted_numbers):
|
||||
print_status("Generating predictions...")
|
||||
print("\033[1;36m" + "=" * 60 + "\033[0m")
|
||||
print("\033[1;32m" + "🎯 PREDICTED NUMBERS 🎯".center(60) + "\033[0m")
|
||||
print("\033[1;36m" + "-" * 60 + "\033[0m")
|
||||
|
||||
if predicted_numbers.size > 0:
|
||||
print(f"\033[1;37m{', '.join(map(str, predicted_numbers[0]))}\033[0m")
|
||||
else:
|
||||
print("\033[1;31mNo predictions available\033[0m")
|
||||
|
||||
print("\033[1;36m" + "=" * 60 + "\033[0m")
|
||||
|
||||
def main():
|
||||
try:
|
||||
print("\x1b[H\x1b[2J\x1b[3J") # Limpia la consola
|
||||
print_intro()
|
||||
|
||||
train_data, val_data, max_value = load_data()
|
||||
|
||||
if train_data.ndim < 2:
|
||||
raise ValueError("Training data has invalid dimensions")
|
||||
|
||||
num_features = train_data.shape[1]
|
||||
model = create_model(num_features, max_value)
|
||||
train_model(model, train_data, val_data)
|
||||
predicted_numbers = predict_numbers(model, val_data, num_features)
|
||||
print_predicted_numbers(predicted_numbers)
|
||||
except Exception as e:
|
||||
print("\033[1;31m[!] Error:\033[0m", str(e))
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
||||
tensorflow>=2.10
|
||||
numpy>=1.22
|
||||
art>=5.9
|
Loading…
x
Reference in New Issue
Block a user