【火炉炼AI】机器学习019-项目案例:使用SVM回归器估算交通流量

【火炉炼AI】机器学习019-项目案例:使用SVM回归器估算交通流量

(本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )

我们都知道,SVM是一个很好地分类器,不仅适用于线性分类模型,而且还适用于非线性模型,但是,在另一方面,SVM不仅可以用于解决分类问题,还可以用于解决回归问题。

本项目打算使用SVM回归器来估算交通流量,所使用的方法和过程与我的上一篇文章【火炉炼AI】机器学习018-项目案例:根据大楼进出人数预测是否举办活动非常类似,所采用的数据处理方法也是大同小异。

1. 准备数据集

本项目所使用的数据集来源于UCI大学数据集,很巧合的是,这个数据集与上一篇文章(大楼进出人数)的数据集位于同一个网页中。

1.1 了解数据集

本数据集统计了洛杉矶Dodgers棒球队在主场比赛期间,体育场周围马路通过的车流量,数据存放在两个文件下:Dodgers.data文件和Dodgers.events文件,这两个文件各列的主要说明为:

Dodgers.data中有50400个样本数据,每一行的基本属性为:

而Dodgers.events文件有中81行数据,每一行数据的基本属性为:

1.2 数据规整

本项目的数据规整主要是将这两个文件中的内容整合到一个可用的数据集中。

1.2.1 规整之一:读取文件错误及其解决办法

本来,我以为读取这两个文件直接用pd.read_csv()即可,就像我以前的多篇文章中用到的一样,然而,本项目中,直接调用该方法读取文件却报错。

# 1 准备数据集
# 从文件中加载数据集
feature_data_path=‘E:\PyProjects\DataSet\BuildingInOut/Dodgers.data‘
feature_set=pd.read_csv(feature_data_path,header=None)
print(feature_set.info())
# print(feature_set.head())
# print(feature_set.tail()) # 检查没有问题

label_data_path=‘E:\PyProjects\DataSet\BuildingInOut/Dodgers.events‘
label_set=pd.read_csv(label_data_path,header=None)
print(label_set.info())
# print(label_set.head())
# print(label_set.tail()) # 读取没有问题,

上面的代码在第二个pd.read_csv()时报以下错误,看来是原始文件的编码出现问题。

-------------------------------------输---------出--------------------------------

UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xa0 in position 5: invalid start byte

--------------------------------------------完-------------------------------------

查看原始Dodger.events文件,我们可以发现,每一行的末尾有一个不能识别的未知字符。

此时我的解决办法是:用记事本将Dodger.events文件打开,在“另存为”中,将编码格式修改为"UTF-8",保存为一个新的文件,此时新文件中就没有了未知字符,如下图所示。

再用pd.read_csv()就没有任何问题。

1.2.2 规整之二:删除缺失数据,拆分数据

由于Dodger.data文件中的样本存在缺失数据,其车流量为-1的表示缺失数据,对缺失数据的处理方式有很多种,此处由于整个样本量比较大,故而我直接将缺失数据删除。另外,由于原始数据中并不全都是用逗号分隔开,故而需要将列进行分隔,代码如下:

# 删除缺失数据
feature_set2=feature_set[feature_set[1]!=-1] # 只获取不是-1的DataFrame即可。
# print(feature_set2) # 没有问题

feature_set2=feature_set2.reset_index(drop=True)
print(feature_set2.head())
# 第0列既包含日期,又包含时间,故要拆分成两列
need_split_col=feature_set2[0].copy()
feature_set2[0]=need_split_col.map(lambda x: x.split()[0].strip())
feature_set2[2]=need_split_col.map(lambda x: x.split()[1].strip())
print(feature_set2.head()) # 拆分没有问题

-------------------------------------输---------出--------------------------------

0 1

0 4/11/2005 7:35 23

1 4/11/2005 7:40 42

2 4/11/2005 7:45 37

3 4/11/2005 7:50 24

4 4/11/2005 7:55 39

0 1 2

0 4/11/2005 23 7:35

1 4/11/2005 42 7:40

