機械学習やディープラーニング、データの可視化をしたいときに、データの中に欠損値があってうまく動かない時があります。
そんな時には、データのクリーニングや前処理を行う必要があります。
この記事ではその方法をご紹介します。
目次
使用するデータ
サンプルデータとして映画のデータを読み込み、カラム名をみてみます。
df = pd.read_csv("movie_metadata.csv") print("colomns name: ",df.columns.values)
colomns name: ['color' 'director_name' 'num_critic_for_reviews' 'duration' 'director_facebook_likes' 'actor_3_facebook_likes' 'actor_2_name' 'actor_1_facebook_likes' 'gross' 'genres' 'actor_1_name' 'movie_title' 'num_voted_users' 'cast_total_facebook_likes' 'actor_3_name' 'facenumber_in_poster' 'plot_keywords' 'movie_imdb_link' 'num_user_for_reviews' 'language' 'country' 'content_rating' 'budget' 'title_year' 'actor_2_facebook_likes' 'imdb_score' 'aspect_ratio' 'movie_facebook_likes']
映画のタイトル、俳優の評価、映画の評価、国、公開年、など28のカラムから構成されるデータです。
欠損地の数を数える
各カラムにおける欠損値の合計値は、`isna().sum()`を使って計算できます。
print(df.isna().sum())
color 19 director_name 104 num_critic_for_reviews 50 duration 15 director_facebook_likes 104 actor_3_facebook_likes 23 actor_2_name 13 actor_1_facebook_likes 7 gross 884 genres 0 actor_1_name 7 movie_title 0 num_voted_users 0 cast_total_facebook_likes 0 actor_3_name 23 facenumber_in_poster 13 plot_keywords 153 movie_imdb_link 0 num_user_for_reviews 21 language 12 country 5 content_rating 303 budget 492 title_year 108 actor_2_facebook_likes 13 imdb_score 0 aspect_ratio 329 movie_facebook_likes 0 dtype: int64
各列の合計値を出すには以下のようにします。
print(df.isna().sum().sum())
2698
欠損値が1つでも含まれる行を消す
1つでもNaNが含まれる行を消すには以下のようにします。
clean_df = df.dropna(how='any')
削除前と削除後の行の数をみてみます。
print("original df shape",df.shape) print("cleaned shape",clean_df.shape)
original df shape (5043, 28) cleaned shape (3756, 28)
約1300行が削除されました。
欠損値の置き換え
消すのではなく特定の文字や数値に置き換えるには以下のようにします。
filled_df_0 = df.fillna(value=0)
行数は変わりませんが欠損値が0に置き換わります。
ビニング
ビニングとは、隣り合うデータや画素を一纏めにすることです。
例えば、0~4の間の評価だった場合には一纏めに「低評価」としてしまって良い場合もあります。
print(df[['movie_title', 'imdb_score']][110:120])
映画のタイトルとスコアをみてみましょう。
movie_title imdb_score 110 The Chronicles of Narnia: The Voyage of the Da... 6.3 111 Pearl Harbor 6.1 112 Transformers 7.1 113 Alexander 5.5 114 Harry Potter and the Order of the Phoenix 7.5 115 Harry Potter and the Goblet of Fire 7.6 116 Hancock 6.4 117 I Am Legend 7.2 118 Charlie and the Chocolate Factory 6.7 119 Ratatouille 8.0
このスコアを、だめ(no way)、まぁまぁ(moderate)、良い(good)の三段階の評価にまとめたいと思います。
pandasの`cut()`を使いましょう。
op_labels = ['no way', 'moderate', 'good'] category = [0.,4.,7.,10.] df['imdb_labels'] = pd.cut(df['imdb_score'], labels=op_labels, bins=category, include_lowest=False)
#binning print(df[['movie_title', 'imdb_score', 'imdb_labels']][110:120])
movie_title imdb_score imdb_labels 110 The Chronicles of Narnia: The Voyage of the Da... 6.3 moderate 111 Pearl Harbor 6.1 moderate 112 Transformers 7.1 good 113 Alexander 5.5 moderate 114 Harry Potter and the Order of the Phoenix 7.5 good 115 Harry Potter and the Goblet of Fire 7.6 good 116 Hancock 6.4 moderate 117 I Am Legend 7.2 good 118 Charlie and the Chocolate Factory 6.7 moderate 119 Ratatouille 8.0 good
1番右の列に三段階の評価を表すラベルが追加されました。
おわり。
参考
https://towardsdatascience.com/data-handling-using-pandas-cleaning-and-processing-3aa657dc9418