项目地址
实验一:SVM
1. 实验目的
- 掌握线性支持向量机(SVM)分类器;
- 掌握基于高斯核的SVM分类器;
- 掌握基于拉普拉斯核的SVM分类器。
2. 数据集介绍
| 数据集 | 样本数 | 维度 | 类数 | 数据类型 |
|---|
| mnist | 3000 | 784 | 10 | 手写体数字 |
| yale | 165 | 1024 | 15 | 人脸图像 |
| lung | 203 | 3312 | 5 | 生物数据 |
3. 实验内容
- 编写程序实现线性SVM分类器设计;
- 编写程序实现基于高斯核的SVM分类器设计;
- 编写程序实现基于拉普拉斯核的SVM分类器设计。
4. 代码实现
# coding=utf-8
from sklearn import svm, datasets
import numpy as np
import scipy.io as scio
from sklearn.model_selection import train_test_split
import math
def load_data(path):
data = scio.loadmat(path)
data_x = data['X']
data_y = data['Y'][:, 0] - 1
return np.array(data_x), np.array(data_y)
def laplace(X1, X2):
K = np.zeros((len(X1), len(X2)), dtype=np.float)
for i in range(len(X1)):
for j in range(len(X2)):
K[i][j] = math.exp(-math.sqrt(np.dot(X1[i] - X2[j], (X1[i] - X2[j]).T)) / 2)
return K
def classify(path, kernel):
x, y = load_data(path)
train_data, test_data, train_label, test_label = train_test_split(x, y, test_size=0.25, random_state=10)
predictor = svm.SVC(gamma='scale', C=2.0, decision_function_shape='ovr', kernel=kernel)
predictor.fit(train_data, train_label.ravel())
print('训练集:', predictor.score(train_data, train_label))
print('测试集:', predictor.score(test_data, test_label))
if __name__ == '__main__':
mnist_path = 'datasets/MNIST.mat'
lung_path = 'datasets/lung.mat'
yale_path = 'datasets/Yale.mat'
print('mnist数据集:')
classify(mnist_path, 'linear')
print('lung数据集:')
classify(lung_path, 'rbf')
print('yale数据集:')
classify(yale_path, laplace)
实验二:神经网络
1. 实验目的
- 掌握全连接神经网络的训练与测试方法;
- 掌握基于RBF分类器训练与测试方法;
2. 数据集介绍
| 数据集 | 样本数 | 维度 | 类数 | 数据类型 |
|---|
| mnist | 3000 | 784 | 10 | 手写体数字 |
| yale | 165 | 1024 | 15 | 人脸图像 |
| lung | 203 | 3312 | 5 | 生物数据 |
3. 实验内容
- 编写程序实现全连接神经网络分类器设计;
- 编写程序实现基于RBF分类器设计;
4. 代码实现
- BP 神经网络
# coding=utf-8
import numpy as np
import scipy.io as scio
from torch import nn, optim
import torch
from torch.utils.data import DataLoader, random_split, TensorDataset
device = 'cuda' if torch.cuda.is_available() else 'cpu'
def load_data(path):
data = scio.loadmat(path)
data_x = torch.from_numpy(np.array(data['X']))
data_y = torch.from_numpy(np.array(data['Y'][:, 0] - 1))
data = TensorDataset(data_x, data_y)
train_size = int(0.8 * len(data))
test_size = len(data) - train_size
train_data, test_data = random_split(data, [train_size, test_size], generator=torch.manual_seed(0))
return train_data, test_data
class MyNet(nn.Module):
def __init__(self, input_size, hidden_size, num_classes):
super(MyNet, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(hidden_size, num_classes)
def forward(self, x):
x = x.to(torch.float32)
out = self.fc1(x)
out = self.relu(out)
out = self.fc2(out)
return out
def train(train_loader, model):
optimizer = optim.SGD(model.parameters(), lr=0.5, momentum=0.8)
closs = nn.CrossEntropyLoss()
for i, data in enumerate(train_loader):
optimizer.zero_grad()
inputs, labels = data
inputs, labels = inputs.to(device), labels.to(device)
pred = model(inputs)
loss = closs(pred, labels)
loss.backward()
optimizer.step()
def test(test_loader, model):
correct = 0
total = 0
for i, data in enumerate(test_loader):
inputs, labels = data
inputs, labels = inputs.to(device), labels.to(device)
pred = model(inputs)
_, predicted = torch.max(pred.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum()
print(' 准确率:{}%'.format(correct * 100 / total))
return correct * 100 / total
if __name__ == '__main__':
mnist_path = 'datasets/MNIST.mat'
lung_path = 'datasets/lung.mat'
yale_path = 'datasets/Yale.mat'
print('mnist: ')
batch_size = 50
input_size = 784
hidden_size = 500
num_classes = 10
epoch = 30 # 0.5 0.8
train_data, test_data = load_data(mnist_path)
train_loader = DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=True)
model = MyNet(input_size, hidden_size, num_classes).to(device)
best = 0
for i in range(epoch):
print('epoch:', i, end='')
train(train_loader, model)
best = max(test(test_loader, model), best)
print('最高准确率:{}%'.format(best))
torch.cuda.empty_cache()
print('lung: ')
batch_size = 20
input_size = 3312
hidden_size = 500
num_classes = 5
epoch = 100 # 0.0005 0.9
train_data, test_data = load_data(lung_path)
train_loader = DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=True)
model = MyNet(input_size, hidden_size, num_classes).to(device)
best = 0
for i in range(epoch):
print('epoch:', i, end='')
train(train_loader, model)
best = max(test(test_loader, model), best)
print('最高准确率:{}%'.format(best))
torch.cuda.empty_cache()
print('yale: ')
batch_size = 10
input_size = 1024
hidden_size = 300
num_classes = 15
epoch = 50 # 0.000082 0.86
train_data, test_data = load_data(yale_path)
train_loader = DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=True)
model = MyNet(input_size, hidden_size, num_classes).to(device)
best = 0
for i in range(epoch):
print('epoch:', i, end='')
train(train_loader, model)
best = max(test(test_loader, model), best)
print('最高准确率:{}%'.format(best))
torch.cuda.empty_cache()
- RBF 分类器
# coding=utf-8
import numpy as np
import scipy.io as scio
from torch import nn, optim
import torch
from torch.utils.data import DataLoader, random_split, TensorDataset
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# device = 'cpu'
def load_data(path):
data = scio.loadmat(path)
data_x = torch.from_numpy(np.array(data['X']).astype(np.float32))
data_y = torch.from_numpy(np.array(data['Y'][:, 0] - 1))
data = TensorDataset(data_x, data_y)
train_size = int(0.8 * len(data))
test_size = len(data) - train_size
train_data, test_data = random_split(data, [train_size, test_size], generator=torch.manual_seed(0))
return data_x, train_data, test_data
class RBFN(nn.Module):
"""
以高斯核作为径向基函数
"""
def __init__(self, centers, n_out=3):
"""
:param centers: shape=[center_num,data_dim]
:param n_out: num_classes
"""
super(RBFN, self).__init__()
self.n_out = n_out
self.num_centers = centers.size(0) # 隐层节点的个数
self.dim_centure = centers.size(1)
self.centers = nn.Parameter(centers)
self.beta = (torch.ones(1, self.num_centers) * 10).to(device)
# 对线性层的输入节点数目进行了修改
self.linear = nn.Linear(self.num_centers + self.dim_centure, self.n_out, bias=True)
self.initialize_weights() # 创建对象时自动执行
def kernel_fun(self, batches):
n_input = batches.size(0) # number of inputs
A = self.centers.view(self.num_centers, -1).repeat(n_input, 1, 1)
B = batches.view(n_input, -1).unsqueeze(1).repeat(1, self.num_centers, 1)
C = torch.exp(-self.beta.mul((A - B).pow(2).sum(2, keepdim=False)))
return C
def forward(self, batches):
radial_val = self.kernel_fun(batches)
class_score = self.linear(torch.cat([batches, radial_val], dim=1))
return class_score
def initialize_weights(self, ):
"""
网络权重初始化
:return:
"""
for m in self.modules():
if isinstance(m, nn.Conv2d):
m.weight.data.normal_(0, 0.02)
m.bias.data.zero_()
elif isinstance(m, nn.ConvTranspose2d):
m.weight.data.normal_(0, 0.02)
m.bias.data.zero_()
elif isinstance(m, nn.Linear):
m.weight.data.normal_(0, 0.02)
m.bias.data.zero_()
def print_network(self):
num_params = 0
for param in self.parameters():
num_params += param.numel()
print(self)
print('Total number of parameters: %d' % num_params)
def train(train_loader, rbf):
optimizer = optim.SGD(rbf.parameters(), lr=0.000088, momentum=0.88)
closs = nn.CrossEntropyLoss()
for i, data in enumerate(train_loader):
optimizer.zero_grad()
inputs, labels = data
inputs, labels = inputs.to(device), labels.to(device)
pred = rbf(inputs)
loss = closs(pred, labels)
loss.backward()
optimizer.step()
def test(test_loader, rbf):
correct = 0
total = 0
for i, data in enumerate(test_loader):
inputs, labels = data
inputs, labels = inputs.to(device), labels.to(device)
pred = rbf(inputs)
_, predicted = torch.max(pred.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum()
print(' 准确率:{}%'.format(correct * 100 / total))
return correct * 100 / total
if __name__ == '__main__':
mnist_path = 'datasets/MNIST.mat'
lung_path = 'datasets/lung.mat'
yale_path = 'datasets/Yale.mat'
print('mnist: ')
batch_size = 50
input_size = 784
num_classes = 10
epoch = 20 # 0.5 0.3
data_x, train_data, test_data = load_data(mnist_path)
train_loader = DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=True)
rbf = RBFN(data_x, num_classes).to(device)
best = 0
for i in range(epoch):
print('epoch:', i, end='')
train(train_loader, rbf)
best = max(test(test_loader, rbf), best)
print('最高准确率:{}%'.format(best))
torch.cuda.empty_cache()
print('lung: ')
batch_size = 10
input_size = 3312
num_classes = 5
epoch = 20 # 0.5 0.3
data_x, train_data, test_data = load_data(lung_path)
train_loader = DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=True)
rbf = RBFN(data_x, num_classes).to(device)
best = 0
for i in range(epoch):
print('epoch:', i, end='')
train(train_loader, rbf)
best = max(test(test_loader, rbf), best)
print('最高准确率:{}%'.format(best))
torch.cuda.empty_cache()
print('yale: ')
batch_size = 10
input_size = 1024
num_classes = 15
epoch = 20 # 0.5 0.3
data_x, train_data, test_data = load_data(yale_path)
train_loader = DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=True)
rbf = RBFN(data_x, num_classes).to(device)
best = 0
for i in range(epoch):
print('epoch:', i, end='')
train(train_loader, rbf)
best = max(test(test_loader, rbf), best)
print('最高准确率:{}%'.format(best))
torch.cuda.empty_cache()
实验三:贝叶斯
1. 实验目的
- 掌握朴素贝叶斯分类器;
- 掌握AODE分类器;
2. 数据集介绍
| 数据集 | 样本数 | 维度 | 类数 | 数据类型 |
|---|
| mnist | 3000 | 784 | 10 | 手写体数字 |
| yale | 165 | 1024 | 15 | 人脸图像 |
| lung | 203 | 3312 | 5 | 生物数据 |
3. 实验内容
- 编写程序实现朴素贝叶斯分类器设计;
- 编写程序实现AODE分类器设计;
4. 代码实现
- 朴素贝叶斯分类器
from sklearn.model_selection import train_test_split # 切分测试集
from sklearn.naive_bayes import MultinomialNB # 贝叶斯
import scipy.io as scio
import numpy as np
def load_data(path):
data = scio.loadmat(path)
data_x = np.array(data['X'])
data_y = np.array(data['Y'][:, 0] - 1)
train_data, test_data, train_label, test_label = train_test_split(data_x, data_y, test_size=0.25, random_state=10)
return train_data, test_data, train_label, test_label
if __name__ == '__main__':
mnist_path = 'datasets/MNIST.mat'
lung_path = 'datasets/lung.mat'
yale_path = 'datasets/Yale.mat'
print('mnist:')
# 进行训练集和测试集切分
x_train, x_test, y_train, y_test = load_data(mnist_path)
# 对数据集进行提取
mlt = MultinomialNB(alpha=1.0)
mlt.fit(x_train, y_train)
y_predict = mlt.predict(x_test)
# 得出准确率
print("准确率为:", mlt.score(x_test, y_test))
print('lung:')
# 进行训练集和测试集切分
x_train, x_test, y_train, y_test = load_data(lung_path)
# 对数据集进行提取
mlt = MultinomialNB(alpha=1.0)
mlt.fit(x_train, y_train)
y_predict = mlt.predict(x_test)
# 得出准确率
print("准确率为:", mlt.score(x_test, y_test))
print('yale:')
# 进行训练集和测试集切分
x_train, x_test, y_train, y_test = load_data(yale_path)
# 对数据集进行提取
mlt = MultinomialNB(alpha=1.0)
mlt.fit(x_train, y_train)
y_predict = mlt.predict(x_test)
# 得出准确率
print("准确率为:", mlt.score(x_test, y_test))
- AODE 分类器
# coding=utf-8
import numpy as np
import scipy.io as scio
from torch import nn, optim
import torch
from torch.utils.data import DataLoader, random_split, TensorDataset
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# device = 'cpu'
def load_data(path):
data = scio.loadmat(path)
data_x = torch.from_numpy(np.array(data['X']).astype(np.float32))
data_y = torch.from_numpy(np.array(data['Y'][:, 0] - 1))
data = TensorDataset(data_x, data_y)
train_size = int(0.8 * len(data))
test_size = len(data) - train_size
train_data, test_data = random_split(data, [train_size, test_size], generator=torch.manual_seed(0))
return data_x, train_data, test_data
class RBFN(nn.Module):
"""
以高斯核作为径向基函数
"""
def __init__(self, centers, n_out=3):
"""
:param centers: shape=[center_num,data_dim]
:param n_out: num_classes
"""
super(RBFN, self).__init__()
self.n_out = n_out
self.num_centers = centers.size(0) # 隐层节点的个数
self.dim_centure = centers.size(1)
self.centers = nn.Parameter(centers)
self.beta = (torch.ones(1, self.num_centers) * 10).to(device)
# 对线性层的输入节点数目进行了修改
self.linear = nn.Linear(self.num_centers + self.dim_centure, self.n_out, bias=True)
self.initialize_weights() # 创建对象时自动执行
def kernel_fun(self, batches):
n_input = batches.size(0) # number of inputs
A = self.centers.view(self.num_centers, -1).repeat(n_input, 1, 1)
B = batches.view(n_input, -1).unsqueeze(1).repeat(1, self.num_centers, 1)
C = torch.exp(-self.beta.mul((A - B).pow(2).sum(2, keepdim=False)))
return C
def forward(self, batches):
radial_val = self.kernel_fun(batches)
class_score = self.linear(torch.cat([batches, radial_val], dim=1))
return class_score
def initialize_weights(self, ):
"""
网络权重初始化
:return:
"""
for m in self.modules():
if isinstance(m, nn.Conv2d):
m.weight.data.normal_(0, 0.02)
m.bias.data.zero_()
elif isinstance(m, nn.ConvTranspose2d):
m.weight.data.normal_(0, 0.02)
m.bias.data.zero_()
elif isinstance(m, nn.Linear):
m.weight.data.normal_(0, 0.02)
m.bias.data.zero_()
def print_network(self):
num_params = 0
for param in self.parameters():
num_params += param.numel()
print(self)
print('Total number of parameters: %d' % num_params)
def train(train_loader, rbf):
optimizer = optim.SGD(rbf.parameters(), lr=0.000088, momentum=0.88)
closs = nn.CrossEntropyLoss()
for i, data in enumerate(train_loader):
optimizer.zero_grad()
inputs, labels = data
inputs, labels = inputs.to(device), labels.to(device)
pred = rbf(inputs)
loss = closs(pred, labels)
loss.backward()
optimizer.step()
def test(test_loader, rbf):
correct = 0
total = 0
for i, data in enumerate(test_loader):
inputs, labels = data
inputs, labels = inputs.to(device), labels.to(device)
pred = rbf(inputs)
_, predicted = torch.max(pred.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum()
print(' 准确率:{}%'.format(correct * 100 / total))
return correct * 100 / total
if __name__ == '__main__':
mnist_path = 'datasets/MNIST.mat'
lung_path = 'datasets/lung.mat'
yale_path = 'datasets/Yale.mat'
print('mnist: ')
batch_size = 50
input_size = 784
num_classes = 10
epoch = 20 # 0.5 0.3
data_x, train_data, test_data = load_data(mnist_path)
train_loader = DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=True)
rbf = RBFN(data_x, num_classes).to(device)
best = 0
for i in range(epoch):
print('epoch:', i, end='')
train(train_loader, rbf)
best = max(test(test_loader, rbf), best)
print('最高准确率:{}%'.format(best))
torch.cuda.empty_cache()
print('lung: ')
batch_size = 10
input_size = 3312
num_classes = 5
epoch = 20 # 0.5 0.3
data_x, train_data, test_data = load_data(lung_path)
train_loader = DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=True)
rbf = RBFN(data_x, num_classes).to(device)
best = 0
for i in range(epoch):
print('epoch:', i, end='')
train(train_loader, rbf)
best = max(test(test_loader, rbf), best)
print('最高准确率:{}%'.format(best))
torch.cuda.empty_cache()
print('yale: ')
batch_size = 10
input_size = 1024
num_classes = 15
epoch = 20 # 0.5 0.3
data_x, train_data, test_data = load_data(yale_path)
train_loader = DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=True)
rbf = RBFN(data_x, num_classes).to(device)
best = 0
for i in range(epoch):
print('epoch:', i, end='')
train(train_loader, rbf)
best = max(test(test_loader, rbf), best)
print('最高准确率:{}%'.format(best))
torch.cuda.empty_cache()
实验四:聚类
1. 实验目的
1、掌握K均值(k-means)聚类算法。
2、掌握学习向量量化(LVQ)聚类算法。
3、掌握高斯混合(Mixture-of-Gaussian)聚类算法。
4、理解聚类相关指标。
2. 数据集介绍
| 数据集 | 样本数 | 维度 | 类数 | 数据类型 |
|---|
| mnist | 3000 | 784 | 10 | 手写体数字 |
| yale | 165 | 1024 | 15 | 人脸图像 |
| lung | 203 | 3312 | 5 | 生物数据 |
3. 实验内容
1、编写程序实现K均值(k-means)聚类算法。
2、编写程序实现学习向量量化(LVQ)聚类算法。
3、编写程序实现高斯混合(Mixture-of-Gaussian)聚类算法。
4、利用Acc(Accuracy)和NMI(标准互信息)指标评价上述聚类算法。
4. 代码实现
- K-means 聚类算法
# coding=utf-8
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.cluster import KMeans
from sklearn import metrics
import scipy.io as scio
from munkres import Munkres
def load_data(path):
data = scio.loadmat(path)
data_x = np.array(data['X'])
data_y = np.array(data['Y'][:, 0] - 1)
train_data, test_data, train_label, test_label = train_test_split(data_x, data_y, test_size=0.25, random_state=10)
return train_data, test_data, train_label, test_label
def best_map(L1, L2):
Label1 = np.unique(L1) # 去除重复的元素,由小大大排列
nClass1 = len(Label1) # 标签的大小
Label2 = np.unique(L2)
nClass2 = len(Label2)
nClass = np.maximum(nClass1, nClass2)
G = np.zeros((nClass, nClass))
for i in range(nClass1):
ind_cla1 = L1 == Label1[i]
ind_cla1 = ind_cla1.astype(float)
for j in range(nClass2):
ind_cla2 = L2 == Label2[j]
ind_cla2 = ind_cla2.astype(float)
G[i, j] = np.sum(ind_cla2 * ind_cla1)
m = Munkres()
index = m.compute(-G.T)
index = np.array(index)
c = index[:, 1]
newL2 = np.zeros(L2.shape)
for i in range(nClass2):
newL2[L2 == Label2[i]] = Label1[c[i]]
return newL2
def acc_rate(gt_s, s):
c_x = best_map(gt_s, s)
err_x = np.sum(gt_s[:] == c_x[:])
acc = err_x.astype(float) / (gt_s.shape[0])
return acc
if __name__ == '__main__':
mnist_path = 'datasets/MNIST.mat'
lung_path = 'datasets/lung.mat'
yale_path = 'datasets/Yale.mat'
print('mnist:')
train_data, test_data, train_label, test_label = load_data(mnist_path)
k_means = KMeans(n_clusters=10, random_state=0)
k_means.fit(train_data)
pred = k_means.predict(test_data)
print('准确率:', acc_rate(test_label, pred))
NMI = metrics.normalized_mutual_info_score(pred, test_label)
print('NMI: ', NMI)
print('lung:')
train_data, test_data, train_label, test_label = load_data(lung_path)
k_means = KMeans(n_clusters=5, random_state=0)
k_means.fit(train_data)
pred = k_means.predict(test_data)
print('准确率:', acc_rate(test_label, pred))
NMI = metrics.normalized_mutual_info_score(pred, test_label)
print('NMI: ', NMI)
print('yale:')
train_data, test_data, train_label, test_label = load_data(yale_path)
k_means = KMeans(n_clusters=15, random_state=0)
k_means.fit(train_data)
pred = k_means.predict(test_data)
print('准确率:', acc_rate(test_label, pred))
NMI = metrics.normalized_mutual_info_score(pred, test_label)
print('NMI: ', NMI)
- LVQ 聚类算法
# coding=utf-8
import numpy as np
from sklearn.model_selection import train_test_split
import scipy.io as scio
from munkres import Munkres
from sklearn import metrics
def load_data(path):
data = scio.loadmat(path)
data_x = np.array(data['X'])
data_y = np.array(data['Y'][:, 0] - 1)
train_data, test_data, train_label, test_label = train_test_split(data_x, data_y, test_size=0.25, random_state=10)
return train_data, test_data, train_label, test_label
def LVQ(X, y, k, MAX_TIME=100, ita=0.2):
init_index = np.random.choice(len(y), k)
px = X[init_index]
py = y[init_index]
for _ in range(MAX_TIME):
j = np.random.choice(len(y), 1)
xj, yj = X[j], y[j]
i = np.argmin([np.linalg.norm(xj - pi) for pi in px])
pyi = py[i]
if pyi == yj:
px[i] = px[i] + ita * (xj - px[i])
else:
px[i] = px[i] - ita * (xj - px[i])
return px
def PVQ_clustering(X, px):
return np.array(list(map(lambda x: np.argmin([np.linalg.norm(x - pi) for pi in px]), X)))
# 采用匈牙利算法处理标签
def best_map(L1, L2):
Label1 = np.unique(L1) # 去除重复的元素,由小大大排列
nClass1 = len(Label1) # 标签的大小
Label2 = np.unique(L2)
nClass2 = len(Label2)
nClass = np.maximum(nClass1, nClass2)
G = np.zeros((nClass, nClass))
for i in range(nClass1):
ind_cla1 = L1 == Label1[i]
ind_cla1 = ind_cla1.astype(float)
for j in range(nClass2):
ind_cla2 = L2 == Label2[j]
ind_cla2 = ind_cla2.astype(float)
G[i, j] = np.sum(ind_cla2 * ind_cla1)
m = Munkres()
index = m.compute(-G.T)
index = np.array(index)
c = index[:, 1]
newL2 = np.zeros(L2.shape)
for i in range(nClass2):
newL2[L2 == Label2[i]] = Label1[c[i]]
return newL2
# 计算精确度
def acc_rate(gt_s, s):
c_x = best_map(gt_s, s)
err_x = np.sum(gt_s[:] == c_x[:])
acc = err_x.astype(float) / (gt_s.shape[0])
return acc
if __name__ == '__main__':
mnist_path = 'datasets/MNIST.mat'
lung_path = 'datasets/lung.mat'
yale_path = 'datasets/Yale.mat'
print('mnist:')
train_data, test_data, train_label, test_label = load_data(mnist_path)
lvq = LVQ(train_data, train_label, 10)
pred = PVQ_clustering(test_data, lvq)
print('准确率:', acc_rate(test_label, pred))
NMI = metrics.normalized_mutual_info_score(pred, test_label)
print('NMI: ', NMI)
print('lung:')
train_data, test_data, train_label, test_label = load_data(lung_path)
lvq = LVQ(train_data, train_label, 5)
pred = PVQ_clustering(test_data, lvq)
print('准确率:', acc_rate(test_label, pred))
NMI = metrics.normalized_mutual_info_score(pred, test_label)
print('NMI: ', NMI)
print('yale:')
train_data, test_data, train_label, test_label = load_data(yale_path)
lvq = LVQ(train_data, train_label, 15)
pred = PVQ_clustering(test_data, lvq)
print('准确率:', acc_rate(test_label, pred))
NMI = metrics.normalized_mutual_info_score(pred, test_label)
print('NMI: ', NMI)
- Mixture-of-Gaussian 聚类算法
# coding=utf-8
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.mixture import GaussianMixture
from sklearn import metrics
import scipy.io as scio
from munkres import Munkres
def load_data(path):
data = scio.loadmat(path)
data_x = np.array(data['X'])
data_y = np.array(data['Y'][:, 0] - 1)
train_data, test_data, train_label, test_label = train_test_split(data_x, data_y, test_size=0.25, random_state=10)
return train_data, test_data, train_label, test_label
def best_map(L1, L2):
Label1 = np.unique(L1) # 去除重复的元素,由小大大排列
nClass1 = len(Label1) # 标签的大小
Label2 = np.unique(L2)
nClass2 = len(Label2)
nClass = np.maximum(nClass1, nClass2)
G = np.zeros((nClass, nClass))
for i in range(nClass1):
ind_cla1 = L1 == Label1[i]
ind_cla1 = ind_cla1.astype(float)
for j in range(nClass2):
ind_cla2 = L2 == Label2[j]
ind_cla2 = ind_cla2.astype(float)
G[i, j] = np.sum(ind_cla2 * ind_cla1)
m = Munkres()
index = m.compute(-G.T)
index = np.array(index)
c = index[:, 1]
newL2 = np.zeros(L2.shape)
for i in range(nClass2):
newL2[L2 == Label2[i]] = Label1[c[i]]
return newL2
def acc_rate(gt_s, s):
c_x = best_map(gt_s, s)
err_x = np.sum(gt_s[:] == c_x[:])
acc = err_x.astype(float) / (gt_s.shape[0])
return acc
if __name__ == '__main__':
mnist_path = 'datasets/MNIST.mat'
lung_path = 'datasets/lung.mat'
yale_path = 'datasets/Yale.mat'
print('mnist:')
train_data, test_data, train_label, test_label = load_data(mnist_path)
gm = GaussianMixture(n_components=10, random_state=0)
gm.fit(train_data)
pred = gm.predict(test_data)
print('准确率:', acc_rate(test_label, pred))
NMI = metrics.normalized_mutual_info_score(pred, test_label)
print('NMI: ', NMI)
print('lung:')
train_data, test_data, train_label, test_label = load_data(lung_path)
gm = GaussianMixture(n_components=5, random_state=0)
gm.fit(train_data)
pred = gm.predict(test_data)
print('准确率:', acc_rate(test_label, pred))
NMI = metrics.normalized_mutual_info_score(pred, test_label)
print('NMI: ', NMI)
print('yale:')
train_data, test_data, train_label, test_label = load_data(yale_path)
gm = GaussianMixture(n_components=15, random_state=0)
gm.fit(train_data)
pred = gm.predict(test_data)
print('准确率:', acc_rate(test_label, pred))
NMI = metrics.normalized_mutual_info_score(pred, test_label)
print('NMI: ', NMI)