2 4/11/2005 37 7:45

3 4/11/2005 24 7:50

4 4/11/2005 39 7:55

--------------------------------------------完-------------------------------------

1.2.3 规整之三:日期格式的统一化

在我们进行这两个DataFrame的合并和日期比较之前,需要先将这两个DataFrame中的日期格式统一化,从两个文件中读取的日期都是String类型,但是从Dodgers.data中读取的日期格式是如4/11/2005的形式,而从Dodgers.events中读取的日期格式是比如:05/01/05形式,显然这两个String之间难以直接比较。幸好Pandas有内置的to_datetime函数,可以直接将这两种日期进行格式统一化。代码为:

# 将两个DataFrame中的日期格式统一,两个DataFrame中的日期目前还是String类型,格式不统一无法比较
feature_set2[0]=pd.to_datetime(feature_set2[0])
print(feature_set2[0][:5]) # 打印第0列的前5行

label_set[0]=pd.to_datetime(label_set[0])
print(label_set[0][:5])

-------------------------------------输---------出--------------------------------

0 2005-04-11

1 2005-04-11

2 2005-04-11

3 2005-04-11

4 2005-04-11

Name: 0, dtype: datetime64[ns]

0 2005-04-12

1 2005-04-13

2 2005-04-15

3 2005-04-16

4 2005-04-17

Name: 0, dtype: datetime64[ns]

--------------------------------------------完-------------------------------------

1.2.4 规整之四:合并两个文件到一个数据集中

在合并文件的时候,我们要知道哪些特征属性是进行机器学习所必须的,此处我们选择的特征列包括有(日期,时间,对手球队名,是否比赛期间),故而我们需要从Dodgers.data文件中选取日期和时间,从Dodger.events文件中选取对手球队名和是否比赛期间的信息,放置到一个数据集中。具体代码如下:

# 合并两个文件到一个数据集中
feature_set2[3]=‘NoName‘ # 对手球队名称暂时用NoName来初始化
feature_set2[4]=0 # 是否比赛期间暂时用否来代替

def calc_mins(time_str):
    nums=time_str.split(‘:‘)
    return 60*int(nums[0])+int(nums[1]) # 将时间转换为分钟数

for row_id,date in enumerate(label_set[0]): # 先取出label中的日期
    temp_df=feature_set2[feature_set2[0]==date]
    if temp_df is None:
        continue

    # 只要这一天有比赛,不管是不是正在比赛,都把对手球队名称写入第3列
    rows=temp_df.index.tolist()
    feature_set2.loc[rows,3]=label_set.iloc[row_id,4]
    start_min=calc_mins(label_set.iloc[row_id,1])
    stop_min=calc_mins(label_set.iloc[row_id,2])
    for row in temp_df[2]: # 在逐一判断时间是否位于label中时间之间
        feature_min=calc_mins(row)
        if feature_min>=start_min and feature_min<=stop_min:
            feature_row=temp_df[temp_df[2]==row].index.tolist()
            feature_set2.loc[feature_row,4]=1 

# feature_set2.to_csv(‘d:/feature_set2_Dodgers.csv‘) # 保存后打印查看没有问题

打开保存的feature_set2_Dodgers.csv,查看发现有很多NoName的行数,这些行数表示当天没有比赛,故而没有对手名。对于NoName样本的处理方式也有多种多用,根据具体的需求不同而不同,可以把它当做ground truth来对待,也可以直接删除,也可以保留作为一种情况来进行训练。此处我直接将其删除。

1.2.5 规整之五:将日期转换为星期数并保存数据集

这部分主要是将日期转换为星期数,并保存数据集到硬盘,方便下次直接读取文件。代码为:

feature_set3=feature_set2[feature_set2[3]!=‘NoName‘].reset_index(drop=True) # 去掉NoName的样本

# 进一步处理,由于日期在以后的日子里不可重复,作为feature并不合适,而可以用星期数来代替,
feature_set3[5]=feature_set3[0].map(lambda x: x.strftime(‘%w‘)) # 将日期转换为星期数
feature_set3=feature_set3.reindex(columns=[0,2,5,3,4,1])
print(feature_set3.tail()) # 查看转换没有问题

