TPOT分析水文数据

1. 水文数据集

https://data.edmonton.ca/dataset/Water-Levels-and-Flows/cnsu-iagr

###该数据集一共9个属性:
1.Raw ID 
2.Station Number => 水文站编号  --26 --离散值
3.Station Description => 水文站描述 --26 --文本信息
4.Latitude => 纬度 --28 --离散值
5.Longitude => 经度 --28 --离散值
6.Station Location => 水文站位置,由经纬度组合而成  --28 --离散值
7.Date and Time => 时间
8.Water Level (m) => 水位 -- --连续值
9.Water Flow (cu meter per sec) => 流速 -- --连续值

因为TPOT只能处理数值类型,在我们的数据集中,有4个变量不是数值类型:
Station Number, Station Description, Station Location, Date and Time
所以,下面重点是处理这几个变量;

###数据预处理:
1.Station Number
离散值,有26个可选,使用one-hot编码

2.Station Description, Station Location, Raw ID
无用信息,删除

3.Date and Time
分析数据,从2016年到2019年,所以年份不敏感;
拆分为月,日和小时

4.Latitude和Longitude可能缺失
总的记录数:
(3910803, 9)

非空记录数:
(1975617, 9)

5.经纬度缺失的数据量很大,所以不能直接舍弃;
首先计算水文站经纬度的平均值,用这个来代替

6.Water Flow (cu meter per sec)可能非法,例如-1, 删除这些记录

2. 代码

from tpot import TPOTRegressor
from sklearn.model_selection import train_test_split
import pandas as pd
import numpy as np
import os
from tensorflow.python.client import device_lib

os.environ["CUDA_VISIBLE_DEVICES"] = "1"
print(device_lib.list_local_devices())

df = pd.read_csv('Water_Levels_and_Flows.csv.1w', header=0,error_bad_lines=False)
print(df.head(5))
print(df.shape)
print(pd.isnull(df).any())

#删除Water_Flow为负的行
print('删除Water_Flow无效行')
df=df[~(df['Water_Flow']<0)]
print(df.shape)

mean_longitude = df.groupby('Station Number').Longitude.mean()
mean_latitude = df.groupby('Station Number').Latitude.mean()
null_longitude = df[df.Longitude.isnull()]

for cat in ['Station Number', 'Station Description', 'Latitude', 'Longitude' ]:
    print("Number of levels in category '{0}': \b {1:2.2f} ".format(cat, df[cat].unique().size))

for cat in ['Latitude', 'Longitude']:
    print("Levels for catgeory '{0}': {1}".format(cat, df[cat].unique()))

#删掉无关因素
df = df.drop(['id', 'Station Description','Station Location', 'Latitude', 'Longitude'],axis=1) # axis=0 删除行,=1 删除列

#将Station用哑变量表示
dumm = pd.get_dummies(df[['Station Number']]) # '哑变量'矩阵
df = df.join(dumm)
del df['Station Number'] # 删除

#添加month,day,hour三个键和值
temp=pd.DatetimeIndex(df['Date and Time'])
df['date']=temp.date
df['time']=temp.time
df['hour']=pd.to_datetime(df.time,format="%H:%M:%S")#变换格式
df['hour']=pd.Index(df["hour"]).hour
df['month']=pd.to_datetime(df.date,format="%Y-%m-%d")#变换格式
df['month']=pd.Index(df["month"]).month
df['day']=pd.to_datetime(df.date,format="%Y-%m-%d")#变换格式
df['day']=pd.Index(df["day"]).day
df = df.drop(['Date and Time', 'date', 'time'],axis=1) # axis=0 删除行,=1 删除列
print(df.head(5))
print(df.shape)

X = np.array(df.drop(['Water_Level'], 1))
Y = np.array(df['Water_Level'])
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2)

tpot = TPOTRegressor(generations=20, verbosity=2) #迭代20次
tpot.fit(X_train, y_train)
print(tpot.score(X_test, y_test))
tpot.export('pipeline.py')

3. 运行TPOT

因为执行时间过长,所以使用后台运行方式:

nohup python -u water_tpot.py > nohup.out 2>&1 &

输出如下:

Generation 1 - Current best internal CV score: -0.10354635942452688
Generation 2 - Current best internal CV score: -0.07407627082459693
Generation 3 - Current best internal CV score: -0.07407627082459693
Generation 4 - Current best internal CV score: -0.07407627082459693
Generation 5 - Current best internal CV score: -0.07261441673202419
Generation 6 - Current best internal CV score: -0.07261441673202419
Generation 7 - Current best internal CV score: -0.07261441673202419
Generation 8 - Current best internal CV score: -0.06272878450716013
Generation 9 - Current best internal CV score: -0.06150379726583473
Generation 10 - Current best internal CV score: -0.06150379726583473
Generation 11 - Current best internal CV score: -0.06150379726583473
Generation 12 - Current best internal CV score: -0.05930206668688394
Generation 13 - Current best internal CV score: -0.054799951152979184
Generation 14 - Current best internal CV score: -0.054799951152979184
Generation 15 - Current best internal CV score: -0.052015877476651276
Generation 16 - Current best internal CV score: -0.052015877476651276
Generation 17 - Current best internal CV score: -0.05173009225925466
Generation 18 - Current best internal CV score: -0.043718068024817355
Generation 19 - Current best internal CV score: -0.043718068024817355
Generation 20 - Current best internal CV score: -0.043718068024817355
Best pipeline: ExtraTreesRegressor(SelectPercentile(DecisionTreeRegressor(ElasticNetCV(input_matrix, l1_ratio=0.7000000000000001, tol=1e-05), max_depth=1, min_samples_leaf=2, min_samples_split=15), percentile=94), bootstrap=False, max_features=1.0, min_samples_leaf=2, min_samples_split=2, n_estimators=100)
-0.027241579610884296

