【机器学习实战】使用SGD-随机梯度下降、随机森林对MNIST数据进行二分类(Jupyterbook)

1. 数据集

  1. 由美国高中生和人口调查局员工手写的70000个数字的图片。
  2. 数据集获取
# 获取MNIST数据集
from sklearn.datasets import fetch_openml
mnist = fetch_openml('mnist_784', version=1, cache=True, as_frame=False)
mnist
  1. 查看X和Y
    在这里插入图片描述
  2. 找索引为36000的实例,并将其还原成数字(书中是还原成了5,但是我这么获取数据集还原的数字是9,不知道什么原因)
# 随机抽取一个实例,将其还原成数字
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt

some_digit = X[36000]
some_digit_image = some_digit.reshape(28, 28)
plt.imshow(some_digit_image, cmap=matplotlib.cm.binary, interpolation='nearest')
plt.axis('off')
plt.show()

在这里插入图片描述

2. 划分数据集

  • 因为有些机器学习算法对训练实例的顺序敏感,如果连续输入许多相似的实例,可能导致执行性能不佳,所以对训练集进行洗牌。
X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]
# 对数据进行洗牌,防止输入许多相似实例导致的执行性能不佳
import numpy as np
shuffle_index = np.random.permutation(60000)
X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]

在这里插入图片描述

3. 重新创建目标向量(以是5和非5作为二分类标准)

y_train_5 = (y_train == '5')
y_test_5 = (y_test == '5')

在这里插入图片描述

4. 训练SGD分类器

from sklearn.linear_model import SGDClassifier

sgd_clf = SGDClassifier(random_state=42)
sgd_clf.fit(X_train, y_train_5)

在这里插入图片描述

4.1 使用准确率进行评估
from sklearn.model_selection import StratifiedKFold
from sklearn.base import clone

skfolds = StratifiedKFold(n_splits=3, random_state=42, shuffle=True) # 三折

for train_index, test_index in skfolds.split(X_train, y_train_5):
    clone_clf = clone(sgd_clf)
    X_train_folds = X_train[train_index]
    y_train_folds = y_train_5[train_index]
    X_test_folds = X_train[test_index]
    y_test_folds = y_train_5[test_index]
    
    clone_clf.fit(X_train_folds, y_train_folds)
    y_pred = clone_clf.predict(X_test_folds)
    n_correct = sum(y_pred == y_test_folds)
    print('预测正确的数量比例:', n_correct / len(y_pred))

在这里插入图片描述

# 使用 cross_val_score()函数来评估模型
from sklearn.model_selection import cross_val_score

cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring='accuracy')

在这里插入图片描述

4.2 使用混淆矩阵进行评估(精度、召回率和F1分数)
from sklearn.model_selection import cross_val_predict

y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3)
from sklearn.metrics import confusion_matrix
confusion_matrix(y_train_5, y_train_pred)
# 精度和召回率
from sklearn.metrics import precision_score, recall_score

precision_score(y_train_5, y_train_pred)
# F1-score
from sklearn.metrics import f1_score
f1_score(y_train_5, y_train_pred)

在这里插入图片描述

4.3 绘制precision、recall相对于threshold的函数图
# 1. 获取训练集中所有实例的决策分数
y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3, method='decision_function')
y_scores
# 2. 计算所有可能的阈值的precision、recall
from sklearn.metrics import precision_recall_curve

precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)
# 3. 绘制precision、recall相对于threshold的函数图
def plot_precision_recall_vs_threshold(precisions, recalls, thresholds):
    plt.plot(thresholds, precisions[: -1], 'b--', label='Precision')
    plt.plot(thresholds, recalls[:-1], 'g--', label='Recall')
    plt.xlabel('Threshold')
    plt.legend(loc='upper left') # 图例位置
    plt.ylim([0, 1]) # 设置刻度

plot_precision_recall_vs_threshold(precisions, recalls, thresholds)
plt.show()

在这里插入图片描述

4.4 精度-召回率(PR曲线)
# 4.精度-召回率曲线
plt.plot(recalls[:-1], precisions[: -1], 'r--')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.show()

在这里插入图片描述

4.5 ROC曲线、AUC值
4.5.1 ROC曲线
# 1. 计算多种阈值的TPR和FPR
from sklearn.metrics import roc_curve

