1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
|
import numpy as np
import pandas as pd
# 绘图函数库
import seaborn as sns
# 为了正确评估模型性能,将数据划分为训练集和测试集,并在训练集上训练模型,在测试集上验证模型性能。
from sklearn.model_selection import train_test_split
# 导入XGBoost模型
from xgboost.sklearn import XGBClassifier
from sklearn.metrics import accuracy_score
from xgboost import plot_importance
# 从sklearn库中导入网格调参函数
from sklearn.model_selection import GridSearchCV
from sklearn import metrics
import matplotlib
from matplotlib import pyplot as plt
# 我们利用Pandas自带的read_csv函数读取并转化为DataFrame格式
data = pd.read_csv("../Data/weather/train.csv")
# 利用.info()查看数据的整体信息
print(data.info())
# 用-1填补NaN值
data = data.fillna(-1)
# 利用value_counts函数查看训练集标签的数量
pd.Series(data['RainTomorrow']).value_counts()
# 对于特征进行一些统计描述, 均值、标准差、最小值等
print(data.describe())
# 获得每一列的数据是浮点数的列名
numerical_features = [x for x in data.columns if data[x].dtype == np.float]
# 获得每一列的数据不是浮点数且不是RainTomorrow的列名,RainTomorrow是明天是否下雨的布尔值,即标签值
category_features = [x for x in data.columns if data[x].dtype != np.float and x != 'RainTomorrow']
# 选取三个特征与标签组合的散点可视化,
# 三个参数为:数据、画图的类型选择直方图、色彩(以RainTomorrow值的种类为颜色种类进行画图)
sns.pairplot(data=data[['Rainfall', 'Evaporation', 'Sunshine'] + ['RainTomorrow']],
diag_kind='hist', hue='RainTomorrow')
# 弹出画好的图
plt.show()
# 获取每一列的数据是浮点数的列名
for col in data[numerical_features].columns:
if col != 'RainTomorrow':
# 画箱型图,x轴为RainTomorrow值,y轴为col值,saturation为色彩饱和度
sns.boxplot(x='RainTomorrow', y=col,
saturation=0.5, palette='pastel', data=data)
plt.title(col) # 设置图上方的标题
plt.show()
tlog = {}
for i in category_features:
# 利用value_counts函数查看在训练集标签为yes中,
# 列表category_features里的每个列名下数据的数量个数
tlog[i] = data[data['RainTomorrow'] == 'Yes'][i].value_counts()
flog = {}
for i in category_features:
# 利用value_counts函数查看在训练集标签为no中,
# 列表category_features里的每个列名下数据的数量个数
flog[i] = data[data['RainTomorrow'] == 'No'][i].value_counts()
# 准备一张10x10的图,准备作画
plt.figure(figsize=(10, 10))
# 在一行两列的图中,第一个位置(大小为10x5)作画
plt.subplot(1, 2, 1)
# 在第一个位置的图写上标题RainTomorrow
plt.title('RainTomorrow')
# 画上条形图,x值为tlog(明天下雨)中的地区值数量大小进行排序后的值,
# y为对应排序后的地区值,颜色为红色
sns.barplot(x=pd.DataFrame(tlog['Location']).sort_index()['Location'],
y=pd.DataFrame(tlog['Location']).sort_index().index,
color="red")
# 在一行两列的图中,第二个位置(大小为10x5)作画
plt.subplot(1, 2, 2)
# 在第一个位置的图写上标题
plt.title('Not RainTomorrow')
# 画上条形图,x值为flog(明天不下雨)中的地区值数量大小进行排序后的值,
# y为对应排序后的地区值,颜色为蓝色
sns.barplot(x=pd.DataFrame(flog['Location']).sort_index()['Location'],
y=pd.DataFrame(flog['Location']).sort_index().index,
color="blue")
plt.show()
# 准备一张10x2的图,准备作画
plt.figure(figsize=(10, 2))
# 在一行两列的图中,第一个位置(大小为10x1)作画
plt.subplot(1, 2, 1)
# 在第一个位置的图写上标题RainToday
plt.title('RainToday')
# 画上条形图,x值为tlog(今天下雨)中的地区值数量大小进行排序后的值,
# y为对应排序后的地区值,颜色为红色
sns.barplot(x=pd.DataFrame(tlog['RainToday'][:2]).sort_index()['RainToday'],
y=pd.DataFrame(tlog['RainToday'][:2]).sort_index().index,
color="red")
plt.subplot(1, 2, 2)
plt.title('Not RainToday')
# 画上条形图,x值为tlog(今天不下雨)中的地区值数量大小进行排序后的值,
# y为对应排序后的地区值,颜色为蓝色
sns.barplot(x=pd.DataFrame(flog['RainToday'][:2]).sort_index()['RainToday'],
y=pd.DataFrame(flog['RainToday'][:2]).sort_index().index,
color="blue")
plt.show()
# 把所有的相同类别的特征编码为同一个值,即将字符串编码成数字
def get_mapfunction(x):
mapp = dict(zip(x.unique().tolist(), range(len(x.unique().tolist()))))
def mapfunction(y):
if y in mapp:
return mapp[y]
else:
return -1
return mapfunction
# 把不是浮点数且不是RainTomorrow的每列的数据中所有的相同类别的特征编码为同一个值
# 首先执行get_mapfunction()函数,然后返回mapfunction()函数,最后将data[i]中
# 的各个数apply()到mapfunction()函数
for i in category_features:
data[i] = data[i].apply(get_mapfunction(data[i]))
# 编码后的字符串特征变成了数字
data['Location'].unique()
# 选择其类别为0和1的样本(即是否下雨,No和Yes)
data_target_part = data['RainTomorrow']
data_features_part = data[[x for x in data.columns if x != 'RainTomorrow']]
# 测试集大小为20%,训练集大小为80%
x_train, x_test, y_train, y_test = train_test_split(data_features_part,
data_target_part,
test_size=0.2,
random_state=2020)
# --------------------使用默认参数进行模型训练---------------------------
# 定义 XGBoost模型
clf = XGBClassifier()
# 在训练集上训练XGBoost模型
clf.fit(x_train, y_train)
# 在训练集和测试集上分布利用训练好的模型进行预测
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)
# 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
print('The accuracy of the Logistic Regression is:',
metrics.accuracy_score(y_train, train_predict)) # 0.89824767039793
print('The accuracy of the Logistic Regression is:',
metrics.accuracy_score(y_test, test_predict)) # 0.85751793333020
# 查看混淆矩阵 (预测值和真实值的各类情况统计矩阵)
confusion_matrix_result = metrics.confusion_matrix(test_predict, y_test)
print('The confusion matrix result:\n', confusion_matrix_result)
# 利用热力图对于结果进行可视化
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()
sns.barplot(y=data_features_part.columns, x=clf.feature_importances_)
# -------------------绘制对应列(即特征)的重要性图-----------------------
def estimate(model, data):
# sns.barplot(data.columns,model.feature_importances_)
ax1 = plot_importance(model, importance_type="gain")
ax1.set_title('gain')
ax2 = plot_importance(model, importance_type="weight")
ax2.set_title('weight')
ax3 = plot_importance(model, importance_type="cover")
ax3.set_title('cover')
plt.show()
def classes(data, label, test):
model = XGBClassifier()
model.fit(data, label)
ans = model.predict(test)
estimate(model, data)
return ans
ans = classes(x_train, y_train, x_test)
pre = accuracy_score(y_test, ans)
print('acc=', accuracy_score(y_test, ans))
# ------------------以下进行网格搜索并用最优参数进行训练------------------------
# 定义参数取值范围
learning_rate = [0.1, 0.3, 0.6]
subsample = [0.8, 0.9]
colsample_bytree = [0.6, 0.8]
max_depth = [3, 5, 8]
parameters = {'learning_rate': learning_rate,
'subsample': subsample,
'colsample_bytree': colsample_bytree,
'max_depth': max_depth}
model = XGBClassifier(n_estimators=50)
# 进行网格搜索
clf_grid = GridSearchCV(model, parameters, cv=3, scoring='accuracy',
verbose=1, n_jobs=-1)
clf_grid = clf_grid.fit(x_train, y_train)
# 网格搜索后的最好参数为
print(clf_grid.best_params_)
# 在训练集和测试集上分布利用最好的模型参数进行预测
# 定义带参数的 XGBoost模型
clf_grid = XGBClassifier(colsample_bytree=0.6, learning_rate=0.1,
max_depth=8, subsample=0.8)
# 在训练集上训练XGBoost模型
clf_grid.fit(x_train, y_train)
train_predict = clf_grid.predict(x_train)
test_predict = clf_grid.predict(x_test)
# 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果,
# 应用网格搜索之后准确率稍有提高,但不明显
print('The accuracy of the Logistic Regression is:',
metrics.accuracy_score(y_train, train_predict)) # 0.89923225693019
print('The accuracy of the Logistic Regression is:',
metrics.accuracy_score(y_test, test_predict)) # 0.85676778095550
# 查看混淆矩阵 (预测值和真实值的各类情况统计矩阵)
confusion_matrix_result = metrics.confusion_matrix(test_predict, y_test)
print('The confusion matrix result:\n', confusion_matrix_result)
# 利用热力图对于结果进行可视化
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()
|