Ask me anything
Ithy Logo
Sign in to save

使用 Flask 規劃 AutoML 的完整網頁應用指南

打造一個全方位的自動化機器學習平台,從專案管理到模型訓練的全面解決方案

flask automl web application interface

三大重點

  • 全面的專案與數據管理功能:提供用戶友好的介面來管理機器學習專案和數據集。
  • 完整的模型建立流程:涵蓋數據前處理、補值、特徵萃取、模型選擇、模型評估及重訓等。
  • 模型列表與訓練隊列:方便用戶查看已訓練的模型並管理訓練任務。

一、專案結構規劃

首先,我們需要規劃專案的目錄結構,以確保應用程式的組織性和可維護性。以下是一個推薦的專案結構:


automl_flask/
│
├── app/
│   ├── __init__.py
│   ├── models/
│   │   ├── __init__.py
│   │   ├── project.py
│   │   ├── dataset.py
│   │   └── model.py
│   ├── services/
│   │   ├── __init__.py
│   │   ├── data_processor.py
│   │   ├── feature_extractor.py
│   │   └── model_trainer.py
│   ├── views/
│   │   ├── __init__.py
│   │   ├── project.py
│   │   ├── dataset.py
│   │   └── model.py
│   ├── templates/
│   │   ├── base.html
│   │   ├── projects/
│   │   │   ├── list.html
│   │   │   └── create.html
│   │   ├── datasets/
│   │   │   └── manage.html
│   │   └── models/
│   │       ├── list.html
│   │       └── training.html
│   └── static/
│       ├── css/
│       └── js/
│
├── requirements.txt
├── config.py
├── run.py
├── celery_config.py
└── README.md

    

二、安裝必要的依賴套件

在requirements.txt中列出所有需要的 Python 套件:


Flask==3.0.0
Flask-SQLAlchemy==3.0.0
pandas==2.0.0
scikit-learn==1.3.0
joblib==1.3.0
TPOT==0.12.0
h2o==3.40.0.1
Celery==5.2.7
redis==4.5.5

    

使用以下指令安裝依賴套件:


pip install -r requirements.txt

    

三、配置 Flask 應用程式

1. 初始化 Flask 和資料庫

在 app/__init__.py 中初始化 Flask 應用程式和 SQLAlchemy 資料庫:


from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import Config

db = SQLAlchemy()

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    
    db.init_app(app)
    
    from app.views import project, dataset, model
    app.register_blueprint(project.bp)
    app.register_blueprint(dataset.bp)
    app.register_blueprint(model.bp)
    
    return app

    

2. 設定檔案

在 config.py 中定義配置參數:


import os

class Config:
    SECRET_KEY = 'your-secret-key'
    SQLALCHEMY_DATABASE_URI = 'sqlite:///automl.db'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    UPLOAD_FOLDER = 'uploads'
    ALLOWED_EXTENSIONS = {'csv', 'xlsx'}
    CELERY_BROKER_URL = 'redis://localhost:6379/0'
    CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'

    

3. 啟動應用程式

在 run.py 中啟動 Flask 應用程式:


from app import create_app, db
from flask_migrate import Migrate

app = create_app()
migrate = Migrate(app, db)

if __name__ == '__main__':
    app.run(debug=True)

    

四、定義資料庫模型

在 app/models 目錄下定義專案管理、數據集和模型的資料庫模型。

1. 專案模型

在 app/models/project.py 中定義專案模型:


from app import db
from datetime import datetime

