You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/ja/3-Web-App/1-Web-App/README.md

18 KiB

Webアプリで機械学習モデルを活用する

このレッスンでは、機械学習モデルをトレーニングし、ユニークなデータセットを使用します。それは、過去100年間のUFO目撃情報 であり、NUFORCのデータベースから取得されたものです。

学ぶ内容:

  • トレーニング済みモデルを「ピクル化」する方法
  • Flaskアプリでそのモデルを使用する方法

ートブックを使ってデータをクリーンアップし、モデルをトレーニングする作業を続けますが、さらに一歩進めて、モデルを「実際の環境」で使用する方法を探ります。つまり、Webアプリでの活用です。

これを実現するには、Flaskを使用してWebアプリを構築する必要があります。

講義前のクイズ

アプリを構築する

機械学習モデルを利用するWebアプリを構築する方法は複数あります。Webアーキテクチャは、モデルのトレーニング方法に影響を与える可能性があります。例えば、データサイエンスチームがトレーニングしたモデルをアプリで使用するよう求められるビジネス環境を想像してみてください。

考慮事項

以下のような質問をする必要があります:

  • Webアプリかモバイルアプリか モバイルアプリを構築する場合やIoT環境でモデルを使用する必要がある場合、TensorFlow Liteを使用して、AndroidやiOSアプリでモデルを活用できます。
  • モデルはどこに配置されるのか? クラウドかローカルか?
  • オフライン対応。 アプリはオフラインで動作する必要があるか?
  • モデルのトレーニングに使用された技術は何か? 選択された技術は、使用するツールに影響を与える可能性があります。
    • TensorFlowを使用する場合。 例えば、TensorFlowを使用してモデルをトレーニングする場合、そのエコシステムはTensorFlow.jsを使用してWebアプリでモデルを活用するための変換機能を提供します。
    • PyTorchを使用する場合。 PyTorchのようなライブラリを使用してモデルを構築する場合、ONNX (Open Neural Network Exchange)形式でエクスポートし、Onnx Runtimeを使用してJavaScript Webアプリで活用することができます。このオプションは、Scikit-learnでトレーニングされたモデルを使用する将来のレッスンで探ります。
    • Lobe.aiやAzure Custom Visionを使用する場合。 Lobe.aiAzure Custom VisionのようなML SaaS (Software as a Service)システムを使用してモデルをトレーニングする場合、この種のソフトウェアは、クラウドでオンラインアプリがクエリを実行するためのカスタムAPIを構築するなど、さまざまなプラットフォーム向けにモデルをエクスポートする方法を提供します。

また、ブラウザ内でモデルをトレーニングできるFlask Webアプリ全体を構築することも可能です。これもJavaScript環境でTensorFlow.jsを使用して実現できます。

私たちの目的では、Pythonベースのートブックを使用してきたので、トレーニング済みモデルをートブックからPythonで構築されたWebアプリで読み取れる形式にエクスポートする手順を探ります。

ツール

このタスクには、FlaskとPickleという2つのツールが必要です。どちらもPython上で動作します。

Flaskとは? Flaskはその開発者によって「マイクロフレームワーク」と定義されており、Pythonを使用してWebページを構築するためのテンプレートエンジンを提供します。この学習モジュールを確認して、Flaskを使った構築を練習してください。

Pickleとは? Pickle 🥒はPythonモジュールで、Pythonオブジェクト構造をシリアル化およびデシリアル化します。モデルを「ピクル化」する際には、その構造をシリアル化またはフラット化してWebで使用できるようにします。ただし、Pickleは本質的に安全ではないため、ファイルを「アンピクル化」するよう求められた場合は注意してください。ピクル化されたファイルの拡張子は.pklです。

演習 - データをクリーンアップする

このレッスンでは、NUFORC (The National UFO Reporting Center) によって収集された80,000件のUFO目撃情報を使用します。このデータには、以下のような興味深い目撃情報の説明が含まれています:

  • 長い説明の例。 「夜の草原に光のビームが照らされ、そこから男性が現れ、テキサスインスツルメンツの駐車場に向かって走る」
  • 短い説明の例。 「光が私たちを追いかけてきた」

ufos.csvスプレッドシートには、目撃が発生したcitystatecountry、物体のshape、およびそのlatitudelongitudeに関する列が含まれています。

