Python 数据模型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 数据模型相关的知识,希望对你有一定的参考价值。

参考技术A

Python 风格的关键完全体现在 Python 的数据模型上,数据模型所描述的 API ,为使用最地道的语言特性来构建开发者自己的对象提供了工具。

当 Python 解析器遇到特殊句法时,会使用特殊方法去激活一些基本的对象操作。特殊方法以双下划线开头,以双下划线结尾。如: obj[key] 的背后就是 __getitem__ 方法。魔术方法是特殊方法的昵称,特殊方法也叫双下方法。

使用 __getitem__ 和 __len__ 创建一摞有序的纸牌:

上面的例子,使用 collections.namedtuple 构建了一个简单的类来表示一张纸牌, namedtuple 用以构建只有少数属性但没有方法的类。

我们自定义的 FrenchDeck 类可以像任何 python 标准集合类型一样使用 len() 函数,查看一叠牌有多少张:

也可以像列表一样,使用位置索引, d[i] 将调用 __getitem__ 方法:

也可以使用标准库模块提供的 random.choice 方法,从序列中随机选取一个元素。下面,我们如随机取出一张纸牌:

现在我们已经体会到通过 python 特殊方法,来使用 Python 数据模型的 2 个好处:

因为 __getitem__ 方法把 [] 操作交给了 self.cards 列表,所以我们的 FrenchDeck 实例自动支持切片:

仅仅实现了 __getitem__ 方法,这一摞牌即变得可迭代:

运行结果:

也可以直接调用内置的 reversed 函数,反向迭代 FrenchDeck 实例:

运行结果:

迭代通常是隐式的,比如一个集合类型没有实现 __contains__ 方法,那么 in 运算符就会按顺序做一次迭代搜索。

因此, in 运算符可以用在我们的 FrenchDeck 实例上,因为它是可迭代的:

FrenchDeck 还可以使用 Python 标准库中的 sorted 函数,实现排序:

首先定义一个排序依据的函数:

优先按 rank 的大小排序,rank 相同时则比较 suit 的值:

运行结果:

优先按 suit 的大小排序,suit 相同时则比较 rank 的值:

运行结果:

按照目前的设计,FrenchDeck 还不支持洗牌,因为它是不可变的:

shuffle 函数要调换集合中元素的位置,而 FrenchDeck 只实现了不可变的序列协议,可变的序列还必须提供 __setitem__ 方法:

洗牌:

没有任何的返回值,可见 random.shuffle 就地修改了可变序列 d 。为便于观察结果,我们定义输入的输出函数:

运行结果:

每次洗牌,都是一个随机的序列:

首先明确一点,特殊方法的存在是为了被 Python 解析器调用的,例如:我们不会使用 obj.__len__() 这种写法,而是 len(obj) 。在执行 len(obj) 时,如果 obj 是一个自定义类的对象,那么 Python 会自己去调用我们实现的 __len__ 方法。

对于 Python 内置的数据类型,比如列表、字符串、字节序列等,那么 CPython 会抄个近路, __len__ 实际上会返回 PyVarObject 里的 ob_size 属性,这是因为直接读取属性比调用一个方法要快得多。

很多时候,特殊方法的调用是隐式的,比如 for i in x: 这个语句其实是调用 iter(x) ,而这个函数的背后是 x.__iter__() 方法。

通过内置函数如来使用特殊方法是最好的选择。这些内置函数不仅会调用这些方法,通常还提供额外的好处,对于内置类型来说,它们的速度更快。

下面,我们通过定义一个简单的二维向量类,再来体会一下 Python 特殊方法的美妙:

使用 Vector 类,就像使用 Python 内置的数据类型一样简单:

用python+sklearn(机器学习)实现天气预报数据 模型和使用

用python+sklearn机器学习实现天气预报 模型和使用

项目地址

github项目:PYWeatherReport

系列教程

机器学习参考篇: python+sklearn+kaggle机器学习
用python+sklearn(机器学习)实现天气预报 准备
用python+sklearn(机器学习)实现天气预报数据 数据
用python+sklearn(机器学习)实现天气预报 模型和使用

0.前言

在上一篇教程里我们已经获取了所需要的全部数据,包括训练数据集和测试数据集,使用ProcessData()调用,所以接下来写模型的建立和预测

1.建立模型

没段代码在文章后面都会整合成一段,分段展示只是便于阅读

a.准备

引入所需要的头文件

from sklearn.ensemble import RandomForestRegressor # 随机树森林模型
import joblib # 保存模型为pkl
from sklearn.metrics import mean_absolute_error # MAE评估方法
from ProcessData import ProcessData # 取数据

选择模型

首先我们先要从模型里选择一项适合这次场景的模型,比如从决策树,随机树森林,RGB模型等等中选择,本处选用的随机树森林也就是RandomForest

选择评估方法

目前有许多的模型准确率评估方法,本处使用的是MAE,也就是mean_absolute_error 平均错误数值,就每个预测的数值离正确数值错误数值的平均数

获取数据集

这次可以从ProcessData()获取到全部的被预处理后的数据,如

# 取到数据
    [X_train, X_valid, y_train, y_valid, X_test] = ProcessData()

b.建立模型

	# 用XGB模型,不过用有bug
    # modelX = XGBRegressor(n_estimators=1000, learning_rate=0.05, random_state=0, n_jobs=4)
    # # model.fit(X_train_3, y_train_3)
    # # model.fit(X_train_2, y_train_2)
    # col = ["Ave_t", "Max_t", "Min_t", "Prec","SLpress", "Winddir", "Windsp", "Cloud"]
    # modelX.fit(X_train, y_train,
    #           early_stopping_rounds=5,
    #           eval_set=[(X_valid, y_valid)],
    #           verbose=False)
    # 随机树森林模型
    model = RandomForestRegressor(random_state=0, n_estimators=1001)
    # 训练模型
    model.fit(X_train, y_train)

