文章目录
一.Python代码
#!/usr/bin/env python3
# encoding: utf-8
'''
@file: classifierRidgeRocksVMines.py
@time: 2020/5/31 0031 18:39
@author: Jack
@contact: jack18588951684@163.com
'''
import urllib.request
import numpy as np
from sklearn import datasets, linear_model
from sklearn.metrics import roc_curve, auc
import pylab as plt
## 读取数据集
target_url = ("https://archive.ics.uci.edu/ml/machine-learning-databases/undocumented/connectionist-bench/sonar/sonar.all-data")
data = urllib.request.urlopen(target_url)
xList = []
labels = []
for line in data:
row = str(line, encoding='utf-8').strip().split(",")
# assign label 1.0 for "M" and 0.0 for "R"
if row[-1] == 'M':
labels.append(1.0)
else:
labels.append(0.0)
# remove lable from row
row.pop()
# convert row to floats
floatRow = [float(num) for num in row]
xList.append(floatRow)
## 将属性矩阵和label分成训练集training set(2/3 of data)和测试集test sets (1/3 of data)
indices = range(len(xList))
xListTest = [xList[i] for i in indices if i % 3 == 0]
xListTrain = [xList[i] for i in indices if i % 3 != 0]
labelsTest = [labels[i] for i in indices if i % 3 == 0]
labelsTrain = [labels[i] for i in indices if i % 3 != 0]
## form list of list input into numpy arrays to match input class for scikit-learn linear model
xTrain = np.array(xListTrain)
yTrain = np.array(labelsTrain)
xTest = np.array(xListTest)
yTest = np.array(labelsTest)
alphaList = [0.1 ** i for i in [-3, -2, -1, 0, 1, 2, 3, 4, 5]]
aucList = []
for alph in alphaList:
rocksVMinesRidgeModel = linear_model.Ridge(alpha=alph)
rocksVMinesRidgeModel.fit(xTrain, yTrain)
fpr, tpr, thresholds = roc_curve(yTest, rocksVMinesRidgeModel.predict(xTest))
roc_auc = auc(fpr, tpr)
aucList.append(roc_auc)
print("AUC alpha")
for i in range(len(aucList)):
print(aucList[i], alphaList[i])
## plot auc values versus alpha values
x = [-3, -2, -1, 0, 1, 2, 3, 4, 5]
plt.plot(x, aucList)
plt.xlabel('-log(alpha)')
plt.ylabel('AUC')
plt.show()
## 可视化最好分类器的性能
indexBest = aucList.index(max(aucList))
alph = alphaList[indexBest]
rocksVMinesRidgeModel = linear_model.Ridge(alpha=alph)
rocksVMinesRidgeModel.fit(xTrain, yTrain)
## 绘制散点图
plt.scatter(rocksVMinesRidgeModel.predict(xTest), yTest, s=100, alpha=0.25)
plt.xlabel("Predicted Value")
plt.ylabel("Actual Value")
plt.show()
AUC alpha
0.8411138411138411 999.9999999999999
0.864045864045864 99.99999999999999
0.9074529074529074 10.0
0.9180999180999181 1.0
0.8828828828828829 0.1
0.8615888615888616 0.010000000000000002
0.8517608517608517 0.0010000000000000002
0.8509418509418509 0.00010000000000000002
0.8493038493038493 1.0000000000000003e-05
二.分类结果分析
AUC的值接近1对应于更好的性能,接近于0.5说明效果不太好。使用AUC的目标是使其最大化而不是最小化。AUC在α=1.0时有一个明显的突起。数据以及图示显示在α远离1.0 时有明显的下降。随着α变小,解方案接近于不受限的线性回归问题。α小于1.0时,性能下降表明不受限的解难以达到岭回归的效果。在之前不受限普通均方回归的结果可以看到,其中AUC在训练集上的预测性能为0.98,在测试集上的预测性能为0.85,非常接近于使用较小的alpha(α设为1E-5)的岭回归的AUC值,这说明岭回归会显著提升性能。对于岩石-水雷问题,数据集包含60个属性,总共208行数据。将70个样本移除作为预留数据,剩下138行用于训练。样本数量大约是属性数量的2倍,但是不受限解(基于普通的最小二乘法)仍然会过拟合数据。这时使用10折交叉验证来估计性能是一个很好的替换方案。使用 10 折交叉验证,每一份数据只有20个样本,训练数据相对测试数据就会多很多,从而性能上会有一致的提升。
上述图1为AUC与alpha参数的关系,该图展示了在系数向量上使用欧式长度限制可以降低解的复杂度。图2为实际分类结果与分类器预测结果的散点图。该图与红酒预测中的散点图类似,因为实际预测的输出是离散的,所以呈现 2 行水平的点。