chintu67/karma_fraud_detector
0
1import json
2import random
3import numpy as np
4from datetime import datetime, timedelta
5from typing import List, Dict, Any
6import os
7
8class RealisticUserGenerator:
9 def __init__(self, seed=42):
10 random.seed(seed)
11 np.random.seed(seed)
12
13 self.normal_comments = [
14 "Great discussion, thanks for posting!", "Insightful post, learned something new.",
15 "Well explained.", "Nice analysis!", "Really enjoyed reading this!", "Good find!",
16 "Appreciate the details!", "Thanks for the update.", "Helpful explanation.",
17 "Clear and concise.", "Agreed.", "Interesting!", "Makes sense.", "This is helpful.",
18 "Thanks!", "Nice!", "Fair point.", "True that."
19 ]
20
21 self.suspicious_comments = [
22 "Insane", "Fire post!", "Unreal", "Mind blown!", "Crazy good!", "This hits, up!",
23 "Epic, more pls!", "Legend post!", "Wild, upvote!", "Major W!", "Gold content!", "Hype this!",
24 "Wow", "Viral vibes!", "Straight fire!", "Facts, up!", "This slaps!", "Banger post!",
25 "Peak", "Truth, vote!", "King move!", "No cap, up!", "Lit content!", "Needed this, up!",
26 "Quick", "Short and sweet!", "Up this now!", "Keep it up!", "Nice, again!"
27 ]
28
29 self.spam_comments = [
30 "Upvote me now", "Check my page", "Pls upvote fast", "Boost this post",
31 "Click my link", "Vote me up", "Sub for sub", "Need karma fast",
32 "Karma farming", "Upvote exchange", "New here, need karma", "Follow back",
33 "Drop an upvote!", "Karma needed ASAP!", "Link in bio!", "Upvote for upvote!",
34 "Pls boost me!", "Check this out!", "Need votes now!", "Support my post!",
35 "Follow me quick!", "Karma trade?", "Vote this up!", "Join my page!",
36 "Upvote my stuff!", "Help me grow!", "Click here now!", "Karma plz!"
37 ]
38
39 # Add post content lists for each user type
40 self.normal_posts = [
41 "Exploring the latest tech trends in AI.",
42 "My experience with open source contributions.",
43 "Tips for effective remote work.",
44 "How to stay productive as a developer.",
45 "A review of the best programming languages in 2024.",
46 "Lessons learned from my first hackathon.",
47 "How to build a personal portfolio website.",
48 "Understanding the basics of machine learning.",
49 "Why code reviews matter in software teams.",
50 "Best resources for learning Python."
51 ]
52 self.suspicious_posts = [
53 "Unbelievable trick to get more followers!",
54 "Boost your karma instantly with this method.",
55 "You won't believe this hack for upvotes.",
56 "Get rich quick with this simple step.",
57 "Secret to viral posts revealed!",
58 "How I gained 1000 followers in a week!",
59 "This one trick will change your life!",
60 "Earn karma fast with this method!",
61 "Top secret upvote strategy!",
62 "Double your upvotes overnight!"
63 ]
64 self.fraudulent_posts = [
65 "Upvote me and I'll upvote you back!",
66 "Need karma fast, help me out!",
67 "Join my upvote group for instant karma.",
68 "Let's trade upvotes, comment below!",
69 "Karma exchange, DM me now!",
70 "Upvote for upvote, guaranteed!",
71 "Help me reach 1000 karma today!",
72 "Instant upvotes, just comment!",
73 "Karma farming, join now!",
74 "Upvote train, hop on!"
75 ]
76
77 def _add_noise(self, text):
78 if random.random() < 0.1:
79 text = text.lower() if random.random() < 0.5 else text.upper()
80 if random.random() < 0.05:
81 if len(text) > 2:
82 i = random.randint(1, len(text)-2)
83 text = text[:i] + text[i+1] + text[i] + text[i+2:]
84 if random.random() < 0.05:
85 if random.random() < 0.5:
86 text = text.replace(" ", " ")
87 else:
88 text += text[-1]
89 if random.random() < 0.2:
90 text += random.choice(["!", "...", "๐ฅ", "๐ฏ", "๐", "๐", "๐", "๐", "๐"])
91 return text
92
93 def _generate_timestamps(self, base_time, user_type, num_acts):
94 ts = []
95 now = base_time
96 for _ in range(num_acts):
97 gap = np.random.exponential(scale={
98 'normal': 72,
99 'suspicious': 24,
100 'fraudulent': 5
101 }[user_type])
102 now = now - timedelta(hours=gap)
103 ts.append(now)
104 return sorted(ts, reverse=True)
105
106 def generate_user(self, user_type, user_id):
107 base_time = datetime.now()
108 user = {
109 "user_id": user_id,
110 "account_age_days": 0,
111 "karma_log": [],
112 "label": user_type
113 }
114
115 if user_type == 'normal':
116 user["account_age_days"] = random.randint(15, 1000)
117 elif user_type == 'suspicious':
118 user["account_age_days"] = random.randint(3, 50)
119 else:
120 user["account_age_days"] = random.randint(1, 15)
121
122 num_posts = random.randint(1, 2)
123 num_comments = random.randint(2, 6)
124 num_upvotes = random.randint(3, 7)
125 total = num_posts + num_comments + num_upvotes
126 timestamps = self._generate_timestamps(base_time, user_type, total)
127
128 # --- Post Created ---
129 posts = []
130 for i in range(num_posts):
131 if user_type == 'normal':
132 post_content = self._add_noise(random.choice(self.normal_posts))
133 elif user_type == 'suspicious':
134 post_content = self._add_noise(random.choice(self.suspicious_posts))
135 else:
136 post_content = self._add_noise(random.choice(self.fraudulent_posts))
137 posts.append(post_content)
138 user["karma_log"].append({
139 "activity_id": f"act_{user_type[0]}_{user_id}_p{i}",
140 "type": "post_created",
141 "content": post_content,
142 "timestamp": timestamps[i].isoformat() + "Z"
143 })
144
145 # --- Comments ---
146 comment_pool = []
147 if user_type == 'normal':
148 comment_pool = self.normal_comments + (self.suspicious_comments[:5] if random.random() < 0.3 else [])
149 elif user_type == 'suspicious':
150 bot_upvote_ratio = np.random.uniform(0.3, 0.8)
151 comment_pool = self.suspicious_comments[:]
152 if random.random() < 0.4:
153 comment_pool += random.sample(self.normal_comments, 5)
154 if random.random() < 0.3:
155 comment_pool += random.sample(self.spam_comments, 3)
156 base_comment = random.choice(comment_pool)
157 comments = []
158 for _ in range(num_comments):
159 if random.random() < 0.3:
160 comments.append(self._add_noise(base_comment))
161 else:
162 comments.append(self._add_noise(random.choice(comment_pool)))
163 else:
164 comment_pool = self.spam_comments + (self.suspicious_comments[:3] if random.random() < 0.2 else [])
165 comments = [self._add_noise(random.choice(comment_pool)) for _ in range(num_comments)]
166 bot_upvote_ratio = np.random.uniform(0.8, 1.2)
167 burst_count = np.random.randint(1, 5)
168
169 if user_type != 'suspicious':
170 comments = [self._add_noise(random.choice(comment_pool)) for _ in range(num_comments)]
171
172 if user_type == 'normal' and random.random() < 0.1:
173 comments[0] = random.choice(self.spam_comments)
174 if user_type == 'fraudulent' and random.random() < 0.2:
175 comments[0] = random.choice(self.normal_comments)
176
177 for i, content in enumerate(comments):
178 user["karma_log"].append({
179 "activity_id": f"act_{user_type[0]}_{user_id}_c{i}",
180 "type": "comment",
181 "content": content,
182 "timestamp": timestamps[num_posts + i].isoformat() + "Z"
183 })
184
185 # --- Upvotes (Received & Sent) ---
186 for i in range(num_upvotes):
187 upvote_timestamp = timestamps[num_posts + num_comments + i].isoformat() + "Z"
188 if user_type == 'normal':
189 from_user_age = random.randint(30, 500)
190 from_user = f"usr_{random.randint(1000,9999)}"
191 # Upvote received
192 user["karma_log"].append({
193 "activity_id": f"act_{user_type[0]}_{user_id}_u{i}",
194 "type": "upvote_received",
195 "from_user": from_user,
196 "from_user_age_days": from_user_age,
197 "timestamp": upvote_timestamp
198 })
199 # Upvote sent (to a random user)
200 sent_to_user = f"usr_{random.randint(1000,9999)}"
201 user["karma_log"].append({
202 "activity_id": f"act_{user_type[0]}_{user_id}_us{i}",
203 "type": "upvote_sent",
204 "to_user": sent_to_user,
205 "to_user_age_days": random.randint(10, 1000),
206 "timestamp": upvote_timestamp
207 })
208 elif user_type == 'suspicious':
209 from_user_age = random.choices(
210 [random.randint(2, 5), random.randint(30, 100)],
211 weights=[0.6, 0.4],
212 k=1
213 )[0]
214 from_user = f"usr_{random.randint(1000,9999)}"
215 # Upvote received
216 user["karma_log"].append({
217 "activity_id": f"act_{user_type[0]}_{user_id}_u{i}",
218 "type": "upvote_received",
219 "from_user": from_user,
220 "from_user_age_days": from_user_age,
221 "timestamp": upvote_timestamp
222 })
223 # Upvote sent (to a random user)
224 sent_to_user = f"usr_{random.randint(1000,9999)}"
225 user["karma_log"].append({
226 "activity_id": f"act_{user_type[0]}_{user_id}_us{i}",
227 "type": "upvote_sent",
228 "to_user": sent_to_user,
229 "to_user_age_days": random.randint(2, 100),
230 "timestamp": upvote_timestamp
231 })
232 else: # fraudulent
233 # For fraudulent, mutual upvotes: upvote_received and upvote_sent to the same user, but with slightly different timestamps
234 mutual_user = f"usr_{random.randint(1000,9999)}"
235 mutual_user_age = random.randint(1, 10)
236 # Generate two close but not identical timestamps
237 base_upvote_time = timestamps[num_posts + num_comments + i]
238 offset_minutes = random.randint(1, 60)
239 if random.random() < 0.5:
240 sent_time = base_upvote_time + timedelta(minutes=offset_minutes)
241 received_time = base_upvote_time
242 else:
243 sent_time = base_upvote_time
244 received_time = base_upvote_time + timedelta(minutes=offset_minutes)
245 # Upvote received
246 user["karma_log"].append({
247 "activity_id": f"act_{user_type[0]}_{user_id}_u{i}",
248 "type": "upvote_received",
249 "from_user": mutual_user,
250 "from_user_age_days": mutual_user_age,
251 "timestamp": received_time.isoformat() + "Z"
252 })
253 # Upvote sent (to the same user)
254 user["karma_log"].append({
255 "activity_id": f"act_{user_type[0]}_{user_id}_us{i}",
256 "type": "upvote_sent",
257 "to_user": mutual_user,
258 "to_user_age_days": mutual_user_age,
259 "timestamp": sent_time.isoformat() + "Z"
260 })
261
262 return user
263
264 def generate_dataset(self, n_normals, n_suspicious, n_fraud, flip_ratio=0.05):
265 dataset = []
266 for i in range(n_normals):
267 dataset.append(self.generate_user("normal", f"normal_{i+1:04}"))
268 for i in range(n_suspicious):
269 dataset.append(self.generate_user("suspicious", f"suspicious_{i+1:04}"))
270 for i in range(n_fraud):
271 dataset.append(self.generate_user("fraudulent", f"fraudulent_{i+1:04}"))
272
273 total = len(dataset)
274 flip_count = int(total * flip_ratio)
275 flip_targets = random.sample(dataset, flip_count)
276 for user in flip_targets:
277 original = user["label"]
278 choices = ["normal", "suspicious", "fraudulent"]
279 choices.remove(original)
280 user["label"] = random.choice(choices)
281
282 random.shuffle(dataset)
283 return dataset
284
285def add_noise_to_label(label, noise_level=0.15):
286 if random.random() < noise_level:
287 choices = ['normal', 'suspicious', 'fraudulent']
288 choices.remove(label)
289 return random.choice(choices)
290 return label
291
292def generate_realistic_hard_dataset(n_normals, n_suspicious, n_fraud, flip_ratio=0.10, overlap_ratio=0.25):
293 generator = RealisticUserGenerator(seed=42)
294 dataset = []
295 for i in range(n_normals):
296 user = generator.generate_user('normal', f'normal_{i+1:04}')
297 user['account_age_days'] = random.randint(15, 1000)
298 if random.random() < overlap_ratio:
299 user['karma_log'][0]['content'] = random.choice(generator.spam_comments + generator.suspicious_comments)
300 user['label'] = add_noise_to_label(user['label'], noise_level=flip_ratio)
301 dataset.append(user)
302 for i in range(n_suspicious):
303 user = generator.generate_user('suspicious', f'suspicious_{i+1:04}')
304 if random.random() < 0.15:
305 user['account_age_days'] = random.randint(1, 15)
306 else:
307 user['account_age_days'] = random.randint(15, 1000)
308 if random.random() < overlap_ratio:
309 user['karma_log'][0]['content'] = random.choice(generator.normal_comments)
310 user['label'] = add_noise_to_label(user['label'], noise_level=flip_ratio)
311 dataset.append(user)
312 for i in range(n_fraud):
313 user = generator.generate_user('fraudulent', f'fraudulent_{i+1:04}')
314 if random.random() < 0.15:
315 user['account_age_days'] = random.randint(1, 15)
316 else:
317 user['account_age_days'] = random.randint(15, 1000)
318 if random.random() < overlap_ratio:
319 user['karma_log'][0]['content'] = random.choice(generator.normal_comments + generator.suspicious_comments)
320 user['label'] = add_noise_to_label(user['label'], noise_level=flip_ratio)
321 dataset.append(user)
322 random.shuffle(dataset)
323 return dataset
324
325def main():
326 os.makedirs("data", exist_ok=True)
327 print('Generating optimal training set...')
328 train_optimal = generate_realistic_hard_dataset(400, 240, 160, flip_ratio=0.10, overlap_ratio=0.25)
329 print('Generating optimal test set...')
330 test_optimal = generate_realistic_hard_dataset(100, 60, 40, flip_ratio=0.10, overlap_ratio=0.25)
331 with open('data/optimal_train.json', 'w') as f:
332 json.dump(train_optimal, f, indent=2)
333 with open('data/optimal_test.json', 'w') as f:
334 json.dump(test_optimal, f, indent=2)
335 print('โ
Done! Optimal Training:', len(train_optimal), 'Test:', len(test_optimal))
336
337if __name__ == "__main__":
338 main() 