4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

記事投稿キャンペーン 「AI、機械学習」

楽曲レコメンドアプリ作ってみた!

Last updated at Posted at 2023-11-08

はじめに

Streamlitで楽曲レコメンドアプリを作成しました。データセットはKaggleで公開されているものを利用しました。
Streamlit Cloudで公開しています。

データセットの加工

データセットにはKaggleで公開されているものを利用しました。KKBOXという音楽レコメンドサービスのデータセットでいくつかのcsvファイルに分割されて提供されています。今回はすべてのデータセットを結合した後にレコメンドに使いたいカラムを抽出して加工しました。また、データセットのlanguageカラムを日本語に指定して、日本の楽曲に限定しています。

data_process.py
import pandas as pd

train = pd.read_csv('/train.csv')
songs = pd.read_csv('/songs.csv')
members = pd.read_csv('/members.csv')
song_ex = pd.read_csv('/song_extra_info.csv')

merge1 = pd.merge(train, songs, on = 'song_id', how = 'left')
merge2 = pd.merge(merge1, members, on = 'msno', how = 'left')
origin_data = pd.merge(merge2, song_ex, on = 'song_id', how = 'left')
del train, songs, members, song_ex, merge1, merge2

origin_data.isnull().sum()
features = ['msno', 'name', 'language', 'artist_name', 'composer', 'lyricist']

origin_data['language'].unique()

data = origin_data[features].dropna()

# language = 17.0 が日本語
j_song = data[data['language'] == 17.0]
jp_song = j_song.copy()

jp_data = jp_song.drop('language', axis=1)
jp_data = jp_data.rename(columns={'msno': 'user_id', 'name': 'song_name'})

# '\u3000'(全角スペースの文字コード)を半角スペースで置換
jp_data['song_name'] = jp_data['song_name'].str.replace('\u3000', ' ')
jp_data['song_name'] = jp_data['song_name'].str.replace('\|', '')
jp_data['artist_name'] = jp_data['artist_name'].str.replace('\u3000', ' ')
jp_data['composer'] = jp_data['composer'].str.replace('\u3000', ' ')
jp_data['lyricist'] = jp_data['lyricist'].str.replace('\u3000', ' ')


music_data = jp_data.drop('user_id', axis=1)
music_data = music_data.drop_duplicates().sort_values('song_name').reset_index(drop=True)

# ファイル出力
# jp_data.to_csv('data.csv', index=False)

# アプリで4種類から選択できるようにする
song_name = sorted(list(set(jp_data['song_name'].tolist())))
artist = sorted(list(set(jp_data['artist_name'].tolist())))
composer = sorted(list(set(jp_data['composer'].tolist())))
lyricist = sorted(list(set(jp_data['lyricist'].tolist())))

# userが聞いた曲
unique = jp_data.groupby('user_id').agg({'song_name': list})
listened_list = unique['song_name'].tolist()

result = []
for i in range(len(listened_list)):
  if song_name[0] in listened_list[i]:
    if len(listened_list[i]) >=  2:
      result += listened_list[i]
print(result)

import collections
c = collections.Counter(result)
values, counts = zip(*c.most_common(3))
print(values, counts)

recommend_df = pd.DataFrame()
for j in range(len(values)):
  recommend_info = music_data[music_data['song_name'].isin([values[j]])]
  df_new = pd.DataFrame(recommend_info)
  recommend_df = pd.concat([recommend_df, df_new])

実装

私自身が初心者だったのではじめから目標物を完成させることは意識せずに、とりあえずアプリの大枠を作成し、随時機能を追加していくという方針で進めていきました。
レコメンド方法は概要レコメンドで自分が聞いた曲を聞いた他のユーザーはどんな曲を聞いているか推薦する仕組みです。
スクリーンショット 2023-11-08 20.33.35.png
実装部分を載せると記事が見にくくなると思ったので気になる方はStreamlit CloudのGitHubアイコンからご覧ください。

頑張ったこと

今回が初めてのWebアプリ作成でAPIも使ってみたいと思い、Youtube Data APIを使用しました。
レコメンドされた楽曲のYoutube上で個々に割り振られているvideo IDをAPIから取得し、そのvideo IDをURLに結合して楽曲に関連した動画にアクセスできるようにしました。
image.png

良くない点

データセットが海外のもので日本の楽曲に絞り込んでも中国語表記だったり、半角スペースの有無で楽曲がダブったり、曲名がローマ字表記だったり、など楽曲を選択するところ場面でUXが悪いと感じています。

最後に

初心者にしては実際に動くものを作れてこれがプログラミングの醍醐味かと感銘しています。知識のインプットばかりするのではなく、なにか作ることを目的に設定して、インプットしていけばアウトプットにもなるし、と改めて学習方法を考え直すきっかけになりました。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?