class Project(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    datasets = db.relationship('Dataset', backref='project', lazy=True)
    models = db.relationship('Model', backref='project', lazy=True)

    

2. 數據集模型

在 app/models/dataset.py 中定義數據集模型:


from app import db

class Dataset(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False)
    file_path = db.Column(db.String(100), nullable=False)
    uploaded_at = db.Column(db.DateTime, default=datetime.utcnow)

    

3. 模型模型

在 app/models/model.py 中定義模型模型:


from app import db

class Model(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False)
    model_info = db.Column(db.String(100), nullable=False)
    accuracy = db.Column(db.Float, nullable=True)
    trained_at = db.Column(db.DateTime, default=datetime.utcnow)

    

五、建立服務層

在 app/services 目錄下建立數據處理、特徵萃取和模型訓練的服務。

1. 數據處理器

在 app/services/data_processor.py 中定義數據處理器:


import pandas as pd
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler

class DataProcessor:
    def __init__(self):
        self.imputer = SimpleImputer(strategy='mean')
        self.scaler = StandardScaler()
    
    def preprocess_data(self, df):
        # 數據清理
        df = df.dropna(how='all')
        
        # 缺失值處理
        numerical_columns = df.select_dtypes(include=['float64', 'int64']).columns
        df[numerical_columns] = self.imputer.fit_transform(df[numerical_columns])
        
        # 特徵標準化
        df[numerical_columns] = self.scaler.fit_transform(df[numerical_columns])
        
        return df

    

2. 特徵萃取器

在 app/services/feature_extractor.py 中定義特徵萃取器:


from sklearn.feature_selection import SelectKBest, f_classif

class FeatureExtractor:
    def __init__(self, k=10):
        self.selector = SelectKBest(score_func=f_classif, k=k)
    
    def extract_features(self, X, y):
        X_new = self.selector.fit_transform(X, y)
        return X_new, self.selector.get_support(indices=True)

    

3. 模型訓練器

在 app/services/model_trainer.py 中定義模型訓練器:


from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from tpot import TPOTClassifier
from h2o.automl import H2OAutoML
import joblib

class ModelTrainer:
    def __init__(self):
        self.models = {
            'random_forest': RandomForestClassifier(),
            'tpot': TPOTClassifier(generations=5, population_size=20, verbosity=2),
            'h2o_automl': H2OAutoML(max_models=20, seed=1)
        }
    
    def train_model(self, X, y, model_name):
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
        
        if model_name == 'h2o_automl':
            import h2o
            h2o.init()
            train = h2o.H2OFrame(pd.concat([X_train, y_train], axis=1))
            aml = self.models[model_name]
            aml.train(y=y_train.name, training_frame=train)
            model = aml.leader
            y_pred = model.predict(train).as_data_frame()['predict']
            accuracy = accuracy_score(y_test, y_pred)
            h2o.shutdown(prompt=False)
        else:
            model = self.models[model_name]
            model.fit(X_train, y_train)
            y_pred = model.predict(X_test)
            accuracy = accuracy_score(y_test, y_pred)
        
        return model, accuracy
    
    def save_model(self, model, filename):
        joblib.dump(model, filename)

    

六、建立視圖與路由

在 app/views 目錄下建立專案管理、數據管理和模型管理的視圖。

1. 專案管理視圖

在 app/views/project.py 中定義專案管理的路由:


from flask import Blueprint, render_template, request, redirect, url_for, flash
from app.models.project import Project
from app import db

bp = Blueprint('project', __name__)

@bp.route('/projects')
def list_projects():
    projects = Project.query.all()
    return render_template('projects/list.html', projects=projects)

@bp.route('/projects/create', methods=['GET', 'POST'])
def create_project():
    if request.method == 'POST':
        name = request.form['name']
        description = request.form['description']
        project = Project(name=name, description=description)
        db.session.add(project)
        db.session.commit()
        flash('專案創建成功!', 'success')
        return redirect(url_for('project.list_projects'))
    return render_template('projects/create.html')

    

2. 數據管理視圖

在 app/views/dataset.py 中定義數據管理的路由:


import os
from flask import Blueprint, render_template, request, redirect, url_for, flash
from app.models.dataset import Dataset
from app import db
from app.services.data_processor import DataProcessor

bp = Blueprint('dataset', __name__)

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in {'csv', 'xlsx'}

@bp.route('/datasets', methods=['GET', 'POST'])
def manage_datasets():
    if request.method == 'POST':
        project_id = request.form['project_id']
        file = request.files['file']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            filepath = os.path.join(current_app.config['UPLOAD_FOLDER'], filename)
            file.save(filepath)
            dataset = Dataset(project_id=project_id, file_path=filepath)
            db.session.add(dataset)
            db.session.commit()
            flash('數據集上傳成功!', 'success')
            return redirect(url_for('dataset.manage_datasets'))
        else:
            flash('無效的文件類型!', 'error')
    projects = Project.query.all()
    datasets = Dataset.query.all()
    return render_template('datasets/manage.html', projects=projects, datasets=datasets)

    

3. 模型管理視圖

在 app/views/model.py 中定義模型管理的路由:


from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify
from app.models.model import Model
from app.models.dataset import Dataset
from app.models.project import Project
from app.services.model_trainer import ModelTrainer
from app import db
from celery_config import celery
import os

bp = Blueprint('model', __name__)

trainer = ModelTrainer()

@bp.route('/models', methods=['GET'])
def list_models():
    models = Model.query.all()
    return render_template('models/list.html', models=models)

@bp.route('/models/train', methods=['POST'])
def train_model():
    data = request.json
    project_id = data.get('project_id')
    dataset_id = data.get('dataset_id')
    target_column = data.get('target_column')
    model_type = data.get('model_type')
    
    task = train_model_task.delay(dataset_id, model_type, target_column)
    return jsonify({'task_id': task.id}), 202

@celery.task
def train_model_task(dataset_id, model_type, target_column):
    dataset = Dataset.query.get(dataset_id)
    df = pd.read_csv(dataset.file_path)
    
    processor = DataProcessor()
    df_processed = processor.preprocess_data(df)
    
    X = df_processed.drop(columns=[target_column])
    y = df_processed[target_column]
    
    model, accuracy = trainer.train_model(X, y, model_type)
    
    model_filename = f"model_{dataset_id}_{model_type}.pkl"
    model_path = os.path.join('models_trained', model_filename)
    trainer.save_model(model, model_path)
    
    new_model = Model(project_id=dataset.project_id, model_info=model_type, accuracy=accuracy, trained_at=datetime.utcnow())
    db.session.add(new_model)
    db.session.commit()
    
    return {'model_path': model_path, 'accuracy': accuracy}

    

七、前端模板設計

在 app/templates 目錄下建立 HTML 模板,提供用戶界面。

1. 基礎模板

在 app/templates/base.html 中定義基礎模板:


<!DOCTYPE html>
<html lang="zh-TW">
<head>
    <meta charset="UTF-8">
    <title>AutoML 系統</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <header>
        <h1>AutoML 系統</h1>
        <nav>
            <ul>
                <li><span style="opacity: 0.2">專案管理</span></li>
                <li><span style="opacity: 0.2">數據管理</span></li>
                <li><span style="opacity: 0.2">模型管理</span></li>
            </ul>
        </nav>
    </header>
    <main>
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
                <ul class="flashes">
                    {% for category, message in messages %}
                        <li class="{{ category }}">{{ message }}</li>
                    {% endfor %}
                </ul>
            {% endif %}
        {% endwith %}
        {% block content %}{% endblock %}
    </main>
    <footer>
        <p>© 2025 AutoML 系統</p>
    </footer>
</body>
</html>

    

2. 專案列表模板

在 app/templates/projects/list.html 中定義專案列表頁面:


{% extends 'base.html' %}
{% block content %}
<h2>專案列表</h2>
<span style="opacity: 0.2">新增專案</span>
<table>
    <tr>
        <th>ID</th>
        <th>名稱</th>
        <th>描述</th>
        <th>建立時間</th>
    </tr>
    {% for project in projects %}
    <tr>
        <td>{{ project.id }}</td>
        <td>{{ project.name }}</td>
        <td>{{ project.description }}</td>
        <td>{{ project.created_at }}</td>
    </tr>
    {% endfor %}
</table>
{% endblock %}

    

3. 新增專案模板

在 app/templates/projects/create.html 中定義新增專案頁面:


{% extends 'base.html' %}
{% block content %}
<h2>新增專案</h2>
<form method="POST">
    <label for="name">專案名稱:</label>
    <input type="text" id="name" name="name" required>
    <br>
    <label for="description">專案描述:</label>
    <textarea id="description" name="description"></textarea>
    <br>
    <button type="submit">創建專案</button>
</form>
{% endblock %}

    

4. 數據管理模板

在 app/templates/datasets/manage.html 中定義數據管理頁面:


{% extends 'base.html' %}
{% block content %}
<h2>數據管理</h2>
<form method="POST" enctype="multipart/form-data">
    <label for="project_id">選擇專案:</label>
    <select name="project_id" id="project_id">
        {% for project in projects %}
            <option value="{{ project.id }}">{{ project.name }}</option>
        {% endfor %}
    </select>
    <br>
    <label for="file">上傳數據文件:</label>
    <input type="file" id="file" name="file" required>
    <br>
    <button type="submit">上傳數據</button>
</form>

<h3>已上傳的數據集</h3>
<table>
    <tr>
        <th>ID</th>
        <th>專案ID</th>
        <th>文件路徑</th>
        <th>上傳時間</th>
    </tr>
    {% for dataset in datasets %}
    <tr>
        <td>{{ dataset.id }}</td>
        <td>{{ dataset.project_id }}</td>
        <td>{{ dataset.file_path }}</td>
        <td>{{ dataset.uploaded_at }}</td>
    </tr>
    {% endfor %}
</table>
{% endblock %}

    

5. 模型列表模板

在 app/templates/models/list.html 中定義模型列表頁面:


{% extends 'base.html' %}
{% block content %}
<h2>模型列表</h2>
<table>
    <tr>
        <th>ID</th>
        <th>專案ID</th>
        <th>模型類型</th>
        <th>準確率</th>
        <th>訓練時間</th>
    </tr>
    {% for model in models %}
    <tr>
        <td>{{ model.id }}</td>
        <td>{{ model.project_id }}</td>
        <td>{{ model.model_info }}</td>
        <td>{{ model.accuracy }}</td>
        <td>{{ model.trained_at }}</td>
    </tr>
    {% endfor %}
</table>

<h3>訓練新模型</h3>
<form id="train-form">
    <label for="project_id">選擇專案:</label>
    <select id="project_id" name="project_id">
        {% for project in projects %}
            <option value="{{ project.id }}">{{ project.name }}</option>
        {% endfor %}
    </select>
    <br>
    <label for="dataset_id">選擇數據集:</label>
    <select id="dataset_id" name="dataset_id">
        {% for dataset in datasets %}
            <option value="{{ dataset.id }}">{{ dataset.file_path }}</option>
        {% endfor %}
    </select>
    <br>
    <label for="target_column">目標欄位:</label>
    <input type="text" id="target_column" name="target_column" required>
    <br>
    <label for="model_type">模型類型:</label>
    <select id="model_type" name="model_type">
        <option value="random_forest">隨機森林</option>
        <option value="tpot">TPOT</option>
        <option value="h2o_automl">H2O AutoML</option>
    </select>
    <br>
    <button type="submit">開始訓練</button>
</form>

<script>
document.getElementById('train-form').addEventListener('submit', function(e){
    e.preventDefault();
    fetch('{{ url_for("model.train_model") }}', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            project_id: document.getElementById('project_id').value,
            dataset_id: document.getElementById('dataset_id').value,
            target_column: document.getElementById('target_column').value,
            model_type: document.getElementById('model_type').value
        })
    }).then(response => response.json())
      .then(data => {
          alert('模型訓練已開始,任務ID:' + data.task_id);
      });
});
</script>
{% endblock %}

    

