

映画のデータセットであるMovielensについて、KNN法を用いて解析をしていたところエラーが出てしまいました。エラーメッセージの意味がよくわからず、解説と解決策のご教授をお願いしたいです。このエラーが出ない映画タイトルもあります。  
ソースコード

[code]

    def get_movie_recommendation(movie_name):
    n_movies_to_reccomend = 2
    movie_list = movies[movies['title'].str.contains(movie_name)]  
    if len(movie_list):        
        movie_idx= movie_list.iloc[0]['movieId']
        movie_idx = final_dataset[final_dataset['movieId'] == movie_idx].index[0]
        distances , indices = knn.kneighbors(csr_data[movie_idx],n_neighbors=n_movies_to_reccomend+1)    
        rec_movie_indices = sorted(list(zip(indices.squeeze().tolist(),distances.squeeze().tolist())),key=lambda x: x[1])[:0:-1]
        recommend_frame = []
        for val in rec_movie_indices:
            movie_idx = final_dataset.iloc[val[0]]['movieId']
            idx = movies[movies['movieId'] == movie_idx].index
            recommend_frame.append({'Title':movies.iloc[idx]['title'].values[0],'Distance':val[1]})
        df = pd.DataFrame(recommend_frame,index=range(1,n_movies_to_reccomend+1))
        return df
    else:
        return "No movies found. Please check your input"
    
[/code]

エラーメッセージ  
[![画像の説明をここに入力](https://i.stack.imgur.com/FTPLE.jpg)](https://i.stack.imgur.com/FTPLE.jpg)


CC BY-SA 4.0
2023-01-23T05:16:25.543
93517
2023-01-25T14:47:32.557
56418
question
python numpy 機械学習
index 0 is out of bounds for axis 0 with size 0


参考にされたコードは [Create Your Own Movie Movie Recommendation
System](https://www.analyticsvidhya.com/blog/2020/11/create-your-own-movie-
movie-recommendation-system/) と推測し，そこからコードを集めて確かめてみると `'Iron Man'`
ではエラーは生じませんが `'First Daughter'` では同様のエラーが生じます。

[code]

    import pandas as pd
    from scipy.sparse import csr_matrix
    from sklearn.neighbors import NearestNeighbors
    
    
    def get_movie_recommendation(movie_name):
        n_movies_to_recommend = 2
        movie_list = movies[movies['title'].str.contains(movie_name)]
    
        if len(movie_list):
            movie_idx = movie_list.iloc[0]['movieId']
            movie_idx = final_dataset[final_dataset['movieId'] == movie_idx].index[0]
            distances, indices = knn.kneighbors(
                csr_data[movie_idx], n_neighbors=n_movies_to_recommend+1)
            rec_movie_indices = sorted(
                list(zip(indices.squeeze().tolist(), distances.squeeze().tolist())),
                key=lambda x: x[1])[:0:-1]
    
            recommend_frame = []
            for val in rec_movie_indices:
                movie_idx = final_dataset.iloc[val[0]]['movieId']
                idx = movies[movies['movieId'] == movie_idx].index
                recommend_frame.append({'Title': movies.iloc[idx]['title'].values[0],
                                        'Distance': val[1]})
    
            df = pd.DataFrame(recommend_frame,
                              index=range(1, n_movies_to_recommend+1))
            return df
        else:
            return "No movies found. Please check your input"
    
    
    movies = pd.read_csv('ml-latest-small/movies.csv')
    ratings = pd.read_csv('ml-latest-small/ratings.csv')
    final_dataset = ratings.pivot(index='movieId', columns='userId',
                                  values='rating').fillna(0)
    
    no_user_voted = ratings.groupby('movieId')['rating'].agg('count')
    no_movies_voted = ratings.groupby('userId')['rating'].agg('count')
    final_dataset = final_dataset.loc[no_user_voted[no_user_voted > 10].index, :]
    final_dataset = final_dataset.loc[:, no_movies_voted[no_movies_voted > 50].index]
    
    csr_data = csr_matrix(final_dataset.values)
    final_dataset.reset_index(inplace=True)
    
    knn = NearestNeighbors(metric='cosine', algorithm='brute',
                           n_neighbors=20, n_jobs=-1)
    knn.fit(csr_data)
    
    # print(get_movie_recommendation('Iron Man'))
    print(get_movie_recommendation('First Daughter'))
    
[/code]

エラーの内容からすると `'First Daughter'` がタイトルに含まれる `movies` の行（映画） が `final_dataset`
には存在しないのでエラーが生じているようです。改めてコードを確認すると（データのノイズを減らすため） `final_dataset`
を行（映画）単位で絞っている下記の記述がありましたので，これをコメントアウトすると `'First Daughter'` でもエラーは生じなくなりました。

[code]

    final_dataset = final_dataset.loc[no_user_voted[no_user_voted > 10].index, :]
    
[/code]

逆に，（上記をコメントアウトせずに）下記に示すように `movies` を `final_dataset`
と同じ条件で絞ってもエラーは生じなくなります。ただし，`'First Daughter'` の場合は `movies`
のタイトルから見つけられなくなります。

[code]

    movies.set_index('movieId', inplace=True)
    movies = movies.loc[no_user_voted[no_user_voted > 10].index, :]
    movies.reset_index(inplace=True)
    
[/code]

なお，今回の件とは関係ありませんが距離がより近い映画を上位に推薦する方が自然なので下記のように変更したくなります。

[code]

                # key=lambda x: x[1])[:0:-1]
                key=lambda x: x[1])[1:n_movies_to_recommend+1]
    
[/code]


CC BY-SA 4.0
2023-01-25T14:47:32.557
93562
2023-01-25T14:47:32.557
54588
93517
answer