# **Music Recommendation System**
**[<ins>Hệ thống đề xuất</ins>](https://viblo.asia/p/gioi-thieu-ve-he-thong-goi-y-recommender-systems-hoac-recommendation-systems-1Je5EALG5nL) nhạc dựa vào sở thích cùa người dùng - User-based Collaborative Filtering:**
- **Thành viên:**
- Phạm Hoàng Phúc (AFK)
- Phan Đình Minh Quân
- Huỳnh Chí Tài
- Nguyễn Hoàng Phúc Thịnh
- Vũ Công Minh Triết
# **I. Khái Niệm**
- Đề xuất nhạc theo sở thích của người dùng sử dụng [User-based Collaborative Filtering](https://www.geeksforgeeks.org/user-based-collaborative-filtering/) là một kỹ thuật dựa trên việc tìm kiếm sự tương đồng giữa các người dùng để đưa ra các đề xuất.
- Trong User-based Collaborative Filtering, chúng ta tìm kiếm những người dùng có sở thích tương tự và đề xuất những mục mà những người dùng tương tự đó thích[[1]](https://www.geeksforgeeks.org/user-based-collaborative-filtering). Hệ thống này không sử dụng các đặc điểm của mục để đề xuất, mà phân loại người dùng thành các cụm tương tự và đề xuất cho mỗi người dùng dựa trên sở thích của cụm của họ[[1]](https://www.geeksforgeeks.org/user-based-collaborative-filtering).
- Cụ thể, hệ thống này hoạt động bằng cách tìm kiếm một nhóm lớn người và tìm ra một tập hợp nhỏ hơn các người dùng có sở thích tương tự với một người dùng cụ thể[[2]](https://www.geeksforgeeks.org/user-based-collaborative-filtering). Nó xem xét các mục mà họ thích và kết hợp chúng để tạo ra một danh sách đề xuất được xếp hạng[[2]](https://www.geeksforgeeks.org/user-based-collaborative-filtering). Có nhiều cách để quyết định người dùng nào tương tự và kết hợp lựa chọn của họ để tạo ra một danh sách đề xuất[[2]](https://www.geeksforgeeks.org/user-based-collaborative-filtering).
- Hệ thống đề xuất này có thể đề xuất một mục cho người dùng A dựa trên sở thích của người dùng B tương tự[[3]](https://developers.google.com/machine-learning/recommendation/collaborative/basics?hl=vi). Điều này cho phép các đề xuất bất ngờ; tức là, các mô hình lọc cộng tác có thể đề xuất một mục cho người dùng A dựa trên sở thích của người dùng B tương tự[[3]](https://developers.google.com/machine-learning/recommendation/collaborative/basics?hl=vi). Ví dụ, nếu một người dùng thích một loạt các cuốn sách khoa học viễn tưởng, hệ thống có thể đề xuất thêm các cuốn sách trong thể loại này dựa trên đánh giá của người dùng khác có sở thích tương tự. Hoặc nếu một người dùng thường mua sách của một tác giả cụ thể, hệ thống có thể đề xuất các cuốn sách khác của tác giả đó.

# **II. Lí Do Chọn Đề Tài**
Cũng giống như hệ thống đề xuất phim, đồ dùng, đồ ăn,... hệ thống đề xuất nhạc ra đời mang lại nhiều lợi ích:
1. Tăng trải nghiệm cá nhân hóa: Hệ thống đề xuất giúp tạo ra trải nghiệm cá nhân hóa cho người dùng bằng cách hiển thị nội dung phù hợp với sở thích và hành vi của họ.
2. Tăng khả năng tương tác: Khi người dùng thấy nội dung phù hợp với sở thích của mình, họ có nhiều khả năng tương tác hơn, dẫn đến việc tăng khả năng giữ chân người dùng và thời gian họ dành trên nền tảng.
3. Tối ưu hóa quảng cáo: Hệ thống đề xuất giúp các nhà quảng cáo hiển thị quảng cáo phù hợp với người dùng, tăng khả năng người dùng tương tác với quảng cáo và tăng hiệu quả quảng cáo.
4. Khám phá nội dung mới: Hệ thống đề xuất giúp người dùng khám phá nội dung mới mà họ có thể quan tâm nhưng chưa biết đến.
5. Tăng doanh thu: Bằng cách tăng khả năng tương tác và tối ưu hóa quảng cáo, hệ thống đề xuất cũng giúp tăng doanh thu cho các nền tảng trực tuyến.
Vì vậy, hệ thống đề xuất theo sở thích của người dùng đóng vai trò quan trọng trong việc tạo ra trải nghiệm người dùng tốt hơn và tăng doanh thu cho các nền tảng trực tuyến.
# **III. Tổng Quan Về Dự Án**
#### **1. Bộ Dữ Liệu**
**Bối Cảnh**
Trong vài thập kỷ qua, với sự phát triển của Youtube, Amazon, Facebook, Netflix và nhiều dịch vụ web khác, hệ thống đề xuất ngày có mặt nhiều hơn trong cuộc sống của chúng ta. Từ thương mại điện tử (gợi ý cho người mua những bài viết mà họ có thể quan tâm) đến quảng cáo trực tuyến (gợi ý cho người dùng những nội dung phù hợp, phù hợp với sở thích của họ), hệ thống đề xuất ngày nay là điều không thể tránh khỏi trong cuộc sống online của chúng ta.
Hệ thống đề xuất thực sự quan trọng trong một số ngành vì chúng có thể tạo ra một lượng thu nhập khổng lồ khi chúng hoạt động hiệu quả hoặc cũng là một cách để nổi bật hơn so với các đối thủ cạnh tranh. Để chứng minh tầm quan trọng của hệ thống đề xuất, chúng ta có thể đề cập rằng, vài năm trước, Netflix đã tổ chức một thử thách (“Netflix prize”) với mục tiêu là tạo ra một hệ thống đề xuất hoạt động tốt hơn thuật toán của chính họ với giải thưởng 1M$ khi giành chiến thắng.

**Nội Dung**
Bộ dữ liệu này bao gồm có 5 file: [<ins>Tải ở đây</ins>](https://www.kaggle.com/datasets/vatsalmavani/spotify-dataset/download?datasetVersionNumber=1)
Các biến được sử dụng trong tập dữ liệu:
- **Years**: năm bài hát được sáng tác.
- **Acousticness**: độ "acoustic" của một bài hát.
- **Genres**: thể loại của bài hát.
- **Artists**: tác giả cuả bài hát.
- **Danceability**: mức độ mà người dùng có thể "vibe" theo hoặc nhảy theo bài hát.
- **Duration**: độ dài của bài hát.
- **Energy**: độ sôi động của bài hát.
- **Valence**: độ vui hay buồn của một bài nhạc, càng gần 1 thì càng vui và ngược lại càng gần 0 thì càng buồn.
- **Explicit**: bài hát có chứa những từ ngữ hoặc nội dung thô tục với 1 là có và 0 là không có.
- **Id**: id của bài hát.
- **Liveness**: độ sống động của bài hát.
- **Loudness**: độ mạnh yếu của âm thanh dựa trên cảm nhận bản thân.
- **Name**: tên của bài hát.
- **Popularity**: độ nổi tiếng của bài hát.
- **Release_date**: năm mà bài hát ra đời.
- **Speechiness**: mức độ, tần suất các câu từ xuất hiện trong bài hát.
- **Instrumentalness**: ngược lại với speechiness, mức độ hoặc tần suất của các nhạc cụ xuất hiện trong bài hát.
- **Tempo**: tốc độ mà bài hát được phát (có thể hiểu như bpm).
#### **2. Thuật toán được áp dụng**
Thuật toán K-mean di chuyển lặp đi lặp lại các hạt nhân để giảm thiểu tổng số trong phương sai cụm.
#### **3. Các thư viện được sử dụng**
Numpy - Thư viện trong Python mã nguồn mở chủ yếu được sử dụng để thao tác và xử lý dữ liệu dưới dạng mảng.
Pandas - Thư viện Python cung cấp các cấu trúc dữ liệu nhanh, mạnh mẽ, linh hoạt.
Seaborn - Thư viện vẽ biểu đồ dựa trên Matplotlib, được thiết kế để giúp người dùng vẽ các biểu đồ phức tạp một cách dễ dàng hơn.
Plotly - Thư viện đồ họa tương tác, mã nguồn mở, và dựa trên nền tảng trình duyệt.
Scikit-learn - Thư viện hỗ trợ các thuật toán hiện đại như KNN, XGBoost, random forest, SVM và một số thuật toán khác:
```python
import os
import numpy as np
import pandas as pd
import seaborn as sns
import plotly.express as px
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.manifold import TSNE
from sklearn.decomposition import PCA
from sklearn.metrics import euclidean_distances
from scipy.spatial.distance import cdist
```
(*Lệnh nhập các thư viện*)
# **IV. Cấu trúc dữ liệu**
1. Nhạc qua thời gian
``` python
def get_decade(year):
period_start = int(year/10) * 10
decade = '{}s'.format(period_start)
return decade
data['decade'] = data['year'].apply(get_decade)
sns.set(rc={'figure.figsize':(11 ,6)})
sns.countplot(data['decade'])
```
(*Dựa vào dữ liệu, ta có thể thấy được xu hướng và sự thay đổi của nó trong khoảng thời gian từ 1921 đến 2020*)

```python
sound_features = ['acousticness', 'danceability', 'energy', 'instrumentalness', 'liveness', 'valence']
fig = px.line(year_data, x='year', y=sound_features)
fig.show()
```

2. Đặc điểm của các thể loại nhạc khác nhau
```python
top10_genres = genre_data.nlargest(10, 'popularity')
fig = px.bar(top10_genres, x='genres', y=['valence', 'energy', 'danceability', 'acousticness'], barmode='group')
fig.show()
```
(*Dataset này chứa các đặc trưng âm thanh của các bài hát khác nhau cùng với các đặc trưng âm thanh của các thể loại nhạc khác nhau. Chúng ta có thể sử dụng thông tin này để so sánh các thể loại nhạc và hiểu rõ sự khác biệt độc đáo về âm thanh của chúng*)

# **V. Sản Phẩm**
1. Giao diện sản phẩm

Trang web dễ dàng sử dụng - thân thiện với người dùng. Nhập tên bài hát thích nghe và năm được phát hành. Hệ thống sẽ tự động xuất ra những bài hát "tiệm cận" với sở thích người dùng.

(*Hệ thống cho ra những đề xuất dựa trên ví dụ sở thích của người dùng :"Blinding Lights - 2019"*)
2. Phân cụm các thể loại
```python
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
cluster_pipeline = Pipeline([('scaler', StandardScaler()), ('kmeans', KMeans(n_clusters=10, n_jobs=-1))])
X = genre_data.select_dtypes(np.number)
cluster_pipeline.fit(X)
genre_data['cluster'] = cluster_pipeline.predict(X)
```
(*Ở đây, thuật toán phân cụm K-Means được sử dụng để chia các thể loại nhạc trong dataset này thành mười cụm dựa trên các đặc trưng âm thanh số của từng thể loại*)
``` python
# Trực quan hóa các cụm với t-SNE
from sklearn.manifold import TSNE
tsne_pipeline = Pipeline([('scaler', StandardScaler()), ('tsne', TSNE(n_components=2, verbose=1))])
genre_embedding = tsne_pipeline.fit_transform(X)
projection = pd.DataFrame(columns=['x', 'y'], data=genre_embedding)
projection['genres'] = genre_data['genres']
projection['cluster'] = genre_data['cluster']
fig = px.scatter(
projection, x='x', y='y', color='cluster', hover_data=['x', 'y', 'genres'])
fig.show()
```
[t-SNE] Computing 91 nearest neighbors...
[t-SNE] Indexed 2973 samples in 0.005s...
[t-SNE] Computed neighbors for 2973 samples in 0.322s...
[t-SNE] Computed conditional probabilities for sample 1000 / 2973
[t-SNE] Computed conditional probabilities for sample 2000 / 2973
[t-SNE] Computed conditional probabilities for sample 2973 / 2973
[t-SNE] Mean sigma: 0.777516
[t-SNE] KL divergence after 250 iterations with early exaggeration: 76.115768
[t-SNE] KL divergence after 1000 iterations: 1.392461

3. Phân cụm các bài hát
```python
song_cluster_pipeline = Pipeline([('scaler', StandardScaler()),
('kmeans', KMeans(n_clusters=20,
verbose=False, n_jobs=4))
], verbose=False)
X = data.select_dtypes(np.number)
number_cols = list(X.columns)
song_cluster_pipeline.fit(X)
song_cluster_labels = song_cluster_pipeline.predict(X)
data['cluster_label'] = song_cluster_labels
```
(*Ta biểu diễn dữ liệu với PCA*)
``` python
from sklearn.decomposition import PCA
pca_pipeline = Pipeline([('scaler', StandardScaler()), ('PCA', PCA(n_components=2))])
song_embedding = pca_pipeline.fit_transform(X)
projection = pd.DataFrame(columns=['x', 'y'], data=song_embedding)
projection['title'] = data['name']
projection['cluster'] = data['cluster_label']
fig = px.scatter(
projection, x='x', y='y', color='cluster', hover_data=['x', 'y', 'title'])
fig.show()
```

```python
def recommend_songs( song_list, spotify_data, n_songs=10):
metadata_cols = ['name', 'year', 'artists']
song_dict = flatten_dict_list(song_list)
song_center = get_mean_vector(song_list, spotify_data)
scaler = song_cluster_pipeline.steps[0][1]
scaled_data = scaler.transform(spotify_data[number_cols])
scaled_song_center = scaler.transform(song_center.reshape(1, -1))
distances = cdist(scaled_song_center, scaled_data, 'cosine')
index = list(np.argsort(distances)[:, :n_songs][0])
rec_songs = spotify_data.iloc[index]
rec_songs = rec_songs[~rec_songs['name'].isin(song_dict['name'])]
return rec_songs[metadata_cols].to_dict(orient='records')
```
(*Gợi ý các bài hát tương tự với danh sách bài hát nhất định. Độ tương tự được xác định dựa trên dữ liệu Spotify - Sử dụng cosin để đo độ tương tự. Chức năng này cũng đảm bảo rằng nó không đề xuất bất kỳ bài hát nào đã có trong danh sách đầu vào, mỗi lần cung cấp cho người dùng những đề xuất mới*)
# **VI. Tổng Kết**
Dựa trên phân tích và hình ảnh hóa, rõ ràng các thể loại tương tự có những điểm dữ liệu nằm gần nhau và các loại bài hát tương tự cũng được nhóm lại cùng nhau.
Quan sát này hoàn toàn hợp lý. Các thể loại tương tự sẽ có xu hướng tương tự và đến từ cùng khoảng thời gian, tương tự như vậy cũng có thể nói với các bài hát trong các thể loại đó. Chúng ta có thể sử dụng ý tưởng này để xây dựng một hệ thống gợi ý bằng cách lấy các điểm dữ liệu của những bài hát mà người dùng đã nghe và gợi ý những bài hát tương ứng với các điểm dữ liệu gần kề.
Spotipy là một thư viện Python cho phép gọi API Web của Spotify, giúp cho nhà phát triển dễ dàng truy xuất dữ liệu và truy vấn danh mục bài hát của Spotify. Bạn cần cài đặt Spotipy bằng cách sử dụng lệnh pip install spotipy.
Sau khi cài đặt Spotipy, bạn sẽ cần tạo một ứng dụng trên trang web Spotify Developer và lưu lại Client ID của bạn.
:::success
Ưu điểm:
1. Tăng mức độ tương tác và tỷ lệ giữ chân người dùng;
2. Thúc đẩy doanh số bán hàng;
3. Cá nhân hoá và tiết kiệm thời gian;
:::
:::danger
Nhược điểm:
1. Độ chính xác và độ tin cây còn thấp;
2. Vấn đề quyền riêng tư;
3. Vấn đề về độ trễ trong cập nhập xu hướng
:::
:::info
Ứng dụng của chương trình đề xuất nhạc là giúp người dùng khám phá và khám phá những bài hát mới dựa trên sở thích âm nhạc của họ. Bằng cách phân tích dữ liệu âm nhạc và tạo ra các mô hình dự đoán, chương trình có thể xác định những bài hát tương tự và nhóm chúng lại với nhau. Khi người dùng nghe một bài hát nào đó, chương trình sẽ sử dụng thông tin đó để tìm kiếm các bài hát tương tự và đề xuất chúng cho người dùng. Điều này giúp mở rộng phạm vi nghe nhạc của người dùng, mang lại trải nghiệm âm nhạc đa dạng và thú vị hơn. Chương trình đề xuất nhạc có thể được tích hợp vào các ứng dụng nghe nhạc hiện có hoặc được sử dụng như một ứng dụng độc lập để mang đến những gợi ý âm nhạc cá nhân hóa và đáp ứng nhu cầu âm nhạc độc đáo của mỗi người. :notes:
:::
### Thanks For Reading!