-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathanalysisold.py
More file actions
140 lines (113 loc) · 3.74 KB
/
analysisold.py
File metadata and controls
140 lines (113 loc) · 3.74 KB
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
import json
import statistics
import math
from collections import Counter
with open("feature.json", "r") as f:
cache = json.load(f)
songs = [
song for song in cache.values()
if "status" not in song
]
songs = list(songs) # ensure it's a list
for i in range(len(songs)):
songs[i]["serial_no"] = i + 1
from collections import Counter
def compute_mood_distribution(songs):
mood_counts = Counter(song["mood"] for song in songs)
total = len(songs)
mood_distribution = {
mood: round((count / total) * 100, 1)
for mood, count in mood_counts.items()
}
dominant_mood = max(mood_distribution, key=mood_distribution.get)
return mood_distribution, dominant_mood
def compute_arousal(song):
energy = song["energy"]
tempo = song["tempo"]
loudness = song["loudness"]
# normalize tempo (40–200 BPM)
tempo_norm = min(max((tempo - 40) / (200 - 40), 0), 1)
# normalize loudness (-60 to 0 dB)
loudness_norm = min(max((loudness + 60) / 60, 0), 1)
arousal = (
0.5 * energy +
0.3 * tempo_norm +
0.2 * loudness_norm
)
aggression = (
0.4 * song["energy"] +
0.3 * loudness_norm +
0.2 * (1 - song["valence"]) +
0.1 * song["speechiness"]
)
return arousal, aggression
def moodclassify(song, mean_valence, mean_arousal):
v = song["valence"]
a = song["arousal"]
neutral = 0.1
intense_threshold = 0.8
if abs(v - 0.5) <= neutral and abs(a - 0.5) <= neutral:
return "Neutral / Mixed"
if a >= intense_threshold:
return "Intense / Angry"
if v >= 0.5 and a >= 0.5:
return "Happy / Energetic"
elif v >= 0.5 and a < 0.5:
return "Calm / Content"
elif v < 0.5 and a >= 0.5:
return "Intense / Angry"
else:
return "Sad / Melancholic"
def compute_emotional_diversity(mood_distribution):
entropy = 0.0
for percentage in mood_distribution.values():
p = percentage / 100
entropy -= p * math.log2(p)
return round(entropy, 2)
def determine_playlist_personality(
dominant_mood,
mood_distribution,
diversity_score,
avg_arousal,
avg_valence
):
# Rollercoaster: high diversity overrides everything
if diversity_score >= 1.7:
return "The Emotional Rollercoaster"
# Intense personality
if dominant_mood == "Intense / Angry" and avg_arousal >= 0.6:
return "The Rebel Manifesto"
# Feel-good personality
if dominant_mood == "Happy / Energetic" and avg_valence >= 0.55:
return "The Feel-Good Mix"
# Chill personality
if dominant_mood == "Calm / Content" and avg_arousal <= 0.45:
return "The Chill Companion"
if dominant_mood == "Sad / Melancholic":
return "The In the feels mix"
# Fallback (balanced playlists)
return "🎧 The Balanced Listener"
for song in songs:
song["arousal"], song["aggression"]= compute_arousal(song)
mean_arousal = statistics.mean(song["arousal"] for song in songs)
mean_valence = statistics.mean(song["valence"] for song in songs)
std_arousal = statistics.stdev(song["arousal"] for song in songs)
print("Mean valence:", round(mean_valence, 3))
print("Mean arousal:", round(mean_arousal, 3))
print("Std arousal:", round(std_arousal, 3))
for song in songs:
song["mood"] = moodclassify(song, mean_valence, mean_arousal)
mood_distribution, dominant_mood = compute_mood_distribution(songs)
diversity_score = compute_emotional_diversity(mood_distribution)
with open("feature.json", "w") as f:
json.dump(cache, f, indent=2)
print(mood_distribution)
print(diversity_score)
print(dominant_mood)
print(determine_playlist_personality(
dominant_mood,
mood_distribution,
diversity_score,
mean_arousal,
mean_valence
))