MNIST数据集:手写的70000个数字的图片,每张图像都用其代表的数字标记
1.获取数据集
from sklearn.datasets import fetch_openml
mnist = fetch_openml('mnist_784',version=1, cache=True)
mnist
1.1sklearn加载数据集通常有类似字典结构
DESCR:描述数据集 data:包含一个数组 每个实例为一行 每个特征为一行 target:包含一个带有标记的数组
X,y=mnist['data'],mnist['target']
X.shape
# (70000,784)---共七万张照片,每张照片有784个特征(图片是28*28像素的) 每个特征代表了一个像素点强度(范围0-255)
(70000, 784)
y.shape
(7000,)
1.2共有70000张照片,每张图片784个特征,图片像素28*28,每个特征代表一个像素点强度(从0到255)
%matplotlib inline
# 当调用matplotlib.pyplot的绘图函数plot进行绘图时候(或者生成figure)可以直接在python console
import matplotlib
import matplotlib.pyplot as plt
1.2.1抓取一个实例的特征向量
# 抓取一个实例的特征向量
# iloc提取行数据
import numpy as np
some_digit = np.array(X.iloc[30000,])
1.2.2将其重新形成一个28*28数组
# 将其形成一个28*28数组
some_digit_image = some_digit.reshape(28,28)
1.2.3使用Matplotlib的imshow()函数将其显示出来
plt.imshow(some_digit_image, interpolation='nearest')
#plt.axis('off')
plt.show()
1.2.4看起来像3,查看标签
y[30000]
3
1.2.创建测试集
X_train,X_test,y_train,y_test=X[:60000],X[60000:],y[:60000],y[60000:]
1.3将训练集数据进行洗牌
import numpy as np
# 训练集随机重新排列
shuffle_index = np.random.permutation(60000)
# iloc提取行数据
X_train,y_train = X_train.iloc[shuffle_index],y_train[shuffle_index]
2.训练一个二元分类器
二元分类器只能区别出这个数字是3或者不是3
2.1创建目标向量
# 先尝试识别一个数字
y_train_3 = (y_train == '3')
y_test_3 = (y_test == '3')
2.2挑选一个分类器并开始训练(随机梯度下降SGD(stochastic gradient descend)分类器)优点:能够有效处理大型数据集
from sklearn.linear_model import SGDClassifier
# random_state 随机种子数 每次运行结果可以相同 ,就能进行调参
sgd_clf = SGDClassifier(random_state=42)
sgd_clf.fit(X_train, y_train_3)
out:SGDClassifier(random_state=42)
2.3检测图像
sgd_clf.predict([some_digit])
out:array([True])
3.考核性能
3.1使用交叉验证测量精度
3.1.1分层抽样
# 选择分层K折模型
from sklearn.model_selection import StratifiedKFold
# 克隆模型方法
from sklearn.base import clone
# n_splits=3:将数据分三份 两份训练 一份测试
skfolds = StratifiedKFold(n_splits=3)
for train_index,test_index in skfolds.split(X_train,y_train_3):
# 克隆clone_clf模型
clone_clf = clone(sgd_clf)
# 训练集测试集命名
X_train_folds=X_train.iloc[train_index]
y_train_folds=(y_train_3[train_index])
X_test_fold=X_train.iloc[test_index]
y_test_fold=(y_train_3[test_index])
# 训练模型
clone_clf.fit(X_train_folds,y_train_folds)
# 预测验证
y_pred=clone_clf.predict(X_test_fold)
# 预测正确的
n_correct=sum(y_pred == y_test_fold)
# 算出正确预测比率
print(n_correct/len(y_pred))
out:0.8794
0.7864
0.55245
3.1.2使用cross_val_score()函数评估SGDClassifier模型
cross_val_score()交叉验证函数,得到K折验证中每一折的得分,K个得分取平均值就是模型的平均性能
from sklearn.model_selection import cross_val_score
#k=3 每次留一个折叠进行验证 两折进行训练
cross_val_score(sgd_clf,X_train,y_train_3,cv=3,scoring='accuracy')
out:array([0.96225, 0.96315, 0.9221 ])
3.1.3二元分类器问题
假设将每张图片都分类成非3
定义一个分类器 全都是非3
# class sklearn.base.BaseEstimator:为所有的estimators提供基类
from sklearn.base import BaseEstimator
class Never3Classifier(BaseEstimator):
def fit(self,X,y=None):
pass
def predict(self,X):
return np.zeros((len(X),1),dtype=bool) #定义全都不是3
准确度
never_3_clf=Never3Classifier()
cross_val_score(never_3_clf,X_train,y_train_3,cv=3,scoring='accuracy')
out:array([0.89825, 0.8959 , 0.8993 ])
结果分析:因为只有 10% 的图片是数字 5,总是猜测某张图片不是 5,也有90%的可能性是对的。
3.2混淆矩阵:评估分类器的更好方法
3.2.1.要计算混淆矩阵,首先要有一组预测和实际目标进行比较
from sklea