このレッスンに含まれる空白のノートブックで以下を行います:

  1. 前のレッスンで行ったようにpandasmatplotlibnumpyをインポートし、UFOスプレッドシートをインポートします。サンプルデータセットを確認できます:

    import pandas as pd
    import numpy as np
    
    ufos = pd.read_csv('./data/ufos.csv')
    ufos.head()
    
  2. UFOデータを新しいタイトルで小さなデータフレームに変換します。Countryフィールドのユニークな値を確認してください。

    ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']})
    
    ufos.Country.unique()
    
  3. 必要なデータ量を減らすために、null値を削除し、1〜60秒間の目撃情報のみをインポートします:

    ufos.dropna(inplace=True)
    
    ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)]
    
    ufos.info()
    
  4. Scikit-learnのLabelEncoderライブラリをインポートして、国名のテキスト値を数値に変換します:

    LabelEncoderはデータをアルファベット順にエンコードします

    from sklearn.preprocessing import LabelEncoder
    
    ufos['Country'] = LabelEncoder().fit_transform(ufos['Country'])
    
    ufos.head()
    

    データは以下のようになります:

    	Seconds	Country	Latitude	Longitude
    2	20.0	3		53.200000	-2.916667
    3	20.0	4		28.978333	-96.645833
    14	30.0	4		35.823889	-80.253611
    23	60.0	4		45.582778	-122.352222
    24	3.0		3		51.783333	-0.783333
    

演習 - モデルを構築する

次に、データをトレーニング用とテスト用に分割してモデルをトレーニングする準備をします。

  1. トレーニングする3つの特徴をXベクトルとして選択し、yベクトルはCountryになります。SecondsLatitudeLongitudeを入力して国IDを返すようにします。

    from sklearn.model_selection import train_test_split
    
    Selected_features = ['Seconds','Latitude','Longitude']
    
    X = ufos[Selected_features]
    y = ufos['Country']
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
    
  2. ロジスティック回帰を使用してモデルをトレーニングします:

    from sklearn.metrics import accuracy_score, classification_report
    from sklearn.linear_model import LogisticRegression
    model = LogisticRegression()
    model.fit(X_train, y_train)
    predictions = model.predict(X_test)
    
    print(classification_report(y_test, predictions))
    print('Predicted labels: ', predictions)
    print('Accuracy: ', accuracy_score(y_test, predictions))
    

精度は悪くありません (約95%)CountryLatitude/Longitudeが相関しているため、当然の結果です。

作成したモデルは非常に革新的なものではありませんが、クリーンアップした生データからトレーニングし、エクスポートしてWebアプリで使用する練習としては良い例です。

演習 - モデルを「ピクル化」する

次に、モデルを「ピクル化」します!数行のコードでこれを実現できます。ピクル化された後、ピクル化されたモデルをロードし、秒数、緯度、経度の値を含むサンプルデータ配列でテストします。

import pickle
model_filename = 'ufo-model.pkl'
pickle.dump(model, open(model_filename,'wb'))

model = pickle.load(open('ufo-model.pkl','rb'))
print(model.predict([[50,44,-12]]))

モデルは**「3」**を返します。これは英国の国コードです。驚きですね!👽

演習 - Flaskアプリを構築する

