实验内容
我们将建立一个SVM来根据相关数据预测交通流量。
准备工作
我们将要使用的数据集可以在https://archive.ics.uci.edu/ml/datasets/Dodgers+Loop+Sensor下 载。这个数据集统计了洛杉矶道奇棒球队(Los Angeles Dodgers)进行主场比赛期间,体育场周 边马路通过的车辆数量,存放在traffic_data.txt文件中。每一行都包含用逗号分隔的字符串格式。
详细步骤
# 使用SVM估计交通流量
import numpy as np
from sklearn import preprocessing
from sklearn.svm import SVR
input_file = 'traffic_data.txt'
# 读取数据
X = []
# X矩阵中包含了traffic_data.txt的所有数据
'''
[['Tuesday' '00:00' 'San Francisco' 'no' '3']
['Tuesday' '00:05' 'San Francisco' 'no' '8']
['Tuesday' '00:10' 'San Francisco' 'no' '10']
...
['Thursday' '23:45' 'Arizona' 'no' '11']
['Thursday' '23:50' 'Arizona' 'no' '14']
['Thursday' '23:55' 'Arizona' 'no' '17']]
'''
count = 0
with open(input_file, 'r') as f:
for line in f.readlines():
data = line[:-1].split(',')
X.append(data)
X = np.array(X)
print("####################")
# 将数据标记编码
label_encoder = []
X_encoded = np.empty(X.shape) # X.shape代表矩阵的形状,即几行几列。转换后的数据集全部放到X_encoded中
for i,item in enumerate(X[0]):
if item.isdigit():
X_encoded[:, i] = X[:, i]
else:
label_encoder.append(preprocessing.LabelEncoder()) # 需要为每个属性使用不同的标记编码器
X_encoded[:, i] = label_encoder[-1].fit_transform(X[:, i])
X = X_encoded[:, :-1].astype(int) # 除了最后一个值外的所有值赋给X
y = X_encoded[:, -1].astype(int) # 每一行最后一个值是流量大小,赋值给变量y
# 建立SVR
params = {'kernel': 'rbf', 'C': 10.0, 'epsilon': 0.2} # 使用径向基函数,C惩罚系数,
regressor = SVR(**params)
regressor.fit(X, y)
# 交叉验证
import sklearn.metrics as sm
y_pred = regressor.predict(X)
print("Mean absolute error =", round(sm.mean_absolute_error(y, y_pred), 2))
# 对单一数据示例进行编码测试
input_data = ['Tuesday', '13:35', 'San Francisco', 'yes']
input_data_encoded = [-1] * len(input_data)
count = 0
# 对测试数据进行标记编码
for i,item in enumerate(input_data):
if item.isdigit():
input_data_encoded[i] = int(input_data[i])
else:
input_data_encoded[i] = int(label_encoder[count].transform([input_data[i]]))
count = count + 1
input_data_encoded = np.array(input_data_encoded)
input_data_encoded = input_data_encoded.reshape(1, len(input_data))
# 为特定数据点预测并打印分类结果
print("Predicted traffic:", int(regressor.predict(input_data_encoded)[0])) # 保留预测结果的整数部分