Skip to content
Snippets Groups Projects
Commit 65008a42 authored by Aaron Cheung's avatar Aaron Cheung
Browse files

Created sentiment analysis page and css styling for it, added line animation to navbar

parent beee3339
No related branches found
No related tags found
No related merge requests found
......@@ -17,6 +17,23 @@ body {
.navbar a {
font-family: Arial, Helvetica, sans-serif;
font-size: 25px;
position: relative;
}
.navbar a::after { /* this and a:hover::after is for navbar line effect */
content: "";
position: absolute;
width: 0;
height: 2px;
bottom: 0;
left: 50%;
background-color: #1db954; /* adjust this as needed */
transition: width 0.3s ease-in-out, left 0.3s ease-in-out;
}
.navbar a:hover::after {
width: 100%;
left: 0;
}
.nav-description {
......@@ -33,7 +50,7 @@ body {
}
.navbar:hover .nav-description {
transform: translateY(10%); /* moves the text description down */
transform: translateY(20%); /* moves the text description down */
}
.container {
......@@ -104,8 +121,10 @@ hr.gradient {
}
.spotify-embed {
/* margin-top: 50px; */
margin-bottom: 20px;
display: flex;
justify-content: center;
gap: 10px;
}
.img-mood-count {
......@@ -163,7 +182,7 @@ hr.gradient {
margin-left: 3%;
}
.image-container > img:hover { /* hovering over the images enlarges them */
.image-container > img:hover { /* hovering over the images to enlarge them */
transform: scale(1.3);
}
......@@ -174,7 +193,7 @@ hr.gradient {
#text-2 {
font-size: 20px;
padding-top: 10%;
padding-top: 12%;
text-align: right;
}
......@@ -279,4 +298,34 @@ hr.gradient {
.table th:not(:first-child) {
font-weight: normal;
}
/* -------------------------------------------------- */
/* sentimentanalysis.html page */
.sentiment-analysis-img {
display: flex;
justify-content: center;
flex-wrap: wrap;
transition:transform 0.25s ease;
}
.img-valence-sentiment-mood2 {
width: 60%;
height: auto;
transition:transform 0.25s ease;
border: 3px solid #1db954;
border-radius: 3px;
margin-top: 25px;
margin-bottom: 25px;
}
.sentiment-analysis-img > img:hover {
transform: scale(1.4);
}
.spotify-container {
margin-top: 25px;
margin-bottom: 25px;
width: 100%;
}
\ No newline at end of file
......@@ -3,7 +3,7 @@
{% block content %}
<p id="intro">Welcome to the website of my dissertation project. This project aims to predict the moods of songs in a Spotify playlist by using both Spotify's track audio features and sentiment analysis of song lyrics, and feeding this data into a machine learning model.
<br><br>
For my project, it will be used to analyse the Top Songs of 2019 - 2022 to look at the listening habits of people during the COVID-19 pandemic, and how they may have been affected. Here you will be able to see the results of my analysis - for example, the most common moods - how useful sentiment analysis of lyrics is in mood prediction, and my justification of choice in machine learning model. A logistic regression model was used to predict the moods - all charts shown are therefore based on this model.
For my project, it will be used to analyse the Top Songs of 2019 - 2022 to look at the listening habits of people during the COVID-19 pandemic, and how they may have been affected. Here you will be able to see the results of my analysis (such as the most common moods), how useful sentiment analysis of lyrics is in mood prediction, and my justification of choice in machine learning model. A logistic regression model was used to predict the moods - all charts shown are therefore based on this model.
</p>
<div class="button-container">
......
......@@ -3,7 +3,7 @@
{% block content %}
<div class="subheading">Choosing a Machine Learning Model</div>
<div class="description">In this project, I tested four different machine learning classification models to predict the mood of the songs in a given playlist, which was trained using a dataset I created: Gaussian Naive Bayes, Support Vector Classifier, Decision Tree, and Logistic Regression. By using different measures to test which was the most accurate (precision, recall, F1-score), I decided to use logistic regression for the final implementation as it had the best scores.</div>
<div class="description">In this project, I tested four different machine learning classification models to predict the mood of the songs in a given playlist, which was trained using a dataset I created: Gaussian Naive Bayes, Support Vector Classifier, Decision Tree, and Logistic Regression. By using different measures to test which was the most accurate (precision, recall, F1-score), I decided to use logistic regression for the final implementation as it had the best results.</div>
<div class="confusion-matrix">
<img src="{{ url_for('static', filename='images/gnb_confusion_matrix.png') }}" alt="Gaussian Naive Bayes Confusion Matrix" class="confusion-matrix-image">
......@@ -18,7 +18,7 @@
<hr class="gradient">
<div class="description">In the confusion matrices, we can see how logistic regression has the greatest number of predicted moods matching the true moods for all except "Calm". When we compare the accuracies we see that logistic regression performs the best, where the accuracy is how many correctly classified instances there are over the total number of instances. However, this may not always be the best measure if the dataset is not completely balanced (there are slight differences in number of songs per mood in the dataset). So, we can look at other metrics to compare the models:</div>
<div class="description">In the confusion matrices, we can see how logistic regression has the greatest number of predicted moods matching the true moods for all except "Calm". When we compare the accuracies we see that logistic regression performs the best, where the accuracy is the number of correctly classified instances over the total number of instances. However, this may not always be the best measure if the dataset is not completely balanced (there are slight differences in number of songs per mood in the dataset). So, we can look at other metrics to compare the models:</div>
<div class="table-container">
<div class="table">
......
{% extends 'base.html' %}
{% block title %} Using sentiment analysis on lyrics {% endblock %}
{% block title %} Using Sentiment Analysis on Lyrics {% endblock %}
{% block content %}
<p>Sentiment analysis page</p>
<div class="subheading">Using Sentiment Analysis on Lyrics</div>
<div class="description">Part of this project's intention was to see if sentiment analysis could be a viable approach to determine the mood of a song. Using the VADER (Valence Aware Dictionary and sEntiment Reasoner) Python module to determine the sentiment of the lyrics in the songs alongside Spotify's track audio features, a classification of mood could be predicted using four labels: Happy, Sad, Excited, Calm.
<hr class="gradient">
However, whilst the overall predictions are fairly accurate, the sentiment analysis of the lyrics alone is not the most reliable feature to predict a song's mood. Multiple reasons for this could be attributed; the sentiment of a song's lyrics could be opposite to the sound of the song which would affect Spotify's audio features (e.g., an upbeat song with sad lyrics), words can have double meanings, and the use of slang and wordplay (especially in genres like rap) can be difficult to interpret.
</div>
<div class="sentiment-analysis-img">
<img src="{{ url_for('static', filename='images/ValenceSentimentMood_Scatter_Dataset.png') }}" alt="Scatter Plot of Valence, Sentiment, Moods of the entire dataset" class="img-valence-sentiment-mood2">
</div>
<div class="description">
In this scatter plot of the entire dataset, the valence scores are against the sentiment analysis score and the moods are colour-coded accordingly so we can compare the accuracy/effectiveness of sentiment analysis. The sentiment analysis values uses the compound score from VADER, which is a single 'normalised, weighted composite score'.
<br><br>
Though there are clusters where we would expect, such as happy songs being in the top right to indicate both a high valence and VADER score, there are some which do not fit our hypothesis. For example, there is a fairly dense cluster of sad songs with high VADER scores and low valence, which could be due to the reasons mentioned above.
</div>
<hr class="gradient">
<div class="description">
You can view the playlist of songs used for each mood to create the entire dataset here:
</div>
<div class="spotify-container">
<div class="spotify-embed">
<iframe style="border-radius:12px" src="https://open.spotify.com/embed/playlist/4SQyVxcMYRxWfPfr5fm0JK?utm_source=generator" width="24%" height="152" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>
<iframe style="border-radius:12px" src="https://open.spotify.com/embed/playlist/0pV6pPswoQSFSDmhZ7lYeN?utm_source=generator" width="24%" height="152" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>
<iframe style="border-radius:12px" src="https://open.spotify.com/embed/playlist/18Phl23oHX8EtqVSv3meh2?utm_source=generator" width="24%" height="152" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>
<iframe style="border-radius:12px" src="https://open.spotify.com/embed/playlist/6vHM1zOGd3tRJnBHY7L5OS?utm_source=generator" width="24%" height="152" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>
</div>
</div>
{% endblock %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment