import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#用来划分训练集和测试集
from sklearn.model_selection import train_test_split
#用来为各种算法计时
import time
接下来读取数据,并对数据进行观察。
data = pd.read_csv("weatherAUS.csv")
data.head()
该数据集包含来自澳大利亚多个气象站的每日天气观测。 目标变量RainTomorrow的意思是:第二天下雨了吗?“是”或“否”。 下面我们将通过对目标RainTomorrow训练一个二元分类模型来预测明天是否会下雨。 在训练二元分类模型时,应该排除RISK_MM。不排除它将泄露模型的答案并降低其可预测性。
#去除RISK_MM变量
del data['RISK_MM']
#观察数据维度
data.shape
可以发现,在上面的数据框有不少的缺失值(NaN),对这些缺失值的处理会在很大程度上影响模型的准确性。
#查看各列缺失值情况
naVariable = pd.isna(data).sum()/data.shape[0]
plt.hist(x = naVariable,
bins = 10,
color = 'steelblue',
edgecolor = 'black'
)
可以看到,很多变量缺失值占15%以内,部分变量缺失值占35%以上。 所以简单起见,我们的处理方法是先去除缺失值占比35%以上的变量(删除列),再从剩下的数据中去除含有缺失值的观测(删除行)。
#删除缺失35%以上的列
data.drop(list(naVariable[naVariable>0.35].index), axis=1, inplace=True)
#删除带有缺失值的行
data.dropna(axis=0, how='any', inplace=True)
data.shape
可以看到,与上面的(142193, 23)相比,处理后的数据并没有损失很多,我们将在此基础上继续进行分析。
#查看变量类型
data.dtypes
可以看到,部分变量为字符串,我们需要将其转换为对应的数值,相当于分类(因子)变量。 下面,我们划分自变量与因变量并完成这一转换工作。
#自变量
X = data.iloc[:,0:(data.shape[1])-1]
#处理日期型数据
X['Date']= pd.to_datetime(X['Date'])
#提取年月日
X['year']=X['Date'].dt.year
X['month']=X['Date'].dt.month
X['day']=X['Date'].dt.day
del X['Date']
#转换为分类变量
for nominal in list(X.dtypes[X.dtypes==object].index):
class_mapping = {label:idx for idx,label in enumerate(set(X[nominal]))}
X[nominal] = X[nominal].map(class_mapping)
X = X.apply(lambda x: (x - np.min(x)) / (np.max(x) - np.min(x)))
#因变量
y = data['RainTomorrow']
y = pd.get_dummies(y, prefix='Rain').iloc[:,1]
为对各种算法模型的表现进行评估,我们按照0.8:0.2的比例划分训练集和测试集。
#划分训练集和测试集
train_X, test_X, train_y, test_y = train_test_split(X,
y,
test_size = 0.2,
random_state = 0)
results = pd.DataFrame()
time_consumption = []
首先是线性回归模型,由于回归模型的输出结果是连续型变量,所以我们将大于0.5的值标记为1,小于0.5的值标记为0。
start = time.time()
from sklearn.linear_model import LinearRegression
regression_m = LinearRegression()
regression_m.fit(train_X, train_y)
results['regression_r'] = (regression_m.predict(test_X)>0.5).astype("int")
end = time.time()
time_consumption.append(end - start)
神经网络模型,隐含层维度(5, 3),事实上这一参数明显会影响到模型预测结果。
from sklearn.neural_network import MLPClassifier
start = time.time()
neural_m = MLPClassifier(alpha=1e-5, hidden_layer_sizes=(5, 3))
neural_m.fit(train_X, train_y)
results['neural_m_r'] = neural_m.predict(test_X)
end = time.time()
time_consumption.append(end - start)
KNN模型,n_neighbors参数为邻居个数,这里选取为3。
from sklearn import neighbors
start = time.time()
knn_m = neighbors.KNeighborsClassifier(n_neighbors=3)
knn_m.fit(train_X, train_y)
results['knn_m_r'] = knn_m.predict(test_X)
end = time.time()
time_consumption.append(end - start)
决策树模型
from sklearn.tree import DecisionTreeClassifier
start = time.time()
tree_m = DecisionTreeClassifier()
tree_m.fit(train_X,train_y)
results['tree_r'] = tree_m.predict(test_X)
end = time.time()
time_consumption.append(end - start)
随机森林模型
from sklearn.ensemble import RandomForestClassifier
start = time.time()
forest_m = RandomForestClassifier()
forest_m.fit(train_X,train_y)
results['forest_r'] = forest_m.predict(test_X)
end = time.time()
time_consumption.append(end - start)
支持向量机
from sklearn.svm import LinearSVC
start = time.time()
SVC_m = LinearSVC()
SVC_m.fit(train_X, train_y)
results['SVC_r'] = SVC_m.predict(test_X)
end = time.time()
time_consumption.append(end - start)
计算各种模型的评价指标,包括精确率(precision)、召回率(recall)、准确率(准确率)以及F1分数(F1_Score)。 最后将运行所用时间添加进去。
evaluations = pd.DataFrame()
from sklearn.metrics import *
for i in range(0, results.shape[1]):
evaluation = {"precision": precision_score(test_y, results.iloc[:,i]),
"recall": recall_score(test_y, results.iloc[:,i]),
"accuracy": accuracy_score(test_y, results.iloc[:,i]),
"f1": f1_score(test_y, results.iloc[:,i])}
evaluations = evaluations.append(evaluation, ignore_index=True)
evaluations.rename(index=dict(zip(range(0, evaluations.shape[0]),
list(results.columns))),inplace=True)
evaluations.insert(0, 'time/s', time_consumption)
查看评价指标。
evaluations
通过上表可以看出,神经网络模型和KNN模型所用的时间较长,执行速度较慢。其他算法速度均较快。 从预测结果来说,各个模型相差不大,神经网络模型和支持向量机模型效果较好,KNN和决策树模型效果较差。 因此,如果对程序的执行速度有严格要求,选择线性回归模型是明智的做法;如果综合考虑,个人认为支持向量机是适合于该数据集的最佳模型。
当然,以上粗略的比较并不能说明算法本身的优劣,各种评价指标与数据集有很大关联。 另外,上面大多使用的是各种模型默认的参数配置,相信通过调节各种参数,能够提高模型的预测性能。
数据:
链接:https://pan.baidu.com/s/1RWw93h-gLSAKr-TzyGBrwQ
提取码:dy5v