pandasは遅い!大量データの高速化、最適化のノウハウを公開!

pandasは、条件を指定してデータを取り出したりするのに便利なライブラリです。

しかし、kaggleのコンペのように1億レコード(行)もある大量データだと、メモリ不足に陥ったり、処理速度が遅くなることがあります。

pandasの高速化について記事化したいと思います!

\IT未経験者からのサポートあり!転職サービス5選!!/

サービス名
未経験 未経験OK 未経験OK 未経験OK 経験者向け 経験者向け
公開の求人数 情報なし ITエンジニア全体で35695件
ITエンジニア未経験で4000件
ITエンジニア全体で1万件以上
ITエンジニア未経験で600件以上
5,000件以上 2500件以上
利用対象 IT未経験者に特化 全職種 全職種 IT特化 ゲーム特化
特徴 ✓IT未経験者に特化した就職サポート
✓IT学習(無料のYoutube動画)のサポートあり
✓転職エージェントが伴走
✓求人数が多い
✓誰もが知る転職サービス
✓経歴を登録しておくとオファーが来る
✓IT専門のエージェントが対応
✓転職成功すると年収200万円以上の大幅アップがある
✓ゲーム転職に強い
✓有名ゲーム会社との取引が多い
公式サイト ウズキャリIT リクルートエージェント リクナビネクスト レバテックキャリア シリコンスタジオ

メモリ容量の最適化

 

pandasにread_csvだけでデータを読み込むだけでは、無駄な領域まで使ってしまい、すぐにメモリ不足に陥ります。

 

ここでは、pandasにおいてできるかぎり少ないメモリ容量で処理できる方法を書きます。

 

大前提として、使用しないメモリ(変数)が出てきたら、その都度、delで解放していきます。

 

 

データに対して型を宣言する

単純にpandasにread_csvしただけでは、最もデータ領域を使う型が選択されてしまいます。たとえば、int系だとint64が使われてしまいます。

数値の範囲が、127までの場合、int16で足りるのに、int64を使っていたら無駄な領域使うことになります。

 

こんなときは、型を定義して、「astype」関数を組み合わせるなどして、メモリ容量を減らすことを検討します。

 

コードの例は以下の通りです。

 

data_types_dict = {
    'timestamp': 'int64',
    'user_id': 'int32', 
    'content_id': 'int16', 
    'content_type_id':'int8', 
    'task_container_id': 'int16',
    'user_answer': 'int8',
    'answered_correctly': 'int8', 
    'prior_question_elapsed_time': 'float32', 
    'prior_question_had_explanation': 'bool'
}

#データは以下からダウンロードしてください
#https://www.kaggle.com/c/riiid-test-answer-prediction/data
train_df = pd.read_csv('./riiid-test-answer-prediction/train.csv',nrows = 1000000)

#型を宣言しないと、無駄にメモリを使う(例:本来int8で足りるのに、int64で確保される)のでしっかり型宣言しておく
train_df = train_df.astype(data_types_dict)

 

関数を作りメモリ容量を最適化する処理をする

 

以下のような関数を使ってメモリ容量を最適化します。

 

'''Function to reduce the DF size'''
# source: https://www.kaggle.com/kernels/scriptcontent/3684066/download

def reduce_mem_usage(df):
    """ iterate through all the columns of a dataframe and modify the data type
        to reduce memory usage.        
    """
    start_mem = df.memory_usage().sum() / 1024**2
    print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))
    
    for col in df.columns:
        col_type = df[col].dtype
        
        if col_type != object:
            c_min = df[col].min()
            c_max = df[col].max()
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)  
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)
        else:
            df[col] = df[col].astype('category')

    end_mem = df.memory_usage().sum() / 1024**2
    print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))
    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))
    
    return df


 

関数は、カグラーさんが作ってくれたもの(作成者が、kaggleから居なくなってしまった?)を使わせて頂きます。

 

 

本当にすべて必要か検討する

Kaggleの「Riiid Answer Correctness Prediction」コンペでは、1億レコードもあるデータセットを使います。

データ全てを使用して訓練させる必要はあるのでしょうか?

 

1億レコードの全てを使用する必要があるのかどうかを検討します。

コンペでは、1000万レコードほどで上位に行った人もいるので、全て使用する必要も無いと言えます。

 

分割してデータを渡して機械学習させる

 

機械学習アルゴリズムによっては、一度にデータを渡す物では無く、分割して渡すことができるものがあります(例:ニューラルネットワーク=NN系)。

そんなときは、ファイルからある程度読み込むことを検討します。

 

