实验1. 用贝叶斯方法进行性别分类的实验
基本要求:
- 1. 用FAMALE.TXT和MALE.TXT的数据作为训练样本集,建立Bayes分类器,用测试样本数据对该分类器进行测试。
- 2. 调整特征、分类器等方面的一些因素,考察它们对分类器性能的影响,从而加深对所学内容的理解和感性认识。
具体做法:
- 应用单个特征进行实验:以(a)身高或者(b)体重数据作为特征,在正态分布假设下利用‘最大似然法’估计概率密度函数(第三章内容基于参数的估计方法,gaussion(x,y)),建立最小错误率Bayes分类器,写出得到的决策规则;将该分类器应用到测试样本,考察测试错误情况。在分类器设计时可以考察采用不同先验概率(如0.5对0.5, 0.75对0.25, 0.9对0.1等)进行实验,考察对决策规则和错误率的影响。
- 应用两个特征进行实验:同时采用身高和体重数据作为特征,假设二者不相关(协方差矩阵>0正相关,<0负相关,=0不相关,C 2*2),在正态分布假设下估计概率密度函数,建立最小错误率Bayes分类器,写出得到的决策规则;将该分类器应用到训练/测试样本,考察训练/测试错误情况。在分类器设计时可以考察采用不同先验概率(如0.5 vs. 0.5, 0.75 vs. 0.25, 0.9 vs. 0.1等)进行实验,考察对决策和错误率的影响。
- 应用两个特征进行实验:同时采用身高和体重数据作为特征,假设二者相关,在正态分布假设下估计概率密度函数,建立最小错误率Bayes分类器,写出得到的决策规则,将该分类器应用到训练/测试样本,考察训练/测试错误情况。比较相关假设和不相关假设下结果的差异。在分类器设计时可以考察采用不同先验概率(如0.5 vs. 0.5, 0.75 vs. 0.25, 0.9 vs. 0.1等)进行实验,考察对决策和错误率的影响。
- 应用两个特征进行实验:同时采用身高和体重数据作为特征,利用PCA进行变换(K=2不压缩维度;K=1压缩特征),在正态分布假设下估计概率密度函数,建立最小错误率Bayes分类器,写出得到的决策规则,将该分类器应用到训练/测试样本,考察训练/测试错误情况,并与变换前结果进行比较。
- 自行给出一个风险表,采用最小风险的Bayes决策重复上面的某个或全部实验。
实验2. 用线性判别方法进行性别分类的实验(第四章线性判别函数)
基本要求:
- 设计线性分类器,与基于概率密度估计的贝叶斯分类器进行比较。
具体做法:
- 同时采用身高和体重数据作为特征,用Fisher线性判别方法构建分类器,将该分类器应用到训练和测试样本,考察训练和测试错误情况。将训练样本和求得的决策边界画到图上。
- 利用PCA变换样本的特征空间(k=2),构建Fisher线性判别分类器,并与上述方法的结果进行比较。
- 将Fisher线性判别分类器的识别结果与贝叶斯分类器的识别结果进行比较分析。(与实验内容1进行比较)
实验3. 用近邻法进行性别分类的实验(第六章近邻法)
基本要求:
- 采用最近邻法、k-近邻法及压缩k-近邻法进行分类,与基于概率密度估计的贝叶斯分类器进行比较。
具体做法:
- 同时采用身高和体重数据作为特征,用最近邻法(k=1)进行分类,考察测试准确率。
- 同时采用身高和体重数据作为特征,用k-近邻进行分类,考察不同k取值情况下的测试准确率(第一章)。
- 同时采用身高和体重数据作为特征,用压缩k-近邻法进行分类,考察测试准确率。
- 对不同方法的结果(最近邻、K近邻、压缩近邻)进行比较。
实验4. 用PCA方法进行人脸识别的实验(第八章特征提取)
基本要求:
- 利用ORL人脸数据库作为训练集和测试集,实现人脸识别系统。
- 采用N-交叉法估计错误率(第一章系统性能)。
具体做法:
- 利用PCA方法对人脸数据进行特征降维(pca里面的K),采用k-近邻法进行人脸识别。
- 用N-交叉法估计准确率,对不同降维维数(pca里面的K)和k取值情况(k-近邻法里参数)下的准确率进行比较。
(选做)附加实验. 用卷积神经网络LeNet进行图像类型识别的实验
基本要求:
- 自选训练集和测试集,实现手写数字或图像识别系统。
- 统计系统的错误率。
import numpy as np
from sklearn.decomposition import PCA
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score
def read_data(file_path):
data = []
with open(file_path, 'r') as file:
for line in file:
items = line.strip().split()
if len(items) == 3:
label = 1 if items[2].lower() == 'm' else 0
value = float(items[0])
value1 = float(items[1])
data.append((value, value1, label))
if len(items) == 2:
value = float(items[0])
value1 = float(items[1])
data.append((value, value1))
return np.array(data)
# 读取数据
female_data = read_data('dataset\\FEMALE.TXT')
male_data = read_data('dataset\\MALE.TXT')
# 合并数据集
all_data = np.vstack((female_data, male_data))
all_labels = np.concatenate((np.zeros(len(female_data)), np.ones(len(male_data))))
# PCA转换
pca_k2 = PCA(n_components=2)
transformed_data_k2 = pca_k2.fit_transform(all_data)
pca_k1 = PCA(n_components=1)
transformed_data_k1 = pca_k1.fit_transform(all_data)
# 建立贝叶斯分类器
classifier_k2 = GaussianNB()
classifier_k1 = GaussianNB()
# 训练分类器
classifier_k2.fit(transformed_data_k2, all_labels)
classifier_k1.fit(transformed_data_k1, all_labels)
# 应用分类器到训练样本
predicted_labels_k2_train = classifier_k2.predict(transformed_data_k2)
predicted_labels_k1_train = classifier_k1.predict(transformed_data_k1)
# 计算训练错误率
error_rate_k2_train = 1 - accuracy_score(all_labels, predicted_labels_k2_train)
error_rate_k1_train = 1 - accuracy_score(all_labels, predicted_labels_k1_train)
# 显示结果
print("Training Error Rate (K=2):", error_rate_k2_train)
print("Training Error Rate (K=1):", error_rate_k1_train)
print(" (K=2):", (1-error_rate_k2_train)*100)
import numpy as np
import scipy.stats as stats
from scipy.stats import multivariate_normal
# 读取数据文件,这里假设数据文件中每行包含两个数据:身高或体重和对应的标签(0代表女生,1代表男生)
def read_data(file_path):
data = []
with open(file_path, 'r') as file:
for line in file:
items = line.strip().split()
if len(items)==3:
label = 1 if(items[2] == 'm' or items[2] == 'M') else 0
value = float(items[0])
value1 =float(items[1])
data.append((value,value1,label))
if len(items)==2:
value = float(items[0])
value1 =float(items[1])
data.append((value,value1))
return np.array(data)
female_data = read_data('dataset\\FEMALE.TXT')
male_data = read_data('dataset\\MALE.TXT')
# 提取身高或体重作为特征
# female_height = np.array([item[0] for item in female_data])
# female_weight = np.array([item[1] for item in female_data])
# male_height = np.array([item[0] for item in male_data])
# male_weight = np.array([item[1] for item in male_data])
# female_var_height = np.var(female_height) # 估计女生
# female_var_weight = np.var(female_weight) # 估计女生体重的方差
# male_var_height = np.var(male_height) # 估计男生身高的方差
# male_var_weight = np.var(male_weight) # 估计男生体重的方差
# 使用最大似然法估计正态分布的参数(均值和方差)
female_mean = np.mean(female_data, axis=0)
male_mean = np.mean(male_data, axis=0)
female_cov = np.cov(female_data.T)
male_cov = np.cov(male_data.T)
def bayes_classifier(value, prior_female, prior_male):
# 计算女生和男生的后验概率
likelihood_female = multivariate_normal.pdf(value, mean=female_mean, cov=np.diag(female_cov))
likelihood_male = multivariate_normal.pdf(value,mean=male_mean,cov=np.diag(male_cov))
posterior_female = likelihood_female * prior_female
posterior_male = likelihood_male * prior_male
# 根据后验概率比较,进行分类
if posterior_female > posterior_male:
return 0 # 女生类别
else:
return 1 # 男生类别
# 定义测试样本
test_samples1 = read_data('dataset\\test1.txt')
test_samples2=read_data('dataset\\test2.txt')
prior_female=0.5
prior_male=1-prior_female
# 应用分类器进行分类并计算错误率
errors = 0
for sample in test_samples1:
predicted_label = bayes_classifier(sample[:2],prior_female,prior_male)
if predicted_label != sample[2]:
errors += 1
for sample in test_samples2:
predicted_label = bayes_classifier(sample[:2],prior_female,prior_male)
if predicted_label != sample[2]:
errors += 1
error_rate = errors / (len(test_samples1)+len(test_samples2))
file_path='out_put2.txt'
with open(file_path,'a') as f:
print("先验概率f:m %.2f:%.2f \t 错误率:%f"%(prior_female,prior_male,error_rate),file=f)
print("Test Error Rate:", error_rate)
print("准确率%f"%((1-errors/330)*100))
import numpy as np
import scipy.stats as stats
from scipy.stats import multivariate_normal
# 读取数据文件,这里假设数据文件中每行包含两个数据:身高或体重和对应的标签(0代表女生,1代表男生)
def read_data(file_path):
data = []
with open(file_path, 'r') as file:
for line in file:
items = line.strip().split()
if len(items)==3:
label = 1 if (items[2] == 'm'or items[2] =='M' ) else 0
value = float(items[0])
value1 =float(items[1])
data.append((value,value1,label))
if len(items)==2:
value = float(items[0])
value1 =float(items[1])
data.append((value,value1))
return np.array(data)
female_data = read_data('dataset\\FEMALE.TXT')
male_data = read_data('dataset\\MALE.TXT')
female_mean = np.mean(female_data, axis=0)
male_mean = np.mean(male_data, axis=0)
female_cov = np.cov(female_data.T)
male_cov = np.cov(male_data.T)
def bayes_classifier(value, prior_female, prior_male):
# 计算女生和男生的后验概率
likelihood_female = multivariate_normal.pdf(value, mean=female_mean, cov=female_cov)
likelihood_male = multivariate_normal.pdf(value,mean=male_mean,cov=male_cov)
posterior_female = likelihood_female * prior_female
posterior_male = likelihood_male * prior_male
# 根据后验概率比较,进行分类
if posterior_female > posterior_male:
return 0 # 女生类别
else:
return 1 # 男生类别
# 定义测试样本
test_samples1 = read_data('dataset\\test1.txt')
test_samples2=read_data('dataset\\test2.txt')
#print(test_samples1)
prior_female=0.5
prior_male=1-prior_female
# 应用分类器进行分类并计算错误率
errors = 0
for sample in test_samples1:
print(sample[2])
predicted_label = bayes_classifier(sample[:2],prior_female,prior_male)
if predicted_label != sample[2]:
#print(predicted_label)
#print(sample[2])
errors += 1
for sample in test_samples2:
predicted_label = bayes_classifier(sample[:2],prior_female,prior_male)
if predicted_label != sample[2]:
errors += 1
error_rate = errors / (len(test_samples1)+len(test_samples2))
file_path='out_put3.txt'
with open(file_path,'a') as f:
print("先验概率f:m %.2f:%.2f \t 错误率:%f"%(prior_female,prior_male,error_rate),file=f)
print("Test Error Rate:", error_rate)
#print("准确率%f"%((1-errors/330)*100))
print((1-error_rate)*100)
import numpy as np
import scipy.stats as stats
# 读取数据文件,这里假设数据文件中每行包含两个数据:身高或体重和对应的标签(0代表女生,1代表男生)
def read_data(file_path):
data = []
with open(file_path, 'r') as file:
for line in file:
items = line.strip().split()
if len(items)==3:
label = 1 if (items[2] == 'm' or items[2] == 'M') else 0
value = float(items[1])
value1 =float(items[0])
data.append((value,label))
if len(items)==2:
value = float(items[1])
value1 =float(items[0])
data.append(value)
return data
female_data = read_data('dataset\\FEMALE.TXT')
male_data = read_data('dataset\\MALE.TXT')
# 提取身高或体重作为特征
female_features = np.array(female_data)
male_features = np.array(male_data)
# 使用最大似然法估计正态分布的参数(均值和方差)
female_mean, female_std = np.mean(female_features), np.std(female_features)
male_mean, male_std = np.mean(male_features), np.std(male_features)
# 定义正态分布概率密度函数
female_dist = stats.norm(female_mean, female_std)
male_dist = stats.norm(male_mean, male_std)
def bayes_classifier(value, prior_female, prior_male):
# 计算女生和男生的后验概率
likelihood_female = female_dist.pdf(value)
likelihood_male = male_dist.pdf(value)
posterior_female = likelihood_female * prior_female
posterior_male = likelihood_male * prior_male
# 根据后验概率比较,进行分类
if posterior_female > posterior_male:
return 0 # 女生类别
else:
return 1 # 男生类别
def bayes_classifier_risk(value, prior_female, prior_male,fenxian1,fenxian2,fenxian3,fenxian4):
# 计算女生和男生的后验概率
likelihood_female = female_dist.pdf(value)
likelihood_male = male_dist.pdf(value)
posterior_female = likelihood_female * prior_female
posterior_male = likelihood_male * prior_male
# 根据后验概率比较,进行分类
if posterior_female*fenxian1+posterior_male*fenxian2 > posterior_female*fenxian3+posterior_male*fenxian4:
return 1 # 返回男生类别
else:
return 0 # 女生类别
# 定义测试样本
test_samples1 = read_data('dataset\\test1.txt')
test_samples2=read_data('dataset\\test2.txt')
prior_female=0.2
prior_male=1-prior_female
# 应用分类器进行分类并计算错误率
errors = 0
for sample,label in test_samples1:
predicted_label = bayes_classifier(sample,prior_female,prior_male)
if predicted_label != label:
errors += 1
for sample,label in test_samples2:
predicted_label = bayes_classifier(sample,prior_female,prior_male)
if predicted_label != label:
errors += 1
error_rate = errors / (len(test_samples1)+len(test_samples2))
file_path='out_put1.txt'
with open(file_path,'a') as f:
print("先验概率f:m %.2f:%.2f \t 错误率:%f"%(prior_female,prior_male,error_rate),file=f)
fenxian11=0
fenxian12=3
fenxian21=4
fenxian22=0
errors = 0
for sample,label in test_samples1:
predicted_label = bayes_classifier(sample,prior_female,prior_male)
if predicted_label != label:
errors += 1
for sample,label in test_samples2:
predicted_label = bayes_classifier(sample,prior_female,prior_male)
if predicted_label != label:
errors += 1
error_rate = errors / (len(test_samples1)+len(test_samples2))
with open(file_path,'a') as f:
print("先验概率f:m %.2f:%.2f 风险表为%d %d \n %d %d \t 错误率:%f"%(prior_female,prior_male,fenxian11,fenxian12,fenxian21,fenxian22,error_rate),file=f)
print("Test Error Rate:", error_rate)
print("准确率%f"%((1-errors/330)*100))
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
# 定义LeNet模型
class LeNet(nn.Module):
def __init__(self):
super(LeNet, self).__init__()
self.conv1 = nn.Conv2d(1, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 4 * 4, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(nn.functional.relu(self.conv1(x)))
x = self.pool(nn.functional.relu(self.conv2(x)))
x = x.view(-1, 16 * 4 * 4)
x = nn.functional.relu(self.fc1(x))
x = nn.functional.relu(self.fc2(x))
x = self.fc3(x)
return x
# 数据预处理操作
transform = transforms.Compose([
transforms.ToTensor(), # 将图像转换为Tensor
transforms.Normalize((0.1307,), (0.3081,)) # 均值和标准差进行归一化
])
# 下载训练数据集
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
# 下载测试数据集
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)
# 类别标签
classes = tuple(str(i) for i in range(10))
# 初始化LeNet模型
net = LeNet()
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)
# 训练模型
for epoch in range(5): # 迭代5次
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 200 == 199: # 每200个batch打印一次损失值
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 200))
running_loss = 0.0
print('Finished Training')
# 在测试集上测试模型
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the 10000 test images: %d %%' % (
100 * correct / total))