從零開始學機器學習——網路應用

努力的小雨發表於2024-10-06

首先給大家介紹一個很好用的學習地址:https://cloudstudio.net/columns

今天,我們的主要任務是按照既定的流程再次執行模型,並將其成功載入到 Web 應用程式中,以便透過 Web 介面進行呼叫。最終生成的模型將能夠基於 UFO 目擊事件的資料和經緯度資訊,推斷出事件發生的城市地址。儘管經緯度資訊似乎已經足夠,但我們還是需要模型進行預測,這只是一個練習目的。希望透過這個過程,你能進一步理解機器學習模型在 Web 應用中的應用與整合。

知識回顧

工具

對於此任務,你需要兩個工具:Flask 和 Pickle,它們都在 Python 上執行。

Flask 是一個輕量級的 web 應用框架,適用於構建簡單的 web 應用和 RESTful API。它遵循 WSGI(Web Server Gateway Interface)標準,支援多種擴充套件,具有以下特點:

  • 簡單易用:Flask 的核心非常簡單,易於上手,適合初學者。
  • 靈活性:開發者可以根據需要選擇和新增擴充套件,使其具有更強的功能。
  • 路由系統:Flask 提供了靈活的 URL 路由機制,方便管理不同的頁面和請求。
  • 模板引擎:整合了 Jinja2 模板引擎,可以輕鬆生成動態 HTML 頁面。
  • 支援 RESTful API:非常適合構建 RESTful 服務。

Pickle 是 Python 的一個內建模組,用於物件序列化和反序列化。序列化是將 Python 物件轉換為位元組流的過程,而反序列化則是將位元組流還原為 Python 物件。它的特點包括:

  • 簡單方便:使用簡單,可以輕鬆地儲存和載入 Python 物件。
  • 支援多種物件:可以序列化大多數 Python 資料型別,包括自定義類。
  • 持久化資料:適合將資料儲存到檔案中,以便後續使用。

注意:Pickle 對安全性有一定的隱患,因為反序列化不可信的資料可能導致程式碼執行漏洞。

清洗資料

首先,讓我們來深入瞭解一下我們的資料集,看看它的具體結構和內容。這一步非常重要,因為資料的質量和特徵將直接影響到模型的效能和預測結果。

import pandas as pd
import numpy as np

ufos = pd.read_csv('./data/ufos.csv')
ufos.head()

image

因此,根據我們要解決的問題,我們需要提取與之相關的向量欄位資料。這些欄位包括:城市名稱、經緯度座標以及目擊時長。這些資訊將為我們後續的分析和建模提供重要的輸入特徵,幫助我們準確地推斷 UFO 目擊事件發生的城市。

ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']})

ufos.Country.unique()
ufos.dropna(inplace=True)
ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)]
ufos.info()

在完成這一系列的資料清洗和篩選後,我們的資料集將僅包含我們所需的相關欄位,確保其精簡而高效。此外,我們還對目擊時長進行了特別的過濾,以確保該特徵的有效性和一致性。

因為我們瞭解到,模型對資料的敏感性會影響其預測結果。接下來,我們需要將文字欄位轉換為適合模型處理的數值資料格式。這一轉換過程將使得模型能夠理解和利用這些文字資訊,從而提升預測能力。

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

目前為止,我們已經成功完成了資料的清理和預處理,確保我們的資料集具備良好的質量和一致性。接下來,我們將進入模型訓練的階段。考慮到我們的任務是預測城市,而城市名稱是一個有限且固定的類別,邏輯迴歸模型將是一個理想的選擇。

建立模型

現在,我們將開始準備訓練模型的關鍵步驟,即將資料集劃分為訓練組和測試組。

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report 
from sklearn.linear_model import LogisticRegression

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)


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))

返回如下:

              precision    recall  f1-score   support

           0       1.00      1.00      1.00        41
           1       0.83      0.23      0.36       250
           2       1.00      1.00      1.00         8
           3       1.00      1.00      1.00       131
           4       0.96      1.00      0.98      4743

    accuracy                           0.96      5173
   macro avg       0.96      0.85      0.87      5173
weighted avg       0.96      0.96      0.95      5173

Predicted labels:  [4 4 4 ... 3 4 4]
Accuracy:  0.9605644693601392

模型的準確率相當不錯,約為95%。這一結果並不令人意外,因為我們的特徵——國家(Country)以及經緯度(Latitude/Longitude)資訊之間確實存在顯著的相關性。

接下來,我們需要將這一訓練好的模型進行打包,以便將其整合到我們的Web應用程式中。這樣,使用者就能夠透過網頁輕鬆呼叫模型進行城市預測,享受流暢的互動體驗。

打包模型

我們可以直接利用pickle庫這一便捷的依賴,將訓練好的模型序列化並寫入檔案。

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

model = pickle.load(open('ufo-model.pkl','rb'))

構建WEB

現在,我們的目標是透過Flask應用程式來呼叫已訓練好的模型,並將預測結果以更加美觀和使用者友好的方式展示在Web頁面上。Flask作為一個輕量級的Web框架,能夠幫助我們快速構建Web應用,讓使用者透過直觀的介面與模型進行互動。

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

這是我們需要新建的目錄結構,請務必嚴格遵循這一佈局,因為不按此結構組織檔案和資料夾可能會導致程式在執行時出現錯誤。

requirements.txt中新增以下幾行:

scikit-learn
pandas
numpy
flask

然後安裝相關依賴

pip install -r requirements.txt

其餘的CSS和HTML程式碼請前往學習中心自行復制和參考,這裡不再一一列舉。

在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)

這段程式碼實現了一個簡單的 web 應用,允許使用者輸入特徵資料並根據載入的機器學習模型進行預測。預測結果會被渲染到同一個頁面上顯示給使用者。透過 Flask 的路由系統,可以方便地處理使用者請求和響應。

例如,當我們輸入特徵資料“50, 44, -12”時,應用將呼叫訓練好的模型進行計算,並在頁面上展示預測結果,如圖所示。

image

總結

在這個專案中,我們透過使用 Flask 和 Pickle 將一個機器學習模型成功整合到 Web 應用中,使使用者能夠透過友好的介面進行預測。這一過程不僅讓我們體驗到了模型訓練與資料預處理的細節,也深刻理解了如何在實際應用中實現機器學習的功能。

透過這一系列的實踐操作,我們不僅鞏固了對工具和技術的理解,也提升了將理論知識轉化為實際應用的能力。這一過程的重要性在於,它不僅是對我們技術能力的挑戰,更是對解決實際問題能力的培養。


我是努力的小雨,一名 Java 服務端碼農,潛心研究著 AI 技術的奧秘。我熱愛技術交流與分享,對開源社群充滿熱情。同時也是一位騰訊雲創作之星、阿里雲專家博主、華為云云享專家、掘金優秀作者。

💡 我將不吝分享我在技術道路上的個人探索與經驗,希望能為你的學習與成長帶來一些啟發與幫助。

🌟 歡迎關注努力的小雨!🌟

相關文章