Skip to content

Recommender

Recommender Page

The recommender page (Home Page) provides the User Interface (UI) structure and process behind the recommendation system.

Recommender Page Documentation

access_tracks()

Method enables access to saved track information.

Returns:

Name Type Description
df DataFrame

The dataframe containing all feature information of saved tracks

Source code in src/recommender.py
105
106
107
108
109
110
111
112
113
114
def access_tracks():
    """Method enables access to saved track information.

    Returns:
        df (DataFrame): The dataframe containing all feature information of saved tracks
    """
    root_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
    file_path = os.path.join(root_path, 'data', 'tracks.csv')
    df = pd.read_csv(file_path, index_col=0)  # Read in stored tracks dataframe
    return df

create_feature_weighting(maximum=12)

Creates a streamlit dropdown menu, providing a selection of features that the user can select to weight.

Parameters:

Name Type Description Default
maximum int

The maximum number of features you can choose for weighting.

12

Returns:

Type Description
list

A list of selected feature names.

Source code in src/recommender.py
179
180
181
182
183
184
185
186
187
188
189
190
191
def create_feature_weighting(maximum=12):
    """Creates a streamlit dropdown menu, providing a selection of features that the user can select to weight.

    Args:
        maximum (int): The maximum number of features you can choose for weighting.

    Returns:
        (list): A list of selected feature names.
    """
    options = ['artist_pop', 'track_pop', 'danceability', 'energy', 'loudness', 'speechiness', 'acousticness',
               'instrumentalness', 'liveness', 'valences', 'tempos', 'durations_ms', 'tempos']
    selected_option = st.multiselect('Select features to weight', options, max_selections=maximum)
    return selected_option

display_spotify_recommendations()

Method deals with displaying the Spotify recommendations in the form of Spotify iFrames for each recommendation.

This section is composed of two columns, with 30 recommendations split evenly between them creating a 15 x 2 table.

Source code in src/recommender.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
def display_spotify_recommendations():
    """Method deals with displaying the Spotify recommendations in the form of Spotify iFrames for each recommendation.

    This section is composed of two columns, with 30 recommendations split evenly between them creating a 15 x 2 table.
    """
    st.markdown("#### Recommended Tracks")

    col1, col2 = st.columns(2)
    count = 0
    rec_df = st.session_state.similarity.get_top_n(30)
    for index, row in rec_df.iterrows():
        spotify_uri = row['uris']
        embed_code = f'<iframe src="https://open.spotify.com/embed/track/{spotify_uri.split(":")[-1]}" ' \
                     'width="300" height="80" frameborder="0" allowtransparency="true" allow="encrypted-media"></iframe>'

        if count % 2 == 0:
            with col1:
                st.markdown(embed_code, unsafe_allow_html=True)
        else:
            with col2:
                st.markdown(embed_code, unsafe_allow_html=True)
        count += 1

feature_def_section()

This method creates the features section in the Streamlit app.

Specifically, it creates the feature definitions drop down information.

Source code in src/recommender.py
14
15
16
17
18
19
20
21
22
23
24
25
26
def feature_def_section():
    """This method creates the features section in the Streamlit app.

    Specifically, it creates the feature definitions drop down information.
    """
    st.markdown(
        '**For advanced recommender personalization please select the features to be weighted (have more importance) to '
        'your search**')

    with st.expander('Feature Definitions'):
        feature_defs = retrieve_feature_defs()
        for definition in feature_defs.split('\\n'):
            st.markdown(definition)

playlist_submission()

Method handles the process that follows the clicking of the submit button

The process is as follows: - The given playlist tracks are retrieved. - The tracks dataset is read in - Similarity is calculated - Streamlit session states are updated

Source code in src/recommender.py
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
def playlist_submission():
    """Method handles the process that follows the clicking of the `submit` button

    The process is as follows:
    - The given playlist tracks are retrieved.
    - The tracks dataset is read in
    - Similarity is calculated
    - Streamlit session states are updated
    """
    df_playlist = retrieve_target_playlist(playlist_url, playlist_name)
    df_tracks = access_tracks()

    st.session_state.similarity = TracksCosineSimilarity(df_playlist, df_tracks, st.session_state.weighted_features)
    st.session_state.similarity.calculate_similarity()
    update_tracking(df_tracks)

    st.session_state.playlist_links.append(playlist_url)
    st.session_state.playlist_names.append(playlist_name)

playlist_to_df(playlist)

Method transforms playlist information in dictionary form to a playlist dataframe Args: playlist (dict): Playlist information in a dictionary, keys are features and values are a list.

Returns:

Type Description
DataFrame

A playlist dataframe.

