Python Flask + Echarts +sklearn做個簡單的線性迴歸
阿新 • • 發佈:2022-04-07
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)