次に、Flaskアプリを構築してモデルを呼び出し、より視覚的に魅力的な方法で結果を返します。

  1. _notebook.ipynb_ファイルの隣にweb-appというフォルダを作成します。その中に_ufo-model.pkl_ファイルを配置します。

  2. そのフォルダ内にさらに3つのフォルダを作成します: static (その中にcssフォルダを作成)、およびtemplates。以下のファイルとディレクトリが揃っているはずです:

    web-app/
      static/
        css/
      templates/
    notebook.ipynb
    ufo-model.pkl
    

    完成したアプリのビューについてはソリューションフォルダを参照してください

  3. 最初に_web-app_フォルダ内にrequirements.txtファイルを作成します。JavaScriptアプリの_package.json_のように、このファイルはアプリに必要な依存関係をリストします。requirements.txtに以下を追加します:

    scikit-learn
    pandas
    numpy
    flask
    
  4. 次に、このファイルを_web-app_で実行します:

    cd web-app
    
  5. ターミナルでpip installと入力し、_requirements.txt_にリストされたライブラリをインストールします:

    pip install -r requirements.txt
    
  6. 次に、アプリを完成させるためにさらに3つのファイルを作成します:

    1. ルートにapp.pyを作成します。
    2. _templates_ディレクトリにindex.htmlを作成します。
    3. _static/css_ディレクトリにstyles.cssを作成します。
  7. _styles.css_ファイルにいくつかのスタイルを追加します:

    body {
    	width: 100%;
    	height: 100%;
    	font-family: 'Helvetica';
    	background: black;
    	color: #fff;
    	text-align: center;
    	letter-spacing: 1.4px;
    	font-size: 30px;
    }
    
    input {
    	min-width: 150px;
    }
    
    .grid {
    	width: 300px;
    	border: 1px solid #2d2d2d;
    	display: grid;
    	justify-content: center;
    	margin: 20px auto;
    }
    
    .box {
    	color: #fff;
    	background: #2d2d2d;
    	padding: 12px;
    	display: inline-block;
    }
    
  8. 次に、_index.html_ファイルを構築します:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>🛸 UFO Appearance Prediction! 👽</title>
        <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
      </head>
    
      <body>
        <div class="grid">
    
          <div class="box">
    
            <p>According to the number of seconds, latitude and longitude, which country is likely to have reported seeing a UFO?</p>
    
            <form action="{{ url_for('predict')}}" method="post">
              <input type="number" name="seconds" placeholder="Seconds" required="required" min="0" max="60" />
              <input type="text" name="latitude" placeholder="Latitude" required="required" />
              <input type="text" name="longitude" placeholder="Longitude" required="required" />
              <button type="submit" class="btn">Predict country where the UFO is seen</button>
            </form>
    
            <p>{{ prediction_text }}</p>
    
          </div>
    
        </div>
    
      </body>
    </html>
    

    このファイルのテンプレート構文を確認してください。変数がアプリによって提供される{{}}の「マスタッシュ」構文に注目してください。また、/predictルートに予測を投稿するフォームがあります。

    最後に、モデルの消費と予測の表示を駆動するPythonファイルを構築します:

  9. app.pyに以下を追加します:

    import numpy as np
    from flask import Flask, request, render_template
    import pickle
    
    app = Flask(__name__)
    
    model = pickle.load(open("./ufo-model.pkl", "rb"))
    
    
    @app.route("/")
    def home():
        return render_template("index.html")
    
    
    @app.route("/predict", methods=["POST"])
    def predict():
    
        int_features = [int(x) for x in request.form.values()]
        final_features = [np.array(int_features)]
        prediction = model.predict(final_features)
    
        output = prediction[0]
    
        countries = ["Australia", "Canada", "Germany", "UK", "US"]
    
        return render_template(
            "index.html", prediction_text="Likely country: {}".format(countries[output])
        )
    
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    💡 ヒント: Flaskを使用してWebアプリを実行する際にdebug=Trueを追加すると、アプリケーションに加えた変更が即座に反映され、サーバーを再起動する必要がなくなります。ただし、注意してください!本番アプリではこのモードを有効にしないでください。

python app.pyまたはpython3 app.pyを実行すると、ローカルでWebサーバーが起動し、短いフォームに記入してUFO目撃情報に関する質問に答えを得ることができます

その前に、app.pyの各部分を確認してください:

  1. まず、依存関係がロードされ、アプリが開始されます。
  2. 次に、モデルがインポートされます。
  3. その後、ホームルートでindex.htmlがレンダリングされます。

/predictルートでは、フォームが投稿されると以下のことが行われます:

  1. フォーム変数が収集され、numpy配列に変換されます。それがモデルに送られ、予測が返されます。
  2. 表示したい国名が予測された国コードから読み取り可能なテキストとして再レンダリングされ、その値がindex.htmlに送られてテンプレートでレンダリングされます。

Flaskとピクル化されたモデルを使用してモデルを活用する方法は比較的簡単です。最も難しいのは、モデルに予測を得るために送信する必要があるデータの形状を理解することです。それはモデルがどのようにトレーニングされたかによります。このモデルでは、予測を得るために入力する必要があるデータポイントが3つあります。

プロフェッショナルな環境では、モデルをトレーニングする人々とWebやモバイルアプリでそれを活用する人々の間で良好なコミュニケーションが必要であることがわかります。私たちの場合、それはあなた一人です


🚀 チャレンジ

ートブックで作業し、モデルをFlaskアプリにインポートする代わりに、Flaskアプリ内でモデルをトレーニングすることができますデータをクリーンアップした後、ートブック内のPythonコードをアプリ内でトレーニングするように変換してみてください。この方法を追求する利点と欠点は何でしょうか

講義後のクイズ

復習と自己学習

機械学習モデルを活用するWebアプリを構築する方法は多数あります。JavaScriptやPythonを使用してWebアプリを構築し、機械学習を活用する方法のリストを作成してください。アーキテクチャを考慮してください: モデルはアプリ内に保持すべきか、それともクラウドに配置すべきか後者の場合、どのようにアクセスしますか応用されたML Webソリューションのアーキテクチャモデルを描いてみてください。

課題

別のモデルを試してみる


免責事項:
この文書は、AI翻訳サービス Co-op Translator を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な表現が含まれる可能性があります。元の言語で記載された原文が正式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤訳について、当社は一切の責任を負いません。