Source code in src/recommender.py
141
142
143
144
145
146
147
148
149
150
def playlist_to_df(playlist: dict):
    """Method transforms playlist information in dictionary form to a playlist dataframe
    Args:
        playlist (dict): Playlist information in a dictionary, keys are features and values are a list.

    Returns:
        (DataFrame): A playlist dataframe.
    """
    target_df = pd.DataFrame.from_dict(playlist)
    return target_df

retrieve_feature_defs()

Method retrieves the feature definitions from the data/feature_def.txt file.

Returns:

Type Description
str

The contents of the feature_def.txt file.

Source code in src/recommender.py
194
195
196
197
198
199
200
201
202
203
204
def retrieve_feature_defs():
    """Method retrieves the feature definitions from the `data/feature_def.txt` file.

    Returns:
        (str): The contents of the `feature_def.txt` file.
    """
    root_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
    file_path = os.path.join(root_path, 'data', 'feature_def.txt')
    with open(file_path, 'r') as file:
        contents = file.read()
        return contents

retrieve_target_playlist(url, name)

This method gathers all the playlist song features and merges this data into the tracks dataset.

Note: credentials are stored using Streamlit secrets keeper

Parameters:

Name Type Description Default
url str

The url for the spotify playlist

required
name str

The name of the spotify playlist

required

Returns: playlist (DataFrame): The playlist features as a DataFrame

Source code in src/recommender.py
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
def retrieve_target_playlist(url: str, name: str):
    """ This method gathers all the playlist song features and merges this data into the tracks dataset.

        Note: credentials are stored using Streamlit secrets keeper

    Args:
        url (str): The url for the spotify playlist
        name (str): The name of the spotify playlist
    Returns:
        playlist (DataFrame): The playlist features as a DataFrame
    """
    client_credentials_manager = SpotifyClientCredentials(client_id=st.secrets['CLIENT_ID'],
                                                          client_secret=st.secrets[
                                                              'CLIENT_SECRET'])  # Set up Spotify Credentials
    sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
    playlist = target_playlist_extraction(sp, url, name)  # Generate target playlist dataframe
    save_data(playlist)  # Save the playlist tracks into the larger tracks dataset
    playlist_df = playlist_to_df(playlist)
    return playlist_df

search_history_section()

This method creates the search history section of the Streamlit application.

This section provides a drop-down that displays the search history in the from playlist name | playlist url

Source code in src/recommender.py
29
30
31
32
33
34
35
36
37
38
39
40
def search_history_section():
    """This method creates the search history section of the Streamlit application.

    This section provides a drop-down that displays the search history in the from
    playlist name | playlist url
    """
    with st.expander("Search History", expanded=False):
        if len(st.session_state.playlist_links) == 0:
            st.markdown('No search history yet...')
        else:
            for name, url in zip(st.session_state.playlist_names, st.session_state.playlist_links):
                st.write(name + " | " + url)

search_results_section()

This methods creates the search results section in the Streamlit app.

This can be broken down into two sub-sections. 1. Spotify Recommendations 2. The similarity visualization

Note, if no playlist or name is given, this section is replaced by a Please perform search first message

Source code in src/recommender.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
def search_results_section():
    """This methods creates the search results section in the Streamlit app.

    This can be broken down into two sub-sections.
    1. Spotify Recommendations
    2. The similarity visualization

    Note, if no playlist or name is given, this section is replaced by a `Please perform search first` message
    """
    st.header('Search Results')
    if st.session_state.similarity is None:
        st.write('Please perform a search first')
    else:
        # Recommended Results
        display_spotify_recommendations()

        # Similarity visualization
        fig_1 = similarity_visualization()
        st.pyplot(fig_1)

similarity_visualization()

This method creates the similarity visualization of the dataset tracks to the created dataset feature vector.

Returns:

Type Description
Pyplot Figure

Figure for visualization by Streamlit

Source code in src/recommender.py
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
def similarity_visualization():
    """This method creates the similarity visualization of the dataset tracks to the created dataset feature vector.

    Returns:
        (Pyplot Figure): Figure for visualization by Streamlit
    """
    df = pd.DataFrame(st.session_state.similarity.access_similarity_scores(),
                           columns=['sim_score'])  # Access similarity scores of the process

    st.markdown("#### Playlist Similarity to Track Dataset")
    sns.set_style('whitegrid')
    fig, axes = plt.subplots(1, 1, figsize=(12, 4))

    g = sns.histplot(data=df,
                     x='sim_score',
                     kde=True,
                     color='red',
                     ax=axes)

    axes.set_yscale('log')
    axes.set_xscale('log')
    axes.set_xlabel('Similarity Values (Log)')
    axes.set_ylabel('Frequency')
    return fig