1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# 生成样本数据及其标签
from sklearn import datasets
Data,labels = datasets.make_circles(n_samples=400, noise=0.1, factor=0.1) #Data是400x2的矩阵,labels是1x400的列表
# 画三维散点图
import plotly.express as px
fig = px.scatter(x=Data[:,0], y=Data[:,1], color=labels)
fig.update_layout(yaxis=dict(scalenchor='x')) #y轴的刻度与x轴一样
from sklearn.metrics.pairwise import rbf_kernel
import numpy as np
def AutoRBF(gv, Data, labels): #计算gv对应的指标J
# 计算Kernel matrix
K = rbf_kernel(Data, gamma=gv) #400x400
# 组内:对角线上的block
n=[] #统计各类样本的个数
w=0 #同组内积矩阵和累计
for i in range(0, max(labels)+1): #遍历每一类
idx = labels==i #把labels列表中等于某类的元素变成:True/False,形成列表idx
#Within the Kernel matrix,取出同类矩阵
KW = K[:,idx] #先取列号等于idx列表中元素为True的index的列
KW = KW[idx,:] #再取行号=idx列表中True元素的index的行
n.append(sum(idx)) #统计各类元素个数,这里是[200,200]
w = w + np.sum(KW) #第一类内积矩阵求和加上第二类内积矩阵求和
# 组间(不同类样本内积的block)
b = np.sum(K) - w #全部元素之和减去同类内积矩阵之和w就是不同类内积矩阵之和b
nw = sum(np.power(n,2)) #每类200个,共200x200 + 200x200=4万个值
nb = sum(n)**2 - nw
w=w/nw #取平均
b=b/nb #取平均
J=(1-w)+b #w越接近1越好,b越接近0越好
return J
# 第一种方法找最佳gamma:grid
grid = np.linspace(0,50,1000) #0-50切成1000份
J=[] #存储各gv对应的J值
for gv in grid:
J.append(AutoRBF(gv,Data,labels))
px.line(x=grid, y=J) #把J画成曲线
# 第二种方法:用 minimize 函数找最低点(比grid快很多)
from scipy.optimize import minimize
gv0=1/Data.shape[1] #初始值:1/维度数
sol = minimize(AutoRBF,gv0,args=(Data,labels)) #solution是使目标函数AutoRBF最小的gv(初值为gv0),args放函数的其余参数
bestgv = sol.x #最低点的x坐标,最好的gv
# 用kpca降维后,能不能分得好
from sklearn.decomposition import KernelPCA
myKPCA = KernelPCA(n_components=2, kernel='rbf', gamma=bestgv)
myKPCA.fit(Data) #训练
reduced_Data = myKPCA.transform(Data) #投影到低维
fig = px.scatter(x=reduced_Data[:,0], y=reduced_Data[:,1],color=labels)
fig.update_layout(yaxis=dict(scaleanchor='x'))
|