1. 程式人生 > 其它 >Python Flask + Echarts +sklearn做個簡單的線性迴歸

Python Flask + Echarts +sklearn做個簡單的線性迴歸

Flask + Echarts + sklearn 做個簡單的線性迴歸

@

目錄

Echarts官網的線性迴歸示例是用了echarts-stat.js這個外掛https://github.com/ecomfe/echarts-stat,在前端完成訓練模型和預測的操作

正好最近解除了python機器學習裡面的線性迴歸,可以用sklearn在後端訓練後把資料傳給前端,下面就來簡單實現一下

1. 專案結構

和正常的Flask結構差不多,blueprints放個藍圖echarts。static為靜態資源目錄,templates為模板目錄,config.py裡是相關環境配置,extension.py為第三方拓展如flask-sqlalchemy等,__init__.py裡放個工廠函式。main.py為程式入口。

1.1 配置檔案

上來先寫配置,BaseConfig為基本配置,有SECRET_KEY為後期作session準備的當然這個小例子用不到,SQLALCHEMY_TRACK_MODIFICATIONS設定為False。如果設定成 True (預設為None),Flask-SQLAlchemy 將會追蹤物件的修改並且傳送訊號。這需要額外的記憶體, 如果不必要的可以禁用它。

import os


class BaseConfig:
    SECRET_KEY = os.urandom(24)
    SQLALCHEMY_TRACK_MODIFICATIONS = False


class DevelopmentConfig(BaseConfig):
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:mysql@localhost:3306/demo?charset=utf8'


class TestingConfig(BaseConfig):
    pass


class ProductionConfig(BaseConfig):
    pass


config = {
    'development': DevelopmentConfig,
    'testing': TestingConfig,
    'production': ProductionConfig,
    'default': DevelopmentConfig
}

1.2 拓展檔案

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()


def init_ext(app):
    db.init_app(app)

1.3 模板檔案

就一個圖,加一個div就行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/js/jquery.min.js"></script>
    <script src="/js/echarts.min.js"></script>
</head>
<body>
<div id="regression" style="height: 600px; width:800px"></div>
<script src="/js/myEcharts.js"></script>
</body>
</html>

1.4 檢視檔案

先寫這個樣子,後面再陸續補充

from flask import Blueprint, render_template

echarts = Blueprint('echarts', __name__)


@echarts.route('/')
def index():
    return render_template('index.html')

1.5 初始化檔案

匯入Flask,檢視,拓展,配置,一一載入,註冊。最終返回app

from flask import Flask

from demo.blueprints import init_blueprints
from demo.extension import init_ext
from demo.config import config

app = Flask(__name__, static_url_path='/')


def create_app(config_name):
    app.config.from_object(config.get(config_name))
    init_blueprints(app)
    init_ext(app)

    return app

1.6 程式入口

傳入系統配置並接受工廠函式的app例項

import os

from demo import create_app

config = os.getenv('FLASK_EBV', 'development')
app = create_app(config)

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

上面都完成後就可以把框架跑起來了

2. 完善後端檢視檔案

2.1 使用sklearn訓練模型

為了把散點圖和折線圖(其實是直線)放在一起,預測的資料必須和原資料一樣是二維列表形式,也就是一個座標列表

from sklearn.linear_model import LinearRegression


def get_linear_regression():
    # 資料太多了,暫時省略
    data = [[...]]
    reg = LinearRegression()
    data_X = [[row[0]] for row in data]
    data_y = [row[1] for row in data]
    # 訓練模型
    reg.fit(data_X, data_y)
    temp = reg.predict(data_X)
    data_y_predict = []
    for i in range(len(temp)):
        data_y_predict.append([data_X[i][0], temp[i]])
    # 一元函式表示式
    expression = f'y = {round(reg.intercept_, 3)}x + {round(reg.coef_[0], 3)}'

    return data, data_y_predict, expression

2.2 定義介面

因為我不太喜歡把js和html和css放在一起,所有我決定拆分它們,單獨寫js。那麼這時候jinja2模板就用不到了,後端傳資料的方式改為Ajax請求介面

定義一個介面

@echarts.route('/echartsData')
def get_echarts_data():
    data, data_y_predict, expression = get_linear_regression()

    echarts_data = {
        'data': data,
        'data_y_predict': data_y_predict,
        'expression': expression
    }
    return echarts_data

3.編寫前端js檔案

3.1 發起Ajax請求

let echartsData;

$.ajax({
    url: '/echartsData',
    async: false,
    success: function(data) {
        echartsData = data
    }
})

這裡的async設為false,方便將資料賦值為全域性變數echartsData

3.2 echarts部分

let divEle = $('#regression')[0]

let myEcharts = echarts.init(divEle)

// 線性迴歸
option = {
    title: {
        text: '線性迴歸',
        subtext: '使用sklearn',
        textStyle: {
            color: 'red',
            fontStyle: 'italic'
        },
        subtextStyle: {
            color: 'black',
            fontSize: 15
        },
        link: 'https://echarts.apache.org/v4/examples/zh/editor.html?c=scatter-linear-regression',
        sublink: 'https://scikit-learn.org/stable/auto_examples/linear_model/plot_ols.html',
        left: 'center'
    },
    legend: {
        left: '25%',
        top: '5%'
    },
    tooltip: {
        type: 'axis',
        axisPointer: {
            type: 'cross'
        }
    },
    xAxis: {
        type: 'value'
    },
    yAxis: {
        type: 'value',
        min: 2
    },
    series: [
        {
            name: 'scatter',
            type: 'scatter',
            data: echartsData.data
        },
        {
            name: 'line',
            type: 'line',
            data: echartsData.data_y_predict,
            // 不展示特徵,如圓點
            showSymbol: false,
            // 圖示標註
            markPoint: {
                itemStyle: {
                    // 透明色
                    color: 'transparent'
                },
                label: {
                    show: true,
                    position: 'left',
                    formatter: echartsData.expression,
                    fontSize: 15,
                    color: '#333'
                },
                data: [
                    {
                        name: '自定義畫素點',
                        x: '50%',
                        y: '30%'
                    }
                ]
            }
        }
    ]
};

myEcharts.setOption(option)

4. 結果展示