TPOT认为ExtraTreesRegressor是最好的模型,并导出pipeline.py。

4. 运行pipeline

导出的pipeline.py文件需要根据实际情况修改如下:

import numpy as np
import pandas as pd
from sklearn.ensemble import ExtraTreesRegressor
from sklearn.feature_selection import SelectPercentile, f_regression
from sklearn.linear_model import ElasticNetCV
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline, make_union
from sklearn.tree import DecisionTreeRegressor
from tpot.builtins import StackingEstimator

# NOTE: Make sure that the class is labeled 'target' in the data file
df = pd.read_csv('Water_Levels_and_Flows.csv.1w', sep=',', header=0,error_bad_lines=False)
#删除Water_Flow为负的行
print('删除Water_Flow无效行')
df=df[~(df['Water_Flow']<0)]
print(df.shape)

mean_longitude = df.groupby('Station Number').Longitude.mean()
mean_latitude = df.groupby('Station Number').Latitude.mean()
null_longitude = df[df.Longitude.isnull()]

for cat in ['Station Number', 'Station Description', 'Latitude', 'Longitude' ]:
    print("Number of levels in category '{0}': \b {1:2.2f} ".format(cat, df[cat].unique().size))

for cat in ['Latitude', 'Longitude']:
    print("Levels for catgeory '{0}': {1}".format(cat, df[cat].unique()))

#删掉无关因素
df = df.drop(['id', 'Station Description','Station Location', 'Latitude', 'Longitude'],axis=1) # axis=0 删除行,=1 删除列

#将Station用哑变量表示
dumm = pd.get_dummies(df[['Station Number']]) # '哑变量'矩阵
df = df.join(dumm)
del df['Station Number'] # 删除

#添加month,day,hour三个键和值
temp=pd.DatetimeIndex(df['Date and Time'])
df['date']=temp.date
df['time']=temp.time
df['hour']=pd.to_datetime(df.time,format="%H:%M:%S")#变换格式
df['hour']=pd.Index(df["hour"]).hour
df['month']=pd.to_datetime(df.date,format="%Y-%m-%d")#变换格式
df['month']=pd.Index(df["month"]).month
df['day']=pd.to_datetime(df.date,format="%Y-%m-%d")#变换格式
df['day']=pd.Index(df["day"]).day
df = df.drop(['Date and Time', 'date', 'time'],axis=1) # axis=0 删除行,=1 删除列
print(df.head(5))
print(df.shape)


X = np.array(df.drop(['Water_Level'], 1))
Y = np.array(df['Water_Level'])
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2)

training_features, testing_features, training_target, testing_target = \
            train_test_split(X, Y, random_state=None)

# Average CV score on the training set was:-0.043718068024817355
exported_pipeline = make_pipeline(
    StackingEstimator(estimator=ElasticNetCV(l1_ratio=0.7000000000000001, tol=1e-05)),
    StackingEstimator(estimator=DecisionTreeRegressor(max_depth=1, min_samples_leaf=2, min_samples_split=15)),
    SelectPercentile(score_func=f_regression, percentile=94),
    ExtraTreesRegressor(bootstrap=False, max_features=1.0, min_samples_leaf=2, min_samples_split=2, n_estimators=100)
)

exported_pipeline.fit(training_features, training_target)
results = exported_pipeline.predict(testing_features)
print("results: %s"%results)
score = exported_pipeline.score(testing_features, testing_target)
print("score: %s"%score)

同样,在后台运行:

nohup python -u pipeline.py > nohup.out 2>&1 &

输出如下:

results: [7.1012806  1.25462311 0.73743519 ... 2.12231535 4.22561277 1.27338528]
score: 0.9999991261258582

5. GPU

可惜的是,目前TPOT不支持GPU:
https://github.com/EpistasisLab/tpot/issues/680

不过,实际应用中我们发现,只是GPU-Util为0, GPU Memory Usage仍然可以达到10440MiB


屏幕快照 2019-01-30 下午6.32.55.png

6. 速度

TPOT在处理小规模数据的时候非常快,结果很给力。但处理大规模的数据问题,速度非常慢。所以可以尝试在数据清洗之后,抽样小部分数据跑一下TPOT,能得到一个还不错的算法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,370评论 0 5
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,725评论 0 10
  • 简评:随着自由职业者的增多,在家工作的人越来越多。这种灵活性似乎是个好主意,但很多人却发现这种模式很难管理时间。在...
    极小光阅读 2,662评论 0 8
  • 寒秋,连天的雨,反复洗刷着我所住的小城,房前屋后的水泥路面,闪着粗糙的冷光。 父亲,在我母亲病逝后的五年,就...
    东园一姝梅阅读 284评论 0 0
  • 海阔凭鱼跃,天高任鸟飞! 行动营,又让我开阔了眼界,涨了新姿势。认识了一条在文山案海里随意跃动的鱼,他带领我们遨游...
    岁月追逐者阅读 935评论 18 12