feature_set3.to_csv(‘E:\PyProjects\DataSet\BuildingInOut/Dodgers_Sorted_Set.txt‘) # 将整理好的数据集保存,下次可以直接读取

-------------------------------------输---------出--------------------------------

0 2 5 3 4 1

22411 2005-09-29 23:35 4 Arizona 0 9

22412 2005-09-29 23:40 4 Arizona 0 13

22413 2005-09-29 23:45 4 Arizona 0 11

22414 2005-09-29 23:50 4 Arizona 0 14

22415 2005-09-29 23:55 4 Arizona 0 17

--------------------------------------------完-------------------------------------

########################小**********结###############################

1. 这个项目的主要难点也在于数据处理方面,其主要的规整方法和上一篇文章类似。

#################################################################

2. 构建SVM回归模型

使用SVM构建回归模型的关键在于导入SVR模块,而不是分类模型中所用的SVC模块,其SVR所用的参数也需要做相应的调整,此处够安静SVM回归模型的代码为:

from sklearn.svm import SVR # 此处不一样,导入的是SVR而不是SVC
regressor = SVR(kernel=‘rbf‘,C=10.0,epsilon=0.2) # 这些参数是优化得来
regressor.fit(train_X, train_y)

-------------------------------------输---------出--------------------------------

SVR(C=10.0, cache_size=200, coef0=0.0, degree=3, epsilon=0.2, gamma=‘auto‘,

kernel=‘rbf‘, max_iter=-1, shrinking=True, tol=0.001, verbose=False)

--------------------------------------------完-------------------------------------

在对模型进行定义和训练之后,就需要使用测试集对模型进行测试,如下是测试代码和输出结果:

y_predict_test=regressor.predict(test_X)
# 使用评价指标来评估模型的好坏
import sklearn.metrics as metrics
print(‘平均绝对误差:{}‘.format(
    round(metrics.mean_absolute_error(y_predict_test,test_y),2)))
print(‘均方误差MSE:{}‘.format(
    round(metrics.mean_squared_error(y_predict_test,test_y),2)))
print(‘中位数绝对误差:{}‘.format(
    round(metrics.median_absolute_error(y_predict_test,test_y),2)))
print(‘解释方差分:{}‘.format(
    round(metrics.explained_variance_score(y_predict_test,test_y),2)))
print(‘R方得分:{}‘.format(
    round(metrics.r2_score(y_predict_test,test_y),2)))

-------------------------------------输---------出--------------------------------

平均绝对误差:5.16

均方误差MSE:50.45

中位数绝对误差:3.75

解释方差分:0.63

R方得分:0.62

--------------------------------------------完-------------------------------------

貌似结果不太好,可能SVR中的参数还需要进一步优化.

很多朋友给我留言,问我训练好的SVM模型如何保存和重新调用,这部分内容去我在前面的文章中已经介绍过了,具体请看:【火炉炼AI】机器学习003-简单线性回归器的创建,测试,模型保存和加载

注:本部分代码已经全部上传到(我的github)上,欢迎下载。

参考资料:

1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译

原文地址:https://www.cnblogs.com/RayDean/p/9765703.html

时间: 2024-10-08 01:07:42

【火炉炼AI】机器学习019-项目案例:使用SVM回归器估算交通流量的相关文章

【火炉炼AI】机器学习018-项目案例:根据大楼进出人数预测是否举办活动