fpr, tpr, thresholds = roc_curve(y_train_5, y_scores)

# 2. 绘制FPR对TPR的曲线
def plot_roc_curve(fpr, tpr, label=None):
    plt.plot(fpr, tpr, lineWidth=2, label=label)
    plt.plot([0, 1], [0, 1], 'k--')  # 副对角线
    plt.axis([0, 1, 0, 1]) # 设置横轴、竖轴的刻度
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')

plot_roc_curve(fpr, tpr)
plt.show()

在这里插入图片描述

4.5.2 AUC值
# 完美分类器的ROC AUC为1,纯随机分类器的ROC AUC等于0.5
from sklearn.metrics import roc_auc_score
roc_auc_score(y_train_5, y_scores)

在这里插入图片描述

5. 使用随机森林训练、评估

from sklearn.ensemble import RandomForestClassifier

forest_clf = RandomForestClassifier(random_state=42)
y_probas_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3, method='predict_proba')
y_probas_forest # 某个实例属于某个类别的概率
# 使用正类的概率作为分数值(第二列)
y_scores_forest = y_probas_forest[:, 1]
y_scores_forest
fpr_forest, tpr_forest, thresholds_forest = roc_curve(y_train_5, y_scores_forest)
# 绘制ROC曲线
plt.plot(fpr, tpr, "b:", label="SGD")
plot_roc_curve(fpr_forest, tpr_forest, "Random Forest")
plt.legend(loc="lower right") # 右下角
plt.show()

在这里插入图片描述
其他评估指标(AUC值、精度、召回率)如下:
在这里插入图片描述

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MNIST数据集是一个手写数字图片数据集,包含60000个训练图片和10000个测试图片,每张图片的大小为28x28像素。使用神经网络对MNIST数据进行分类机器学习中的一个经典问题,下面是使用Torch神经网络实现MNIST数据分类的结果分析。 首先,我们可以使用Torch内置的MNIST数据集读取函数来读取数据集,并将数据集分成训练集和测试集。代码如下: ```lua require 'torch' require 'nn' require 'optim' mnist = require 'mnist' -- load dataset trainset = mnist.traindataset() testset = mnist.testdataset() ``` 接下来,我们定义一个简单的神经网络模型,包括两个全连接层和一个softmax层,代码如下: ```lua -- define neural network model model = nn.Sequential() model:add(nn.Linear(28*28, 128)) model:add(nn.ReLU()) model:add(nn.Linear(128, 10)) model:add(nn.LogSoftMax()) ``` 在训练模型之前,我们需要定义损失函数和优化器。这里我们使用交叉熵损失和随机梯度下降优化器。代码如下: ```lua -- define loss function and optimizer criterion = nn.CrossEntropyCriterion() optimizer = optim.SGD(model.parameters, 0.01) ``` 接着,我们开始训练模型。我们使用训练集对模型进行训练,并使用测试集对训练的模型进行测试,以评估模型的性能。代码如下: ```lua -- train model for epoch = 1, 10 do for i = 1, trainset.size do local x = trainset[i].x:view(28*28) local y = trainset[i].y optimizer.zero_grad() local output = model:forward(x) local loss = criterion:forward(output, y) local gradOutput = criterion:backward(output, y) model:backward(x, gradOutput) optimizer.step() end -- evaluate model local correct = 0 for i = 1, testset.size do local x = testset[i].x:view(28*28) local y = testset[i].y local output = model:forward(x) local _, prediction = output:max(1) if prediction[1] == y then correct = correct + 1 end end print(string.format('Epoch %d, accuracy = %.2f', epoch, correct/testset.size)) end ``` 运行上面的代码,我们可以得到模型在测试集上的分类准确率,如下所示: ``` Epoch 1, accuracy = 0.89 Epoch 2, accuracy = 0.92 Epoch 3, accuracy = 0.94 Epoch 4, accuracy = 0.94 Epoch 5, accuracy = 0.95 Epoch 6, accuracy = 0.95 Epoch 7, accuracy = 0.95 Epoch 8, accuracy = 0.96 Epoch 9, accuracy = 0.96 Epoch 10, accuracy = 0.96 ``` 可以看到,模型在测试集上的分类准确率达到了96%以上,说明模型的性能比较好。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想做一只快乐的修狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值