Update everything
This commit is contained in:
parent
ad202995b9
commit
e613b862e2
5 changed files with 846 additions and 274 deletions
202
wordsdb.py
Normal file
202
wordsdb.py
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
import sqlite3
|
||||
from datetime import datetime
|
||||
from typing import List, Optional, Dict, Any
|
||||
|
||||
class WordsDatabase:
|
||||
"""
|
||||
Database to track the performance of words when added to a prefix.
|
||||
Stores word statistics and allows querying for top-performing words.
|
||||
"""
|
||||
def __init__(self, db_path: str = "word_performance.db"):
|
||||
"""Initialize the database, creating tables if they don't exist."""
|
||||
self.db_path = db_path
|
||||
self.conn = None
|
||||
self.initialize_db()
|
||||
|
||||
def initialize_db(self):
|
||||
"""Create the database tables if they don't exist."""
|
||||
try:
|
||||
self.conn = sqlite3.connect(self.db_path)
|
||||
cursor = self.conn.cursor()
|
||||
|
||||
# Create table for word performance
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS word_performance (
|
||||
id INTEGER PRIMARY KEY,
|
||||
word TEXT NOT NULL,
|
||||
position TEXT NOT NULL,
|
||||
benign_score REAL NOT NULL,
|
||||
improvement REAL NOT NULL,
|
||||
token_count INTEGER NOT NULL,
|
||||
combined_score REAL NOT NULL,
|
||||
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
''')
|
||||
|
||||
# Create table for word statistics (aggregated data)
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS word_stats (
|
||||
word TEXT PRIMARY KEY,
|
||||
avg_improvement REAL NOT NULL,
|
||||
max_improvement REAL NOT NULL,
|
||||
avg_token_count REAL NOT NULL,
|
||||
min_token_count INTEGER NOT NULL,
|
||||
use_count INTEGER NOT NULL,
|
||||
best_position TEXT NOT NULL,
|
||||
last_updated DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
''')
|
||||
|
||||
self.conn.commit()
|
||||
print(f"Database initialized at {self.db_path}")
|
||||
except sqlite3.Error as e:
|
||||
print(f"Database error: {e}")
|
||||
|
||||
def record_word_performance(self, word: str, position: str, benign_score: float,
|
||||
improvement: float, token_count: int, combined_score: float):
|
||||
"""Record the performance of a word when added to a prefix."""
|
||||
if self.conn is None:
|
||||
self.initialize_db()
|
||||
|
||||
try:
|
||||
cursor = self.conn.cursor()
|
||||
|
||||
# Insert performance record
|
||||
cursor.execute('''
|
||||
INSERT INTO word_performance
|
||||
(word, position, benign_score, improvement, token_count, combined_score)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
''', (word, position, benign_score, improvement, token_count, combined_score))
|
||||
|
||||
# Update statistics
|
||||
cursor.execute('''
|
||||
INSERT INTO word_stats
|
||||
(word, avg_improvement, max_improvement, avg_token_count, min_token_count, use_count, best_position)
|
||||
VALUES (?, ?, ?, ?, ?, 1, ?)
|
||||
ON CONFLICT(word) DO UPDATE SET
|
||||
avg_improvement = (avg_improvement * use_count + ?) / (use_count + 1),
|
||||
max_improvement = MAX(max_improvement, ?),
|
||||
avg_token_count = (avg_token_count * use_count + ?) / (use_count + 1),
|
||||
min_token_count = MIN(min_token_count, ?),
|
||||
use_count = use_count + 1,
|
||||
best_position = CASE WHEN ? > max_improvement THEN ? ELSE best_position END,
|
||||
last_updated = CURRENT_TIMESTAMP
|
||||
''', (
|
||||
word, improvement, improvement, token_count, token_count, position,
|
||||
improvement, improvement, token_count, token_count, improvement, position
|
||||
))
|
||||
|
||||
self.conn.commit()
|
||||
except sqlite3.Error as e:
|
||||
print(f"Error recording word performance: {e}")
|
||||
# Still try to continue without failing
|
||||
|
||||
def get_top_words(self, limit: int = 20, min_uses: int = 2, sort_by: str = "improvement",
|
||||
token_weight: float = 0.0) -> List[str]:
|
||||
"""
|
||||
Get the top-performing words based on selected criteria.
|
||||
|
||||
Parameters:
|
||||
-----------
|
||||
limit: Maximum number of words to return
|
||||
min_uses: Minimum number of uses a word must have to be considered
|
||||
sort_by: How to sort the results - options: "improvement", "tokens", "combined"
|
||||
token_weight: When sort_by="combined", weight for token count vs improvement (0-1)
|
||||
|
||||
Returns:
|
||||
--------
|
||||
List of words matching the criteria
|
||||
"""
|
||||
if self.conn is None:
|
||||
self.initialize_db()
|
||||
|
||||
try:
|
||||
cursor = self.conn.cursor()
|
||||
|
||||
# Different sorting strategies
|
||||
if sort_by == "tokens":
|
||||
# Sort by token count (ascending) then by improvement (descending)
|
||||
cursor.execute('''
|
||||
SELECT word FROM word_stats
|
||||
WHERE use_count >= ? AND avg_improvement > 0
|
||||
ORDER BY min_token_count ASC, avg_improvement DESC
|
||||
LIMIT ?
|
||||
''', (min_uses, limit))
|
||||
elif sort_by == "combined":
|
||||
# Get all qualifying words with their stats
|
||||
cursor.execute('''
|
||||
SELECT word, avg_improvement, min_token_count
|
||||
FROM word_stats
|
||||
WHERE use_count >= ? AND avg_improvement > 0
|
||||
''', (min_uses,))
|
||||
|
||||
# Calculate combined scores
|
||||
results = cursor.fetchall()
|
||||
if not results:
|
||||
return []
|
||||
|
||||
# Normalize values
|
||||
max_improvement = max(row[1] for row in results)
|
||||
max_tokens = max(row[2] for row in results)
|
||||
|
||||
# Calculate combined score for each word
|
||||
scored_words = []
|
||||
for row in results:
|
||||
word = row[0]
|
||||
norm_improvement = row[1] / max_improvement if max_improvement > 0 else 0
|
||||
norm_tokens = 1 - (row[2] / max_tokens if max_tokens > 0 else 0) # Invert so lower is better
|
||||
combined_score = (1 - token_weight) * norm_improvement + token_weight * norm_tokens
|
||||
scored_words.append((word, combined_score))
|
||||
|
||||
# Sort by combined score and return top words
|
||||
scored_words.sort(key=lambda x: x[1], reverse=True)
|
||||
return [word for word, _ in scored_words[:limit]]
|
||||
else:
|
||||
# Default: sort by improvement
|
||||
cursor.execute('''
|
||||
SELECT word FROM word_stats
|
||||
WHERE use_count >= ? AND avg_improvement > 0
|
||||
ORDER BY avg_improvement DESC
|
||||
LIMIT ?
|
||||
''', (min_uses, limit))
|
||||
|
||||
results = cursor.fetchall()
|
||||
return [row[0] for row in results]
|
||||
except sqlite3.Error as e:
|
||||
print(f"Error getting top words: {e}")
|
||||
return []
|
||||
|
||||
def get_word_stats(self, word: str) -> Optional[Dict[str, Any]]:
|
||||
"""Get statistics for a specific word."""
|
||||
if self.conn is None:
|
||||
self.initialize_db()
|
||||
|
||||
try:
|
||||
cursor = self.conn.cursor()
|
||||
cursor.execute('''
|
||||
SELECT word, avg_improvement, max_improvement, avg_token_count, min_token_count, use_count, best_position
|
||||
FROM word_stats
|
||||
WHERE word = ?
|
||||
''', (word,))
|
||||
|
||||
result = cursor.fetchone()
|
||||
if result:
|
||||
return {
|
||||
"word": result[0],
|
||||
"avg_improvement": result[1],
|
||||
"max_improvement": result[2],
|
||||
"avg_token_count": result[3],
|
||||
"min_token_count": result[4],
|
||||
"use_count": result[5],
|
||||
"best_position": result[6]
|
||||
}
|
||||
return None
|
||||
except sqlite3.Error as e:
|
||||
print(f"Error getting word stats: {e}")
|
||||
return None
|
||||
|
||||
def close(self):
|
||||
"""Close the database connection."""
|
||||
if self.conn:
|
||||
self.conn.close()
|
||||
self.conn = None
|
||||
Loading…
Add table
Add a link
Reference in a new issue