[火炉炼AI]机器学习018-项目案例:根据大楼进出人数预测是否举办活动 (本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 我们经常看到办公大楼中人来人往,进进出出,在平时没有什么活动的时候,进出大楼的人数会非常少,而一旦举办有大型商业活动,则人山人海,熙熙攘攘,所以很明显,大楼进出的人数和大楼是否举办活动有很明显的关联,那么,是否可以构建一个模型,通过大楼进出人数来预测该大楼是否在举办

【火炉炼AI】机器学习006-用决策树回归器构建房价评估模型

[火炉炼AI]机器学习006-用决策树回归器构建房价评估模型 (本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 最近几十年,房价一直是中国老百姓心中永远的痛,有人说,中国房价就像女人的无肩带文胸,一半人在疑惑:是什么支撑了它?另一半人在等待:什么时候掉下去? 而女人,永不可能让它掉下来.就算快掉下来了,提一提还是又上去了..... 虽然我们不能预测中国房价什么时候崩盘,但是却可以用机器学

【火炉炼AI】机器学习007-用随机森林构建共享单车需求预测模型

[火炉炼AI]机器学习007-用随机森林构建共享单车需求预测模型 (本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 共享单车是最近几年才发展起来的一种便民交通工具,基本上是我等屌丝上班,下班,相亲,泡妞必备神器.本项目拟使用随机森林回归器构建共享单车需求预测模型,从而查看各种不同的条件下,共享单车的需求量. 1. 准备数据集 本次使用的数据集来源于加利福尼亚大学欧文分校(UCI)大学的公

【火炉炼AI】机器学习042-NLP文本的主题建模

[火炉炼AI]机器学习042-NLP文本的主题建模 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, NLTK 3.3) 文本的主题建模时用NLP来识别文本文档中隐藏的某种模式的过程,可以发现该文档的隐藏主题,以便对文档进行分析.主题建模的实现过程是,识别出某文本文档中最有意义,最能表征主题的词来实现主题分类,即寻找文本文档中的关键词,通过关键词就可以识别出某文档的隐藏主题. 1. 准备数

【火炉炼AI】机器学习048-Harris检测图像角点

[火炉炼AI]机器学习048-Harris检测图像角点 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 角点检测算法大致有三类:基于灰度图像的角点检测,基于二值图像的角点检测,基于轮廓曲线的角点检测.基于灰度图像的角点检测又可分为基于梯度.基于模板和基于模板梯度组合3类方法,其中基于模板的方法主要考虑像素领域点的灰度变化,即图像亮度的变化,将与邻点亮度对比足够大的点定义为角点.常见的基

【火炉炼AI】机器学习017-使用GridSearch搜索最佳参数组合

[火炉炼AI]机器学习017-使用GridSearch搜索最佳参数组合 (本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 在前面的文章([火炉炼AI]机器学习012-用随机森林构建汽车评估模型及模型的优化提升方法),我们使用了验证曲线来优化模型的超参数,但是使用验证曲线难以同时优化多个参数的取值,只能一个参数一个参数的优化,从而获取每个参数的最优值,但是有时候,一个非常优秀的模型,可能A

【火炉炼AI】机器学习046-图像边缘的检测方法

[火炉炼AI]机器学习046-图像边缘的检测方法 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 图像中各种形状的检测时计算机视觉领域中非常常见的技术之一,特别是图像中直线的检测,圆的检测,图像边缘的检测等,下面我们来研究一下如何快速检测图像边缘. 边缘是不同区域的分界线,是周围(局部)像素有显著变化的像素的集合,有幅值与方向两个属性.这个不是绝对的定义,主要记住边缘是局部特征以及周围

【火炉炼AI】机器学习050-提取图像的Star特征

[火炉炼AI]机器学习050-提取图像的Star特征 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 对于图像的特征点,前面我们讨论过边缘检测方法,Harris角点检测算法等,这些检测算法检测的都是图像的轮廓边缘,而不是内部细节,如果要进一步提取图像内部细节方面的特征,需要用到SIFT特征提取器和Star特征提取器.上一篇我们讲解了SIFT特征提取器,下面我们来介绍Star特征提取器.

【火炉炼AI】深度学习005-简单几行Keras代码解决二分类问题

[火炉炼AI]深度学习005-简单几行Keras代码解决二分类问题 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, Keras 2.1.6, Tensorflow 1.9.0) 很多文章和教材都是用MNIST数据集作为深度学习届的"Hello World"程序,但是这个数据集有一个很大的特点:它是一个典型的多分类问题(一共有10个分类),在我们刚刚开始接触深度学习时,我倒是觉得