前面两篇文章介绍了澳大利亚天气数据集的特征工程,将数据处理到了可以建模的程度,本文介绍SVM建模来做天气预测。同时在线性模型基础上,介绍准确率和召回率的平衡调节方法。
代码示例
1、建模和模型评估
from sklearn.svm import SVC from sklearn.metrics import accuracy_score, recall_score, roc_auc_score kernels = ['linear', 'poly', 'rbf', 'sigmoid'] for k in kernels: clf = SVC(kernel=k, degree=1, gamma='auto').fit(x_train, y_train) score = clf.score(x_test, y_test) #准确率 # 其他指标 y_pred = clf.predict(x_test) recall = recall_score(y_test, y_pred) #召回率 auc = roc_auc_score(y_test, clf.decision_function(x_test)) print('%s score:%.3f, recall:%.3f, auc:%.3f' % (k, score, recall, auc)) # linear score:0.831, recall:0.431, auc:0.862 # poly score:0.834, recall:0.422, auc:0.862 # rbf score:0.806, recall:0.308, auc:0.826 # sigmoid score:0.637, recall:0.172, auc:0.437
以上训练结果中,准确率还勉强可以,但recall都不高,而且在特征工程阶段,我们就发现数据存在不均衡的问题。所以下面我们还需要在召回率,准确率,以及两者的平衡方向,继续通过调参来优化模型。
2、追求更高的recall
要追求更高的recall,就要不惜一切代价判断出少数类,以下我们用class_weight=balanced和固定值,来调节权重。
clf = SVC(kernel=k, degree=1, class_weight='balanced', gamma='auto').fit(x_train, y_train) # linear score:0.786, recall:0.749, auc:0.861 # poly score:0.794, recall:0.755, auc:0.862 # rbf score:0.793, recall:0.597, auc:0.825 # sigmoid score:0.501, recall:0.376, auc:0.437 # class_weight={1:10} 表示1类别占10份,隐藏了0:1 clf = SVC(kernel=k, degree=1, class_weight={1: 10}, gamma='auto').fit(x_train, y_train) # linear score:0.636, recall:0.905, auc:0.857 # poly score:0.631, recall:0.910, auc:0.857 # rbf score:0.783, recall:0.575, auc:0.812 # sigmoid score:0.245, recall:1.000, auc:0.437 # 随着class_weight的上升,在线性模型上得到了很高的recall值,但这样调整显然无法得到一个临界值。
3、画ROC曲线
经过前面的尝试,我们发现当前数据集,线性模型的效果最好,所以我们在线性模型的基础上,来画ROC曲线,获得临界阈值。
clf = SVC(kernel='linear', degree=1, class_weight='balanced', gamma='auto').fit(x_train, y_train) from sklearn.metrics import roc_curve import matplotlib.pyplot as plt import numpy as np fpr, tpr, thresholds = roc_curve(y_test, clf.decision_function(x_test)) area = roc_auc_score(y_test, clf.decision_function(x_test)) # 画ROC曲线 # plt.plot(fpr, tpr, label='ROC curve (area=%.3f)' % area) # plt.plot([0, 1], [0, 1], c='k', linestyle='--') # plt.legend() # plt.show()
4、找平衡点threshold
idx = np.argmax(tpr - fpr) threshold = thresholds[idx] # 设定阈值下的预测值 prob = clf.decision_function(x_test) y_pred_t = (prob >= threshold).astype('int') # 计算平衡点的准确率和召回率 score = accuracy_score(y_test, y_pred_t) recall = recall_score(y_test, y_pred_t) print('score:%.3f, recall:%.3f' % (score, recall)) # score:0.801, recall:0.728
至此,这份数据集经过特征处理后,在SVM模型下的效果已经基本到极限了。 如果还想得到更好的效果,可以继续尝试其他模型,但亲测决策树、随机森林、KNN都未能超过SVM的效果。
另一个优化的方向,就是特征工程,但可能要有一定的专业知识,大家有时间还可以继续探索。
本文为 陈华 原创,欢迎转载,但请注明出处:http://ichenhua.cn/read/291
- 上一篇:
- 数据结构之链表类的封装
- 下一篇:
- 数据结构之拉链法创建哈希表