| from bertopic import BERTopic |
| import os |
|
|
| |
| MODEL_PATH = "my_mastodon_model_reduced" |
| OUTPUT_HTML = "safe_topics_map.html" |
|
|
| |
| |
| NSFW_KEYWORDS = { |
| "nsfw", "porn", "nude", "naked", "sex", "18+", "xxx", |
| "cum", "dick", "pussy", "hentai", "erotic", "onlyfans", |
| "boobs", "tits", "cock", "slut", "whore", "bitch", "incest", |
| "lewd", "horny", "sensual", "fetish", "bondage" |
| } |
|
|
| def get_safe_topic_ids(model, nsfw_set): |
| """ |
| Returns a list of Topic IDs that do NOT contain any blocklisted words |
| in their top 10 keywords. |
| """ |
| safe_ids = [] |
| unsafe_ids = [] |
| |
| |
| all_topics = model.get_topics() |
| |
| print(f"Scanning {len(all_topics)} topics for NSFW content...") |
| |
| for topic_id, words_with_scores in all_topics.items(): |
| |
| |
| |
| topic_words = {word for word, score in words_with_scores} |
| |
| |
| |
| intersection = topic_words.intersection(nsfw_set) |
| |
| if intersection: |
| print(f" [BLOCKED] Topic {topic_id}: Found {intersection}") |
| unsafe_ids.append(topic_id) |
| else: |
| safe_ids.append(topic_id) |
| |
| print(f"\nResult: {len(safe_ids)} Safe, {len(unsafe_ids)} Unsafe.") |
| return safe_ids |
|
|
| |
| if not os.path.exists(MODEL_PATH): |
| print(f"Error: Model not found at {MODEL_PATH}") |
| exit() |
|
|
| print("Loading model...") |
| topic_model = BERTopic.load(MODEL_PATH) |
|
|
| |
| safe_topics = get_safe_topic_ids(topic_model, NSFW_KEYWORDS) |
|
|
| |
| print(f"Generating visualization for {len(safe_topics)} topics...") |
|
|
| |
| |
| try: |
| fig = topic_model.visualize_topics(topics=safe_topics) |
| |
| |
| fig.write_html(OUTPUT_HTML) |
| print(f"Success! Clean map saved to '{OUTPUT_HTML}'") |
| |
| except Exception as e: |
| print(f"Visualization failed (maybe 0 topics left?): {e}") |