├── plot.png ├── README.md └── lyric-sentiment-project.ipynb /plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salimzubair/lyric-sentiment/HEAD/plot.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sentiment Analysis of Billboard Hot 100 Songs over Time (1958-2019) 2 | 3 | For this project, I scraped all song lyrics for all entries of the Billboard Hot 100 from 1958 to 2019 from the website [genius.com](https://genius.com/) using LyricsGenius, a python API client developed by [John W Miller](https://github.com/johnwmillr/LyricsGenius). The dataset consists of lyrics for 26,138 unique songs. After scraping all the song lyrics, I performed sentiment analysis of songs using TextBlob, a Python text processing library. 4 | 5 | ## Results 6 | 7 | 1. On average, the sentiment of lyrics on the Billboard Hot 100 tend to be neutral. 8 | 9 | 2. Lyric Setiment in 2019 is about **4 times more negative** as lyric sentiment in the 1960s. 10 | 11 | ![Lyric Sentiment over Time Plot](https://github.com/salimzubair/lyric-sentiment/blob/master/plot.png) 12 | 13 | 3. Lyric sentiment, on average, has declined by 1.3% annually between 1958 and 2019. 14 | 15 | 4. Top keywords for lyrics in 1958 include: 16 | 1. "like" 17 | 2. "come" 18 | 3. "littleness" 19 | 4. "manning" 20 | 5. "knows" 21 | 6. "jump like" 22 | 7. "good" 23 | 8. "time" 24 | 25 | 5. Top Keywords for lyrics in 2019 include: 26 | 1. "like" 27 | 2. "yeah" 28 | 3. "niggas" 29 | 4. "bitches" 30 | 5. "lil bitch" 31 | 6. "love" 32 | 7. "need" 33 | 8. "fuck" 34 | 35 | ## Data 36 | 37 | The datasets containing the analysis results and scraped lyrics could not be uploaded to GitHub due to size limits. It can be viewed and downloaded here: https://data.world/szubair/lyric-sentiment-ananlysis 38 | 39 | ## Author 40 | 41 | Salim Zubair 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /lyric-sentiment-project.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "cleaned-project.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [], 9 | "machine_shape": "hm" 10 | }, 11 | "kernelspec": { 12 | "name": "python3", 13 | "display_name": "Python 3" 14 | }, 15 | "accelerator": "GPU" 16 | }, 17 | "cells": [ 18 | { 19 | "cell_type": "markdown", 20 | "metadata": { 21 | "id": "vC4oCGihZZZM", 22 | "colab_type": "text" 23 | }, 24 | "source": [ 25 | "**1. Install Libraries**\n", 26 | "\n" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "metadata": { 32 | "id": "emM8GuQ6cJac", 33 | "colab_type": "code", 34 | "colab": {} 35 | }, 36 | "source": [ 37 | "#install modules\n", 38 | "!pip install lyricsgenius\n", 39 | "!pip install textblob\n", 40 | "!python -m textblob.download_corpora" 41 | ], 42 | "execution_count": 0, 43 | "outputs": [] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": { 48 | "id": "LI2_HAAOZtpU", 49 | "colab_type": "text" 50 | }, 51 | "source": [ 52 | "**2. Import Packages**" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "metadata": { 58 | "id": "NjUzrhjiFePy", 59 | "colab_type": "code", 60 | "colab": {} 61 | }, 62 | "source": [ 63 | "#import packages\n", 64 | "from gensim.summarization import keywords\n", 65 | "import spacy\n", 66 | "import nltk\n", 67 | "from nltk.corpus import stopwords\n", 68 | "nltk.download('stopwords')\n", 69 | "stopwords = set(stopwords.words('english'))\n", 70 | "from spacy.lang.en import English\n", 71 | "nlp = English()\n", 72 | "nlp.max_length = 10000000\n", 73 | "import lyricsgenius\n", 74 | "import pandas as pd\n", 75 | "from google.colab import files" 76 | ], 77 | "execution_count": 0, 78 | "outputs": [] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": { 83 | "id": "CBoqsrUgbdsM", 84 | "colab_type": "text" 85 | }, 86 | "source": [ 87 | "**3. Define Genius API Authentication**" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "metadata": { 93 | "id": "KvJAJ-KKcO71", 94 | "colab_type": "code", 95 | "colab": {} 96 | }, 97 | "source": [ 98 | "#define Genius API authentication\n", 99 | "genius = lyricsgenius.Genius('your-api-key')" 100 | ], 101 | "execution_count": 0, 102 | "outputs": [] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "metadata": { 107 | "id": "U4XZi8LXd7q0", 108 | "colab_type": "text" 109 | }, 110 | "source": [ 111 | "**4. Import Billboard Hot 100 Dataset from Data World**\n" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "metadata": { 117 | "id": "3tM-BLi5cSOo", 118 | "colab_type": "code", 119 | "colab": {} 120 | }, 121 | "source": [ 122 | "#import billboard hot100 dataset\n", 123 | "hot100_df = pd.read_csv('https://query.data.world/s/qf6et5c7dh23kglnvjcoztlmom62it')\n", 124 | "hot100_df.drop_duplicates(subset='SongID', inplace = True) #remove duplicate occurrences of songs\n", 125 | "hot100_df.reset_index()" 126 | ], 127 | "execution_count": 0, 128 | "outputs": [] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": { 133 | "id": "n-KIa299eSsq", 134 | "colab_type": "text" 135 | }, 136 | "source": [ 137 | "**5. Define Functions**" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "metadata": { 143 | "id": "YsKhuc-ScTDy", 144 | "colab_type": "code", 145 | "colab": {} 146 | }, 147 | "source": [ 148 | "def get_lyrics(title, artist):\n", 149 | "\t''' \n", 150 | "\tFunction to return lyrics of each song using Geniu API\n", 151 | "\t'''\n", 152 | " try:\n", 153 | " return genius.search_song(title, artist).lyrics\n", 154 | " except:\n", 155 | " return 'not found'" 156 | ], 157 | "execution_count": 0, 158 | "outputs": [] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "metadata": { 163 | "id": "6e52BoUGcg-J", 164 | "colab_type": "code", 165 | "colab": {} 166 | }, 167 | "source": [ 168 | "def get_lyric_sentiment(lyrics): \n", 169 | "\t''' \n", 170 | "\tFunction to return sentiment score of each song\n", 171 | "\t'''\n", 172 | "\tanalysis = TextBlob(lyrics) \n", 173 | "\treturn analysis.sentiment.polarity" 174 | ], 175 | "execution_count": 0, 176 | "outputs": [] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "metadata": { 181 | "id": "-uNMkGovFTwB", 182 | "colab_type": "code", 183 | "colab": {} 184 | }, 185 | "source": [ 186 | "# Function to preprocess text\n", 187 | "def preprocess(text):\n", 188 | " # Create Doc object\n", 189 | " doc = nlp(text, disable=['ner', 'parser'])\n", 190 | " # Generate lemmas\n", 191 | " lemmas = [token.lemma_ for token in doc]\n", 192 | " # Remove stopwords and non-alphabetic characters\n", 193 | " a_lemmas = [lemma for lemma in lemmas \n", 194 | " if lemma.isalpha() and lemma not in stopwords]\n", 195 | " \n", 196 | " return ' '.join(a_lemmas)" 197 | ], 198 | "execution_count": 0, 199 | "outputs": [] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "metadata": { 204 | "id": "ndTW-QfUFWqQ", 205 | "colab_type": "code", 206 | "colab": {} 207 | }, 208 | "source": [ 209 | "\"\"\"Extract Keywords from text\"\"\"\n", 210 | "def return_keywords(texts):\n", 211 | " xkeywords = []\n", 212 | " values = keywords(text=preprocess(texts),split='\\n',scores=True)\n", 213 | " for x in values[:10]:\n", 214 | " xkeywords.append(x[0])\n", 215 | " try:\n", 216 | " return xkeywords \n", 217 | " except:\n", 218 | " return \"no content\"" 219 | ], 220 | "execution_count": 0, 221 | "outputs": [] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": { 226 | "id": "-U7f1mOdfryZ", 227 | "colab_type": "text" 228 | }, 229 | "source": [ 230 | "**4. Calculate Lyric Sentiment**" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "metadata": { 236 | "id": "SPl8jV8KcUru", 237 | "colab_type": "code", 238 | "colab": {} 239 | }, 240 | "source": [ 241 | "#Use get_lyrics funcion to get lyrics for every song in dataset\n", 242 | "lyrics = hot100_df.apply(lambda row: get_lyrics(row['Song'], row['Performer']), axis =1)\n", 243 | "hot100_df['Lyrics'] = lyrics\n", 244 | "hot100_df = hot100_df.drop(hot100_df[hot100_df['Lyrics'] == 'not found'].index) #drop rows where lyrics are not found on Genius" 245 | ], 246 | "execution_count": 0, 247 | "outputs": [] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "metadata": { 252 | "id": "tE6Nf5QMck3L", 253 | "colab_type": "code", 254 | "colab": {} 255 | }, 256 | "source": [ 257 | "#Use get_lyric_sentiment to get sentiment score for all the song lyrics\n", 258 | "sentiment = hot100_df.apply(lambda row: get_lyric_sentiment(row['Lyrics']), axis =1)\n", 259 | "hot100_df['Sentiment'] = sentiment" 260 | ], 261 | "execution_count": 0, 262 | "outputs": [] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "metadata": { 267 | "id": "1dQGrwZbpJ2h", 268 | "colab_type": "code", 269 | "colab": {} 270 | }, 271 | "source": [ 272 | "#Set the index of the dataframe to the WeekID. This sets us up to resample dataframe based on time\n", 273 | "hot100_df['WeekID'] = pd.to_datetime(hot100_df['WeekID'],infer_datetime_format=True)\n", 274 | "hot100_df = hot100_df.sort_values(by='WeekID')\n", 275 | "hot100_df = hot100_df.reset_index(drop=True)\n", 276 | "hot100_df = hot100_df.set_index('WeekID')" 277 | ], 278 | "execution_count": 0, 279 | "outputs": [] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "metadata": { 284 | "id": "3C6Rdc5dvkTx", 285 | "colab_type": "code", 286 | "colab": {} 287 | }, 288 | "source": [ 289 | "#Resample dataframe sentiment column by year. This arranges the mean lyric sentiment for every year\n", 290 | "hot100_resample = hot100_df['Sentiment'].resample('Y').mean()" 291 | ], 292 | "execution_count": 0, 293 | "outputs": [] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": { 298 | "id": "Uhq0GHNpf0T_", 299 | "colab_type": "text" 300 | }, 301 | "source": [ 302 | "**5. Plot Lyric Sentiment Over Time**" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "metadata": { 308 | "id": "S-AflueCuCmf", 309 | "colab_type": "code", 310 | "outputId": "b359c2c0-d395-47e1-acc2-f369e6e18be2", 311 | "colab": { 312 | "base_uri": "https://localhost:8080/", 313 | "height": 297 314 | } 315 | }, 316 | "source": [ 317 | "#Plot a line graph of lyric sentiment over time\n", 318 | "hot100_resample.plot(label='Sentiment', legend=True)" 319 | ], 320 | "execution_count": 0, 321 | "outputs": [ 322 | { 323 | "output_type": "execute_result", 324 | "data": { 325 | "text/plain": [ 326 | "" 327 | ] 328 | }, 329 | "metadata": { 330 | "tags": [] 331 | }, 332 | "execution_count": 12 333 | }, 334 | { 335 | "output_type": "display_data", 336 | "data": { 337 | "image/png": "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\nP/aybSVUR0pNAAAAAElFTkSuQmCC\n", 338 | "text/plain": [ 339 | "
" 340 | ] 341 | }, 342 | "metadata": { 343 | "tags": [] 344 | } 345 | } 346 | ] 347 | }, 348 | { 349 | "cell_type": "code", 350 | "metadata": { 351 | "id": "s9jKf91x56xa", 352 | "colab_type": "code", 353 | "outputId": "91300d84-ec8f-4500-ad9a-da55f28ac84e", 354 | "colab": { 355 | "base_uri": "https://localhost:8080/", 356 | "height": 35 357 | } 358 | }, 359 | "source": [ 360 | "#Calculate the mean percentage change of lyric sentiment\n", 361 | "hot100_resample.pct_change().mean()" 362 | ], 363 | "execution_count": 0, 364 | "outputs": [ 365 | { 366 | "output_type": "execute_result", 367 | "data": { 368 | "text/plain": [ 369 | "-0.012904971574345343" 370 | ] 371 | }, 372 | "metadata": { 373 | "tags": [] 374 | }, 375 | "execution_count": 30 376 | } 377 | ] 378 | }, 379 | { 380 | "cell_type": "markdown", 381 | "metadata": { 382 | "id": "-98z8IFof8Nz", 383 | "colab_type": "text" 384 | }, 385 | "source": [ 386 | "**6. Discover Top Keywords in Lyrics Over Time**" 387 | ] 388 | }, 389 | { 390 | "cell_type": "code", 391 | "metadata": { 392 | "id": "zqRLuCoHC1aa", 393 | "colab_type": "code", 394 | "colab": {} 395 | }, 396 | "source": [ 397 | "#Resample daraframe lyrics by year. Get all the lyrics for every song for each year\n", 398 | "lyrics_resample = hot100_df['Lyrics'].resample('Y').sum()" 399 | ], 400 | "execution_count": 0, 401 | "outputs": [] 402 | }, 403 | { 404 | "cell_type": "code", 405 | "metadata": { 406 | "id": "2sJ2mFIW1cOt", 407 | "colab_type": "code", 408 | "colab": {} 409 | }, 410 | "source": [ 411 | "#Use return_keywords function on lyrics_resample to get the top 20 keywords for each year\n", 412 | "lyric_keywords = [return_keywords(x[1]) for x in lyrics_resample.iteritems()]" 413 | ], 414 | "execution_count": 0, 415 | "outputs": [] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "metadata": { 420 | "id": "EUhWy9cjZQbP", 421 | "colab_type": "code", 422 | "colab": {} 423 | }, 424 | "source": [ 425 | "#Put lyric_keywords into a DataFrame and include lyrics_resample and hot100_resample\n", 426 | "keywords_df = pd.DataFrame(lyrics_keywords, columns = ['Keywords'])\n", 427 | "keywords_df = keywords_df.set_index(lyrics_resample.index)\n", 428 | "keywords_df['Lyrics'] = lyrics_resample\n", 429 | "keywords_df['Sentiment'] = hot100_resample" 430 | ], 431 | "execution_count": 0, 432 | "outputs": [] 433 | } 434 | ] 435 | } --------------------------------------------------------------------------------