Spaces:
Sleeping
Sleeping
File size: 6,046 Bytes
e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 b006083 a506622 1585e6e 0061bc4 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e a611cff 1585e6e e4f7ea7 a611cff e4f7ea7 a611cff e4f7ea7 1585e6e be12e87 1585e6e a611cff 1585e6e e4f7ea7 1585e6e a611cff 1585e6e a506622 e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e 81ac2d0 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e a611cff e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 1585e6e e4f7ea7 a611cff e4f7ea7 1585e6e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | import os
import sys
import pandas as pd
import httpx
from openai import OpenAI
from env.environment import DataCleaningEnv
# ------------------ ENV VARIABLES ------------------
API_BASE_URL = os.getenv("API_BASE_URL", "https://router.huggingface.co/v1")
HF_TOKEN = os.getenv("HF_TOKEN") or os.getenv("API_KEY")
MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-72B-Instruct")
# ------------------ OPENAI CLIENT ------------------
client = None
try:
if not HF_TOKEN:
raise RuntimeError("API_KEY or HF_TOKEN environment variable is not set")
client = OpenAI(
base_url=API_BASE_URL,
api_key=HF_TOKEN,
http_client=httpx.Client(timeout=30.0, trust_env=False)
)
except Exception as e:
print(f"[WARN] OpenAI client init failed: {e}", file=sys.stderr)
client = None
MAX_STEPS = 6
# ------------------ LOGGING ------------------
def clean_line(value):
return str(value).replace("\r", " ").replace("\n", " ")
def log_start(task, env, model):
print(f"[START] task={clean_line(task)} env={clean_line(env)} model={clean_line(model)}")
def log_step(step, action, reward, done, error):
error_val = clean_line(error) if error else "null"
print(f"[STEP] step={step} action={clean_line(action)} reward={reward:.2f} done={str(done).lower()} error={error_val}")
def log_end(success, steps, rewards, score=None):
rewards_str = ",".join(f"{r:.2f}" for r in rewards)
if score is None:
print(f"[END] success={str(success).lower()} steps={steps} rewards={rewards_str}")
else:
print(f"[END] success={str(success).lower()} steps={steps} score={score:.4f} rewards={rewards_str}")
# ------------------ LLM DECISION ------------------
def fallback_action(history):
actions = [
{"type": "fill_nulls", "column": "city"},
{"type": "deduplicate", "column": "customer_id"},
{"type": "convert_types", "column": "age"},
{"type": "trim_whitespace", "column": "city"},
{"type": "normalize", "column": "income"},
{"type": "remove_nulls", "column": "customer_id"},
]
for action in actions:
if str(action) not in history:
return action
return {"type": "deduplicate", "column": "customer_id"}
def normalize_action(action, df, history):
valid_actions = {
"fill_nulls",
"remove_nulls",
"deduplicate",
"convert_types",
"trim_whitespace",
"normalize",
}
if not isinstance(action, dict):
return fallback_action(history)
action_type = action.get("type")
column = action.get("column")
if action_type not in valid_actions:
return fallback_action(history)
if action_type != "deduplicate" and column not in df.columns:
return fallback_action(history)
return action
def get_action_from_llm(dataset, history):
if client is None:
return fallback_action(history)
prompt = f"""
You are an intelligent data cleaning agent.
Actions:
fill_nulls, remove_nulls, deduplicate, convert_types, trim_whitespace, normalize
Previous actions:
{history}
Dataset:
{dataset}
Return ONLY:
action_type,column_name
"""
try:
response = client.chat.completions.create(
model=MODEL_NAME,
messages=[{"role": "user", "content": prompt}],
temperature=0.3,
max_tokens=50
)
output = response.choices[0].message.content.strip()
first_line = output.splitlines()[0].strip()
parts = first_line.split(",", 1)
if len(parts) < 2:
return fallback_action(history)
action_type, column = parts[0], parts[1]
return {"type": action_type.strip(), "column": column.strip()}
except Exception as e:
print(f"[WARN] LLM call failed: {e}", file=sys.stderr)
return fallback_action(history)
# ------------------ MAIN ------------------
def main():
env = None
rewards = []
steps_taken = 0
history = []
success = False
score = None
log_start("task1", "data_cleaning", MODEL_NAME)
try:
for task_id in [1, 2, 3]:
env = DataCleaningEnv(task=task_id)
obs = env.reset()
for step in range(1, MAX_STEPS + 1):
df = pd.DataFrame(obs["dataset"])
col_info = {}
for col in df.columns:
col_info[col] = {
"nulls": float(df[col].isnull().mean()),
"dtype": str(df[col].dtype),
"unique": int(df[col].nunique())
}
summary = f"""
Columns: {list(df.columns)}
Column Info: {col_info}
Duplicates: {df.duplicated().sum()}
Sample: {df.head(3).to_dict()}
"""
action = get_action_from_llm(summary, history)
action = normalize_action(action, df, history)
if str(action) in history:
action = fallback_action(history)
action = normalize_action(action, df, history)
history.append(str(action))
error = None
try:
obs, reward, done, _ = env.step(action)
except Exception as e:
error = str(e)
reward = 0.0
done = True
rewards.append(reward)
steps_taken = step
log_step(step, str(action), reward, done, error)
if done:
break
final = env.submit_cleaned_data(env.dirty_df)
score = final["final_score"]
success = score > 0.3
except Exception as e:
print(f"[WARN] inference failed: {e}", file=sys.stderr)
success = False
score = None
finally:
if env is not None and hasattr(env, "close"):
try:
env.close()
except Exception as e:
print(f"[WARN] env.close failed: {e}", file=sys.stderr)
log_end(success, steps_taken, rewards, score)
# ------------------ RUN ------------------
if __name__ == "__main__":
main()
|