八、配置 Celery 進行異步任務處理

為了處理模型訓練的耗時操作,我們使用 Celery 與 Redis 作為訊息代理。

1. Celery 配置

在 celery_config.py 中配置 Celery:


from celery import Celery
from config import Config

celery = Celery('tasks', broker=Config.CELERY_BROKER_URL)
celery.conf.update(result_backend=Config.CELERY_RESULT_BACKEND)

    

2. 啟動 Celery Worker

使用以下指令啟動 Celery Worker:


celery -A celery_config.celery worker --loglevel=info

    

九、啟動與測試應用程式

完成所有設定後,依序執行以下步驟來啟動應用程式:

  1. 啟動 Redis 伺服器。
  2. 啟動 Celery Worker:
  3. 
    celery -A celery_config.celery worker --loglevel=info
    
            
  4. 啟動 Flask 應用程式:
  5. 
    python run.py
    
            
  6. 在瀏覽器中訪問 http://localhost:5000 來使用應用程式。

確保每個步驟都正確執行,並監控終端機中的日誌以檢查是否有任何錯誤。


十、結論

透過上述步驟,我們成功建立了一個基於 Flask 的 AutoML 網頁應用程式,具備全面的專案管理、數據管理、模型建立流程及模型訓練隊列等功能。此應用程式能夠協助用戶自動化機器學習流程,提升開發效率和模型性能。

未來可以進一步優化前端介面、增加更多的模型類型支援、引入用戶認證機制,以及整合更先進的 AutoML 工具,以滿足更廣泛的需求。


參考資料



Last updated January 24, 2025

AI-assisted research. Sources, methodology and corrections · Source-checked guides and tools · Explore published answers

Ask Ithy AI