Download gen_data.py from PrachiSandipkumar/GhostingPrediction101: direct link, hf CLI and curl.
- Browser
- Download file 4.85 kB
-
https://huggingface.co/spaces/PrachiSandipkumar/GhostingPrediction101/resolve/main/gen_data.py
- Command line
-
hf download hf://spaces/PrachiSandipkumar/GhostingPrediction101/gen_data.py
-
curl -L -o gen_data.py https://huggingface.co/spaces/PrachiSandipkumar/GhostingPrediction101/resolve/main/gen_data.py
4.85 kB
| import pandas as pd | |
| import numpy as np | |
| import random | |
| random.seed(42) | |
| np.random.seed(42) | |
| n = 10000 | |
| data = [] | |
| for _ in range(n): | |
| # --- RAW FEATURES --- | |
| last_message_length = random.randint(1, 50) | |
| response_time_gap = random.uniform(0, 72) | |
| initiator = random.choice(['me', 'them']) | |
| conversation_length = random.randint(1, 200) | |
| reply_ratio = round(random.uniform(0, 1), 2) | |
| avg_response_time = random.uniform(1, 120) | |
| message_tone = random.choice(['dry', 'neutral', 'enthusiastic']) | |
| emoji_count = random.randint(0, 10) | |
| question_asked = random.choice([0, 1]) | |
| time_of_day = random.choice(['day', 'night']) | |
| seen_ignored = random.choice([0, 1]) | |
| past_ghosting_history = random.choice([0, 1]) | |
| # --- PERSONA (KEY IDEA FROM CHATGPT — BUT EXPOSE IT AS A FEATURE) --- | |
| user_type = random.choice(['interested', 'casual', 'dry_texter', 'ghoster']) | |
| # --- REPLY LOGIC --- | |
| reply_prob = 0.5 | |
| if seen_ignored == 1 and response_time_gap > 24: reply_prob -= 0.35 | |
| if message_tone == 'enthusiastic': reply_prob += 0.20 | |
| if question_asked == 1: reply_prob += 0.15 | |
| if response_time_gap > 24: reply_prob -= 0.20 | |
| # Persona effect on reply | |
| if user_type == 'interested': reply_prob += 0.25 | |
| elif user_type == 'casual': reply_prob += 0.05 | |
| elif user_type == 'dry_texter': reply_prob -= 0.10 | |
| elif user_type == 'ghoster': reply_prob -= 0.30 | |
| reply_prob = max(0.05, min(reply_prob, 0.95)) | |
| reply = 1 if random.random() < reply_prob else 0 | |
| # --- GHOSTING LOGIC --- | |
| ghost_prob = 0.20 | |
| # Response time (capped contribution) | |
| if response_time_gap > 48: ghost_prob += 0.28 | |
| elif response_time_gap > 24: ghost_prob += 0.15 | |
| # Reply ratio (capped contribution) | |
| if reply_ratio < 0.2: ghost_prob += 0.22 | |
| elif reply_ratio < 0.4: ghost_prob += 0.12 | |
| # Tone | |
| if message_tone == 'dry': ghost_prob += 0.15 | |
| elif message_tone == 'neutral': ghost_prob += 0.05 | |
| # Seen ignored | |
| if seen_ignored == 1: ghost_prob += 0.18 | |
| # Past ghosting | |
| if past_ghosting_history == 1: ghost_prob += 0.15 | |
| # Combo: high gap + low engagement (ChatGPT step 3 — done safely) | |
| # Cap this so it can't stack to 0.98 by itself | |
| combo_bonus = 0.0 | |
| if reply_ratio < 0.3 and response_time_gap > 24: | |
| combo_bonus += 0.15 | |
| # Conversation decay (ChatGPT step 3 — made safe) | |
| # Only applies a small, capped bonus — not a runaway multiplier | |
| decay = min(conversation_length / 200, 1.0) # max 1.0 | |
| combo_bonus += decay * 0.10 # max +0.10, not +0.30 | |
| # Emotional mismatch (ChatGPT step 4) | |
| if message_tone == 'enthusiastic' and reply_ratio < 0.3: | |
| combo_bonus += 0.08 | |
| # Inconsistency (ChatGPT step 3) | |
| if abs(response_time_gap - avg_response_time) > 20: | |
| combo_bonus += 0.08 | |
| # HARD CAP on combo to prevent stacking explosion | |
| combo_bonus = min(combo_bonus, 0.25) | |
| ghost_prob += combo_bonus | |
| # Persona effect on ghosting | |
| if user_type == 'interested': ghost_prob -= 0.18 | |
| elif user_type == 'casual': ghost_prob += 0.05 | |
| elif user_type == 'dry_texter': ghost_prob += 0.12 | |
| elif user_type == 'ghoster': ghost_prob += 0.28 | |
| ghost_prob = max(0.05, min(ghost_prob, 0.92)) # cap at 0.92, not 0.98 | |
| ghosted = 1 if random.random() < ghost_prob else 0 | |
| # 2% label noise | |
| if random.random() < 0.02: reply = 1 - reply | |
| if random.random() < 0.02: ghosted = 1 - ghosted | |
| data.append([ | |
| last_message_length, response_time_gap, initiator, | |
| conversation_length, reply_ratio, avg_response_time, | |
| message_tone, emoji_count, question_asked, time_of_day, | |
| seen_ignored, past_ghosting_history, user_type, # <-- exposed! | |
| reply, ghosted | |
| ]) | |
| columns = [ | |
| 'last_message_length', 'response_time_gap', 'initiator', | |
| 'conversation_length', 'reply_ratio', 'avg_response_time', | |
| 'message_tone', 'emoji_count', 'question_asked', 'time_of_day', | |
| 'seen_ignored', 'past_ghosting_history', | |
| 'user_type', # persona is now a feature the model can learn from | |
| 'reply', 'ghosted' | |
| ] | |
| df = pd.DataFrame(data, columns=columns) | |
| df.to_csv("ghosting_dataset5.csv", index=False) | |
| print(df.shape) | |
| print("\nClass distribution (ghosted):") | |
| print(df['ghosted'].value_counts()) | |
| print(f"Ghosting rate: {df['ghosted'].mean():.1%}") | |
| print("\nClass distribution (reply):") | |
| print(df['reply'].value_counts()) | |
| print(f"Reply rate: {df['reply'].mean():.1%}") | |
| print("\nUser type distribution:") | |
| print(df['user_type'].value_counts()) |