其中n_estimators是可自己选的,不过在多次调试后得到1001是MAE最优

c.获取模型评估结果

	# 用MAE评估
    score = mean_absolute_error(y_valid, preds)

d.用joblib模块保存模型

保存后的模型便于传播即可多次使用,但当前环境下的需求不大但我还是写了

    # 保存模型到本地
    joblib.dump(model, a)

e.封装

GetModel.py

# -*- coding: utf-8 -*-
# @Time: 2020/12/16
# @Author: Eritque arcus
# @File: GetModel.py
from sklearn.ensemble import RandomForestRegressor
import joblib
from sklearn.metrics import mean_absolute_error
from ProcessData import ProcessData


# 训练并保存模型
def GetModel(a="Model.pkl"):
    """
    :param a: 模型文件名
    :return:
        [socre: MAE评估结果,
        X_test: 预测数据集]
    """
    # 取到数据
    [X_train, X_valid, y_train, y_valid, X_test] = ProcessData()
    # 用XGB模型,不过用有bug
    # modelX = XGBRegressor(n_estimators=1000, learning_rate=0.05, random_state=0, n_jobs=4)
    # # model.fit(X_train_3, y_train_3)
    # # model.fit(X_train_2, y_train_2)
    # col = ["Ave_t", "Max_t", "Min_t", "Prec","SLpress", "Winddir", "Windsp", "Cloud"]
    # modelX.fit(X_train, y_train,
    #           early_stopping_rounds=5,
    #           eval_set=[(X_valid, y_valid)],
    #           verbose=False)
    # 随机树森林模型
    model = RandomForestRegressor(random_state=0, n_estimators=1001)
    # 训练模型
    model.fit(X_train, y_train)
    # 预测模型,用上个星期的数据
    preds = model.predict(X_valid)
    # 用MAE评估
    score = mean_absolute_error(y_valid, preds)
    # 保存模型到本地
    joblib.dump(model, a)
    # 返回MAE
    return [score, X_test]

2.总控

代码

这几篇文章写了零零散散好几个类,所以要写个总文件也就是启动文件串起来,然后在控制台输出
Main.py

# -*- coding: utf-8 -*-
# @Time: 2020/12/16
# @Author: Eritque arcus
# @File: Main.py
import joblib
import datetime as DT
from GetModel import GetModel
import matplotlib.pyplot as plt


# 训练并保存模型并返回MAE
r = GetModel()
print("MAE:", r[0])
# 读取保存的模型
model = joblib.load('Model.pkl')

# 最终预测结果
preds = model.predict(r[1])
# 反归一化或标准化,不过出bug了,不用
# for cols in range(0, len(preds)):
#     preds[cols] = scaler.inverse_transform(preds[cols])
# sns.lineplot(data=preds)
# plt.show()
# 打印结果到控制台
print("未来7天预测")
print(preds)
all_ave_t = []
all_high_t = []
all_low_t = []
for a in range(1, 7):
    today = DT.datetime.now()
    time = (today + DT.timedelta(days=a)).date()
    print(time.year, '/', time.month, '/', time.day,
          ': 平均气温',  preds[a][0],
          '最高气温', preds[a][1],
          '最低气温', preds[a][2],
          "降雨量", preds[a][3],
          "风力", preds[a][4])
    all_ave_t.append(preds[a][0])
    all_high_t.append(preds[a][1])
    all_low_t.append(preds[a][2])
temp = "ave_t": all_ave_t, "high_t": all_high_t, "low_t": all_low_t
# 绘画折线图
plt.plot(range(1, 7), temp["ave_t"], color="green", label="ave_t")
plt.plot(range(1, 7), temp["high_t"], color="red", label="high_t")
plt.plot(range(1, 7), temp["low_t"], color="blue", label="low_t")
plt.legend()  # 显示图例
plt.ylabel("Temperature(°C)")
plt.xlabel("day")
# 显示
plt.show()

使用方法

直接用python运行pre_weather/Main.py,就会在控制台输出预测的数据

python pre_weather/Main.py

在你的python代码里用joblib导入生成的模型,然后输入你的数据进行预测

(PS: 因为模型的训练用的数据日期和你预测数据的日期有关,所以不建议直接用使用非当天训练的模型进行预测,误差可能偏大)

如以下代码(在Main.py的11行):

import joblib

# 读取保存的模型
model = joblib.load('Model.pkl')

# 最终预测结果
preds = model.predict(r[1])
其中,r[1]是预测数据

参考Main.py,自己写一个符合你需求的启动文件

3.最后效果

本系列教程到这就结束了,代码具体还要以github项目:PYWeatherReport为主,可能会在这个github项目上不定期优化更新
有问题可以在评论问问

-END-

以上是关于Python 数据模型的主要内容,如果未能解决你的问题,请参考以下文章

Python数据模型及Pythonic编程

Python时间序列模型推理预测实战:时序推理数据预处理(特征生成lstm输入结构组织)模型加载模型预测结果保存条件判断模型循环运行

python计算多个模型在不同数据集上的预测概率获取每个数据集上的最优模型多个最优模型的ROC曲线进行对比分析

用python+sklearn(机器学习)实现天气预报数据 模型和使用

python 求lna满足给定误差的值

Python数据模型