系列文章目录及链接
上篇:机器学习(五) -- 无监督学习(2) --降维1
下篇:
前言
tips:标题前有“***”的内容为补充内容,是给好奇心重的宝宝看的,可自行跳过。文章内容被“
文章内容”删除线标记的,也可以自行跳过。“!!!”一般需要特别注意或者容易出错的地方。
本系列文章是作者边学习边总结的,内容有不对的地方还请多多指正,同时本系列文章会不断完善,每篇文章不定时会有修改。
由于作者时间不算富裕,有些内容的《算法实现》部分暂未完善,以后有时间再来补充。见谅!
文中为方便理解,会将接口在用到的时候才导入,实际中应在文件开始统一导入。
三、**算法实现
四、接口实现
0、三维图绘制
0.1、散点图
API:
ax.scatter(xs, ys, zs, s=20, c=None, depthshade=True, *args, *kwargs)
xs,ys,zs:输入数据;
s:scatter点的尺寸
c:颜色,如c = 'r'就是红色;
depthshase:透明化,True为透明,默认为True,False为不透明
*args等为扩展变量,如maker = 'o',则scatter结果为’o‘的形状
# 获取数据
data = [[1,7,3,4], [1,4,7,3], [4,3,7,1]]
x,y,z=data[0],data[1],data[2]
# 创建一个新的图
fig = plt.figure()
# 创建一个3D绘图区域
ax = fig.add_subplot(111, projection='3d')
# 画出3D散点图
ax.scatter(x, y, z, c=np.arange(4))
# 设置标签
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')
# 显示图
plt.show()
0.2、直线图
API:
ax.plot(x,y,z,label=' ')
data = [[1,7,3,4], [1,4,7,3], [4,3,7,1]]
x,y,z=data[0],data[1],data[2]
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(x, y, z, label='线')
ax.legend()
plt.show()
theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
z = np.linspace(-2, 2, 100)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(x, y, z, label='参数曲线')
ax.legend()
plt.show()
0.3、线框图
API:
ax.plot_wireframe(X, Y, Z, *args, **kwargs)
X,Y,Z:输入数据
rstride:行步长
cstride:列步长
rcount:行数上限
ccount:列数上限
from mpl_toolkits.mplot3d import axes3d
# 获取一些测试数据
x, y, z = axes3d.get_test_data(0.05)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 绘制一个基本的线框
ax.plot_wireframe(x, y, z, rstride=10, cstride=10)
plt.show()
0.4、表面图
API:
ax.plot_surface(X, Y, Z, *args, **kwargs)
X,Y,Z:数据
rstride、cstride、rcount、ccount:同Wireframe plots定义
color:表面颜色
cmap:图层
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
# 制作数据
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 绘制表面
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,linewidth=0, antialiased=False)
# 自定义z轴
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
# 添加一个将值映射到颜色的颜色条
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
0.5、三角表面图
API:
ax.plot_trisurf(*args, **kwargs)
X,Y,Z:数据
其他参数类似surface-plot
n_radii = 8
n_angles = 36
# 使半径和角度空间(半径r=0省略,以消除重复)。
radii = np.linspace(0.125, 1.0, n_radii)
angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)
# 重复每个半径的所有角度
angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)
# 将极坐标(半径,角度)转换为直角坐标(x, y)
# (0,0)是在这个阶段手动添加的,所以不会有重复
# (x, y)平面上的#个点
x = np.append(0, (radii*np.cos(angles)).flatten())
y = np.append(0, (radii*np.sin(angles)).flatten())
# 计算z来得到普林格曲面
z = np.sin(-x*y)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(x, y, z, linewidth=0.2, antialiased=True)
plt.show()
0.6、等高线图
API:
ax.contour(X, Y, Z, *args, **kwargs)
from mpl_toolkits.mplot3d import axes3d
from matplotlib import cm
X, Y, Z = axes3d.get_test_data(0.05)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
cset = ax.contour(X, Y, Z, cmap=cm.coolwarm)
ax.clabel(cset, fontsize=9, inline=1)
plt.show()
0.7、条形图
API:
ax.bar(left, height, zs=0, zdir='z', *args, **kwargs
x,y,zs = z,数据
zdir:条形图平面化的方向
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for c, z in zip(['r', 'g', 'b', 'y'], [30, 20, 10, 0]):
xs = np.arange(20)
ys = np.random.rand(20)
# 您可以提供单一颜色或数组。为了证明这一点,
# 每一组的第一栏将被涂成青色。
cs = [c] * len(xs)
cs[0] = 'c'
ax.bar(xs, ys, zs=z, zdir='y', color=cs, alpha=0.8)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
0.8、子图
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 用x轴和y轴画一条sin曲线
x = np.linspace(0, 1, 100)
y = np.sin(x * 2 * np.pi) / 2 + 0.5
ax.plot(x, y, zs=0, zdir='z', label='curve in (x,y)')
# 在x和z轴上绘制散点图数据(每种颜色20个2D点)
colors = ('r', 'g', 'b', 'k')
x = np.random.sample(20*len(colors))
y = np.random.sample(20*len(colors))
c_list = []
for c in colors:
c_list.append([c]*20)
c_list=np.array(c_list)
c_list=c_list.reshape(-1)
# 通过使用zdir='y',这些点的y值固定为zs值0
# 和(x,y)点绘制在x和z轴上。
ax.scatter(x, y, zs=0, zdir='y', c=c_list, label='points in (x,z)')
# 制作图例,设置轴限制和标签
ax.legend()
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_zlim(0, 1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
1、PCA
sklearn.decomposition.PCA
导入:
from sklearn.decomposition import PCA
语法:
pca = PCA(n_components=None,copy=True,whiten=False,svd_solver="auto",tol=0.0,iterated_power="auto",random_state=None)
参数:
n_components: 保留的主成分数量。
None(默认值),保留所有主成分。
整数k,则只保留前k个主成分;
k为小数,保留主成分的方差百分比。
属性:
components_: 选定的主成分。是一个形状为 (n_components, n_features) 的数组,表示每个主成分的特征向量。
explained_variance_: 每个主成分的解释方差。它是一个包含了按降序排列的每个主成分的解释方差值的一维数组。
explained_variance_ratio_: 每个主成分的解释方差比例。它是一个包含了按降序排列的每个主成分的解释方差比例的一维数组。
singular_values_: 每个主成分的奇异值。它是一个包含了按降序排列的每个主成分的奇异值的一维数组。
mean_: 每个特征的均值。是一个形状为 (n_features,) 的一维数组。
noise_variance_: 噪声方差的估计值。只有当 whiten=True 时才计算。
n_samples_:训练数据中的样本数量。
n_features_:训练数据中的特征数。
方法:
fit(X): 拟合PCA模型,其中X是形状为(n_samples, n_features)的输入数据。
transform(X): 将输入数据X转换为降维后的表示。接受形状为(n_samples, n_features)的输入数据,并返回降维后的数据表示,形状为(n_samples, n_components)。
fit_transform(X): 这个方法是fit()和transform()的结合,即先拟合模型,然后将输入数据转换为降维后的表示。
inverse_transform(X): 这个方法用于将降维后的数据表示X转换为原始的高维表示。
score(X):用于计算数据在主成分空间中的重构误差。
get_precision():用于返回数据的精度矩阵(仅在whiten=True时可用)。
1.1、获取数据
from sklearn.decomposition import PCA
# 获取数据
data=np.array([[0,1,0],
[4,5,9],
[10,2,6],
[10,11,12]])
x,y,z=data[:,0],data[:,1],data[:,2]
print(data.shape)
# 可视化
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z,c='b')
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')
plt.show()
1.2、数据预处理
1.3、特征工程
1.4、模型训练
# 实例化学习器
transfer1 = PCA(n_components=0.9)
# 调用fit_transform
data1 = transfer1.fit_transform(data)
# 实例化学习器
transfer2 = PCA(n_components=2)
# 调用fit_transform
data2 = transfer2.fit_transform(data)
1.5、模型评估
print("保留75%的信息,降维结果为:\n", data1)
print("降维到2维的结果:\n", data2)
# 可视化
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 原数据
ax.scatter(x, y, z,c='b')
# 降维后数据
print(data2.shape)
ax.scatter(data2[:,0], data2[:,1],c='r')
# 等价与=ax.scatter(data2[:,0], data2[:,1],0,c='r')
ax.legend(['原数据','降维后数据'])
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')
plt.show()
1.6、结果预测
经过模型评估后通过的模型可以代入真实值进行预测。
!!!注意
出现:ValueError: n_components=4 must be between 0 and min(n_samples, n_features)=3 with svd_solver='full'
是由于:PCA降维后的特征数数少于样本数
如把n_components超过3,就会出现此类错误:
原因:
矩阵shape(样本数,特征数)
首先,PCA降维实现是对特征数的减少,而不是样本数,因此降维之后的样本数是不变的,而PCA降维后特征数多于样本数数量会报错,这是算法本身决定的,
PCA降维原理,如果降到n维,就需要构造一个n维的投影空间,而n维投影空间至少要通过n+1个样本数量决定(两点确定线,三点确定面),如果样本数量太少,就无法得到一个有效的投影空间。
如下将二维数据点,投影到一条直线上,就需要两个或以上的点,这样才能确定一条直线,使得样本点到直线的距离和最小,如果是一个点就有无数条直线,因此这里样本数要大于1。
所以要求降维后特征数少于样本数
然后,在使用PCA接时n_components<=min(n_samples, n_features),这里可以等于的原因是,在相等时,会默认把最后一个特征赋值0,相当于有效特征数还是少于样本数的。
2、KernelPCA
sklearn.decomposition.KernelPCA
导入:
from sklearn.decomposition import KernelPCA
语法:
kpca=KernelPCA(n_components=None, *, kernel='linear', gamma=None, degree=3, coef0=1, kernel_params=None, alpha=1.0, fit_inverse_transform=False, eigen_solver='auto', tol=0, max_iter=None, remove_zero_eig=False, random_state=None, copy_X=True, n_jobs=None)
参数:
n_components:主成分个数
kernel:选择的核函数。"linear"(默认值)、“poly”、“rbf”、“sigmoid”、“cosine”、“precomputed”
gamma:核函数选择“poly”、“rbf”、“sigmoid”时有效。浮点类型,默认值=1/n_features
属性:
kpca.lambdas_:核化矩阵的特征值
alphas_:特征向量
dual_coef_:逆转换矩阵
方法:
kpca.fit(x[,y]):拟合模型
transform(x):转换x
kpca.fit_transform(x[,y]):根据x中的数据拟合模型并转换x。
inverse_transform(x):将x转换回原始空间
2.1、获取数据
from sklearn.datasets import make_moons
from sklearn.decomposition import PCA
from sklearn.decomposition import KernelPCA
# 获取数据
x, y = make_moons(n_samples=100, random_state=233)
print(x.shape)
# 可视化
plt.scatter(x[y == 0, 0], x[y == 0, 1], color='red', marker='^', alpha=0.5)
plt.scatter(x[y == 1, 0], x[y == 1, 1], color='blue', marker='o', alpha=0.5)
plt.title("样本数据")
plt.show()
2.2、数据预处理
2.3、特征工程
2.4、模型训练
# PCA
pca2 = PCA(n_components=2)
x_pca2 = pca2.fit_transform(x)
pca = PCA(n_components=1)
x_pca = pca.fit_transform(x)
# KernelPCA
kpca = KernelPCA(n_components=2, kernel='rbf', gamma=15)
x_kpca = kpca.fit_transform(x)
2.5、模型评估
# 绘制降维结果并与原样本数据对比
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(7, 3))
ax[0].scatter(x_pca2[y == 0, 0], x_pca2[y == 0, 1], c='r', marker='^')
ax[0].scatter(x_pca2[y == 1, 0], x_pca2[y == 1, 1], c='b', marker='o')
ax[1].scatter(x_pca[y == 0], np.zeros((50, 1))+0.02, c='r', marker='^')
ax[1].scatter(x_pca[y == 1], np.zeros((50, 1))-0.02, c='b', marker='o')
ax[0].set_xlabel('X')
ax[0].set_ylabel('Y')
ax[0].set_title("去中心化的数据")
ax[1].set_ylim([-1, 1])
ax[1].set_yticks([])
ax[1].set_xlabel('X_pca')
ax[1].set_title("降维后样本数据")
plt.tight_layout()
plt.show()
# 绘制降维结果并与原样本数据对比
kfig, kx = plt.subplots(nrows=1, ncols=2, figsize=(7, 3))
kx[0].scatter(x[y == 0, 0], x[y == 0, 1], c='r', marker='^')
kx[0].scatter(x[y == 1, 0], x[y == 1, 1], c='b', marker='o')
kx[1].scatter(x_kpca[y == 0, 0], x_kpca[y == 0, 1], c='r', marker='^')
kx[1].scatter(x_kpca[y == 1, 0], x_kpca[y == 1, 1], c='b', marker='o')
kx[0].set_xlabel('X')
kx[0].set_ylabel('Y')
kx[0].set_title("样本数据")
kx[1].set_ylim([-1, 1])
kx[1].set_yticks([])
kx[1].set_xlabel('X_kpca')
kx[1].set_title("降维后样本数据")
plt.tight_layout()
plt.show()
2.6、结果预测
经过模型评估后通过的模型可以代入真实值进行预测。
3、PCA2
3.1、获取数据
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
# 获取数据
iris = load_iris()
3.2、数据预处理
# 划分数据集
x_train,x_test,y_train,y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=1473)
print(x_train.shape)
# 可视化
plt.figure()
plt.scatter(x_train[:,0],x_train[:,1],c=y_train,edgecolors='b')
plt.show()
3.3、特征工程
3.4、模型训练
# 实例化学习器
transfer= PCA(n_components=3)
# 调用fit_transform
x_train = transfer.fit_transform(x_train)
3.5、模型评估
print(x_train.shape)
# 可视化
plt.figure()
plt.scatter(x_train[:,0],x_train[:,1],c=y_train,edgecolors='b')
plt.show()
2.6、结果预测
经过模型评估后通过的模型可以代入真实值进行预测。
4、LDA
sklearn.discriminant_analysis.LinearDiscriminantAnalysis
导入:
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
语法:
lda=LinearDiscriminantAnalysis(n_components=None)
参数:
n_components:降维后维度
属性:
lda.coef_:权重向量
lda.intercept:截距向量
lda.covariance_:每个类别的协方差矩阵
lda.means_:每个类别的均值向量
lda.xbar_:整体样本的均值向量
lda.n_iter_:实际迭代次数
方法:
lda.fit(x[,y]):拟合模型
lda.predict(x):用模型预测,返回预测值
lda.score(x,y):准确率
lda.predict_log_proba(x):x预测为各个类别的概率的对数值。
lda.predict_proba(x):x预测为各个类别的概率的概率值
4.1、获取数据
# API导入
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
# 获取数据
iris = load_iris()
4.2、数据预处理
# 划分数据集
x_train,x_test,y_train,y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=1473)
print(x_train.shape)
# 可视化
plt.figure()
plt.scatter(x_train[:,0],x_train[:,1],c=y_train,edgecolors='b')
plt.show()
4.3、特征工程
4.4、模型训练
# 实例化学习器
lda = LinearDiscriminantAnalysis(n_components=2)
# 拟合转换
x_train = lda.fit_transform(x_train, y_train) #拟合训练并转换
4.5、模型评估
print(x_train.shape)
# 可视化
plt.figure()
plt.scatter(x_train[:,0],x_train[:,1],c=y_train,edgecolors='b')
plt.show()
4.6、结果预测
经过模型评估后通过的模型可以代入真实值进行预测。
旧梦可以重温,且看:机器学习(五) -- 无监督学习(2) --降维1
欲知后事如何,且看: