File size: 2,135 Bytes
13065f0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Stable public feature preprocessing for Forge2Vec."""

from __future__ import annotations

from typing import Optional


GENRE_VOCABULARY = {
    "Comedy": 1, "Fantasy": 2, "Romance": 3, "Action": 4, "Drama": 5,
    "School": 6, "Shoujo": 7, "Shounen": 8, "Adventure": 9,
    "Supernatural": 10, "Kids": 11, "Slice of Life": 12, "Sci-Fi": 13,
    "Music": 14, "Historical": 15, "Mystery": 16, "Boys Love": 17,
    "Adult Cast": 18, "Horror": 19, "Isekai": 20, "Sports": 21,
    "Mecha": 22, "Psychological": 23, "Anthropomorphic": 24,
    "Martial Arts": 25, "Girls Love": 26, "Super Power": 27,
    "Mythology": 28, "Military": 29, "Avant Garde": 30, "Seinen": 31,
    "Parody": 32, "Harem": 33, "Gourmet": 34, "Workplace": 35,
    "Space": 36, "Ecchi": 37, "Award Winning": 38, "Detective": 39,
    "Gag Humor": 40, "Strategy Game": 41, "Gore": 42, "Vampire": 43,
    "Mahou Shoujo": 44, "Samurai": 45, "Idols (Female)": 46,
    "Suspense": 47, "CGDCT": 48, "Educational": 49, "Villainess": 50,
    "Love Polygon": 51, "Racing": 52, "Childcare": 53, "Iyashikei": 54,
    "Team Sports": 55, "Combat Sports": 56, "Delinquents": 57,
    "Idols (Male)": 58, "Medical": 59, "Memoir": 60,
    "Reincarnation": 61, "Video Game": 62, "Magical Sex Shift": 63,
    "Time Travel": 64, "Performing Arts": 65, "High Stakes Game": 66,
    "Pets": 67, "Josei": 68, "Otaku Culture": 69, "Organized Crime": 70,
    "Survival": 71, "Visual Arts": 72, "Erotica": 73,
    "Reverse Harem": 74, "Romantic Subtext": 75, "Crossdressing": 76,
    "Showbiz": 77, "Hentai": 78,
}


def genre_indices(names: list[str], max_length: int = 10) -> list[int]:
    values = [GENRE_VOCABULARY.get(name, 0) for name in names[:max_length]]
    return values + [0] * (max_length - len(values))


def metadata_vector(content_type: str, year: Optional[int], score: Optional[float]) -> list[float]:
    return [
        1.0 if content_type.lower() == "anime" else 0.0,
        1.0 if content_type.lower() == "manga" else 0.0,
        max(0.0, min(1.0, (year - 1960) / 70.0)) if year else 0.5,
        max(0.0, min(1.0, score / 10.0)) if score is not None else 0.5,
    ]