说明:本文依据《Sklearn 与 TensorFlow 机器学习实用指南》完成,所有版权和解释权均归作者和翻译成员所有,我只是搬运和做注解。
第八章降维
到达第一部分机器学习的最终章,降维,最早也是在这里开始应用的,当时是使用Sklearn中LDA模型完成主题抽取,现在又回到这里,另外可能看帖的童鞋也发现了,最近的状态有问题,一直在往前推,但是对代码的分析变得很少。我只是想尽快搞定,然后转到NLP上去。
很多机器学习的问题都会涉及到有着几千甚至数百万维的特征的训练实例。这不仅让训练过程变得非常缓慢,同时还很难找到一个很好的解,这种问题通常被称为维数灾难(curse of dimentionality)。
降维会让项目更复杂因而更难维护。所有应该先尝试使用原始的数据训练,如果训练速度太慢的话再考虑使用降维。在某些情况下,降低训练集数据的维度可能会筛选掉一些噪音和不必要的细节,这可能会让你的结果比降维之前更好。
源代码已经同步在github中
https://github.com/jwc19890114/-02-learning-file-100days
3.增量PCA(Incremental PCA)
现在遇到的问题是,如果一批训练集特别大,无法一次性全部存入内存中处理,这时SVD算法就不合适了,教程中提出使用增量PCA算法(IPCA)。即是训练集分批处理,似乎类似Tensorflow的batch。
教程中使用numpy的array_split函数将mnist数据集处理成100个batch,然后降维到154,这里每一个批次都要调用一次partial_fit方法,而不是针对整体fit
from sklearn.decomposition import IncrementalPCA
n_batches=100
inc_pca=IncrementalPCA(n_components=154)
for X_batch in np.array_split(X_train,n_batches):
print(".",end="")#显示一个进程
inc_pca.partial_fit(X_batch)
X_reduced=inc_pca.transform(X_train)
X_recovered_inc_pac=inc_pca.inverse_transform(X_reduced)
plt.figure(figsize=(11,4))
plt.subplot(121)
plot_digits(X_train[::2100])
plt.subplot(122)
plot_digits(X_recovered_inc_pac[::2100])
plt.tight_layout()
4.随机PCA(Randomized PCA)
Sklearn提供了另一种执行PCA的选择,称为随机 PCA。这是一种随机算法,可以快速找到前d个主成分的近似值。它的计算复杂度是O(m × d^2) + O(d^3),而不是O(m × n^2) + O(n^3),所以当d远小于n时,它比之前的算法快得多。操作时设定PCA中svd_solver='randomized'。
在这里,教程对运行时间进行了对比。
import time
for n_components in (2,10,154):
print("n_components=",n_components)
regular_pca=PCA(n_components=n_components)
inc_pca=IncrementalPCA(n_components=n_components,batch_size=500)
rnd_pca=PCA(n_components=n_components,random_state=42,svd_solver="randomized")
for pca in (regular_pca,inc_pca,rnd_pca):
t1=time.time()
pca.fit(X_train)
t2=time.time()
print(" {}: {:.1f} seconds".format(pca.__class__.__name__, t2 - t1))
'''
n_components= 2
PCA: 2.1 seconds
IncrementalPCA: 10.7 seconds
PCA: 1.9 seconds
n_components= 10
PCA: 2.1 seconds
IncrementalPCA: 11.0 seconds
PCA: 2.1 seconds
n_components= 154
PCA: 5.6 seconds
IncrementalPCA: 14.5 seconds
PCA: 6.5 seconds
'''
对比在不同数据集大小下PCA和随机PCA的表现
times_rpca=[]#随机PCA
times_pca=[]
sizes=[1000, 10000, 20000, 30000, 40000, 50000, 70000, 100000, 200000, 500000]
for n_samples in sizes:
X=np.random.randn(n_samples,5)
pca=PCA(n_components=2,svd_solver="randomized",random_state=42)
t1=time.time()
pca.fit(X)
t2=time.time()
times_rpca.append(t2-t1)
pca = PCA(n_components = 2)
t1 = time.time()
pca.fit(X)
t2 = time.time()
times_pca.append(t2 - t1)
print(times_pca)
print(times_rpca)
plt.plot(sizes, times_rpca, "b-o", label="RPCA")
plt.plot(sizes, times_pca, "r-s", label="PCA")
plt.xlabel("n_samples")
plt.ylabel("Training time")
plt.legend(loc="upper left")
plt.title("PCA and Randomized PCA time complexity ")
领取专属 10元无门槛券
私享最新 技术干货