以下のようなイメージです。

  1. ファイル全体から1/10(先頭から)ほどのデータをメモリに読み込む
  2. 学習モデルに渡して学習
  3. ファイル全体から次の1/10ほどのデータをメモリに読み込む
  4. 学習モデルに渡して学習

 

 

実装例あり!pandasの処理の高速化

 

pandasが、データ容量が多くなると処理遅くなりがちです。

特に、for文でデータの参照をするとものすごく遅くなってしまいます。

そこで、改善した方法を記載します。

 

改善方法は以下の通り

やりたいこと 方法 かかった時間
pandasのデータ参照 for文にてpandasのiterrowsで参照 1分1秒
pandasのデータ参照 for文にてpandasから配列に変換して参照 753ミリ秒
pandasのデータ更新 for文にてpandasのiterrowsで参照
更新は、pandas.atで更新する
1分25秒
pandasのデータ更新 for文にてpandasから配列に変換して参照
更新は、pandas.atで更新する
16秒
pandasのデータ更新 for文にてpandasから配列に変換して参照
更新は、一旦更新元のデータを配列に格納して、for文抜けたあとで更新
979ミリ秒

次に実装例を示します。

 

 

独学で挫折した人向け・AI(機械学習)を短期間で学ぶ方法

独学で挫折してしまった
本買ったり、YoutubeでAIを勉強していたんだけど、結局から何を勉強してよいかわからず挫折してしまったんだ。どうしたら解消できる?

 

独学で挫折してしまった人向けに、PythonとAI(機械学習)について、短期間で効率的に学ぶ方法を紹介します。

それは、以下のようなサービス、プログラミングスクールを利用することです。

プログラミングスキルを習得している人でも機械学習の習得は、難しいため、独学で迷うよりは、プロに教えてもらったほうが遥かに最短経路で身につけることができます。

\AI(機械学習)を学べるプログラミングスクール5選/

イメージ スクール名 学べる内容 受講形式 特徴 料金めやす オススメする人
.Pro(ドットプロ) WEB開発
機械学習(AI)
教室授業 ✔教室による対面授業
✔WEB開発と同時にAIも学べる

AI×Django コース
24週間
¥517,800円

✔仲間と一緒に学びたい
✔AIありのWEBシステムを作りたい
Aidemy Premium Plan WEB開発
機械学習(AI)
オンライン ✔申し込んだ講座以外のカリキュラムも学べる
✔給付金制度を利用して最大70%支給あり

AIアプリ開発講座
12週間
¥528,000円

✔AI(機械学習)について広く学びたい
✔給付金を利用して実質70%引きで学びたい

AIジョブカレ 機械学習(AI)
数学、統計学
教室授業、オンライン ✔10万円台から受講可能
✔数学や統計学を学びたい人向けの講座あり

機械学習講座
16週間
¥132,000円

✔Python,数学、統計学など基礎から学びたい
✔授業形式で講師から学びたい
✔受講料を抑えたい
テックアカデミー WEB開発
機械学習(AI)
Unityでゲーム開発
オンライン ✔AI以外にPHP,Unity,C言語など、主要な言語を学べる
✔料金が10万円代から

Python+AIコース
8週間
¥316,800円

✔AI(機械学習)以外にも学びたいものがある
✔できる限り安い金額で学びたい
✔マイペースで学びたい
侍エンジニア 機械学習(AI)
ブロックチェーン
オンライン ✔現役エンジニアが入学から最後まで寄り添ってサポート
✔ブロックチェーンも学べる
AIコース
12週間〜
¥698,000〜
✔マンツーマンで教えてほしい
✔ポートフォリオのサポートが欲しい
✔ブロックチェーンにも興味がある

>>より詳しく5つのスクールについて知りたい方は、以下をクリック!

 

 

まとめ

最近は、データ容量が多いコンペが増えてきました。

今後も大量データの処理のスキルも必要になってくるといえます。

 

 

 

AI(機械学習)が学べるスクールを講座ごとに一覧表示!

さらに、比較表を活用することにより、細かい特徴が違いが一発でわかります。

AIスキルを身に付けて、市場価値が高いエンジニアを目指しましょう!

 

AIスクールの検索、比較ができるペン太ブル本家

最新情報をチェックしよう!
>プログラミングスクール検索・比較表サイト

プログラミングスクール検索・比較表サイト

ワンクリック、さらに詳細に条件を指定してプログラミングスクールの検索ができます。さらに比較表により特徴を細かく比較できる!

CTR IMG