使用Logistics回归去实现MNIST¶
In [1]:
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
#新学的库
# 下载Minist数据集
from sklearn.datasets import fetch_openml
from sklearn.linear_model import LogisticRegression
# 设置种子
from sklearn.utils import check_random_state
# 记录运行时间
import time
In [2]:
t0 = time.time()
train_samples = 5000
X ,y = fetch_openml('mnist_784',version=1,return_X_y = True)
random_state = check_random_state(0)
permutation = random_state.permutation(X.shape[0])
X = X[permutation]
y = y[permutation]
X = X.reshape(X.shape[0],-1)
解释:我感觉上面这步很有技巧,permutation就是对数组进行重排,所以这里直接对X的大小进行重排,重排后的数组位置就直接可以视为Index。
In [3]:
print(X.shape)
print(y.shape )
数据划分¶
这里给训练数据划分为:5000,而测试数据则为10000。
In [4]:
X_train,X_test,y_train,y_test = train_test_split(X,y,
train_size=train_samples,
test_size = 10000)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
注:之前在Pipeline那个章节的时候已经说过了这种转换了,当时没有理解,现在原来是先fit_transform,之后根据之前已经设置的标准化数据(应该是训练数据的均值和方差吧)
训练模型¶
In [5]:
clf = LogisticRegression(C = 50./train_samples,
multi_class='multinomial',
penalty='l1',solver='saga',tol=0.1)
clf.fit(X_train,y_train)
# 计算稀疏度,统计出多少权重系数的值是0
sparsity = np.mean(clf.coef_==0)*100
score = clf.score(X_test,y_test)
#print('最好的C值为:%.4f' % clf.C_)
print('L1正则化的的稀疏度:%.2f%%' % sparsity)
print('L1正则化的测试分数:%.4f'% score)
这里有个编程非常好,通过统计布尔值的个数,计算均值 np.mean(clf.coef_==0)
其中:Score 计算的数据的准确率
。
对于Logistics输出属性的进一步理解¶
首先Logistics回归
做的是分类的任务,但是输出的属性与回归类似。
本例中有784个像素,即784个属性特征,每个属性配一个权重。对于每张照片每个像素都有值。
$$ z = w_0 + w_1*x_1+ w_2*x_2+\cdots+w_{784}*x_{784} $$这里coef_
返回的就是w
值,之后将回归后的值,再经过类似于阶梯的判断(即sigmoid函数)的分类:
In [9]:
coef = clf.coef_.copy()
print(coef)
scale = np.abs(coef).max()
print(scale)
print(coef.shape)
In [11]:
plt.figure(figsize=(14,7))
for i in range(10):
l1_plot = plt.subplot(2,5,i+1)
l1_plot.imshow(coef[i].reshape(28,28),interpolation='bilinear',
cmap=plt.cm.RdBu,vmin=-scale,vmax=scale)
l1_plot.set_xticks(())
l1_plot.set_yticks(())
l1_plot.set_xlabel('类别:%i' %i)
plt.suptitle('分类向量为')
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
run_time = time.time()-t0
print('该案例运行时间为:%.3f s' % run_time)
plt.show()
In [ ]: