GMM数据分类
最近接了一个小单子,做基于GMM数据分类的,实现程序如下所示:
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.preprocessing import Normalizer
from sklearn.metrics import accuracy_score
import os
import PySide2
dirname = os.path.dirname(PySide2.__file__)
plugin_path = os.path.join(dirname, 'plugins', 'platforms')
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_pathclass GMM:def __init__(self,Data,K,weights = None,means = None,covars = None):"""这是GMM(高斯混合模型)类的构造函数:param Data: 训练数据:param K: 高斯分布的个数:param weigths: 每个高斯分布的初始概率(权重):param means: 高斯分布的均值向量:param covars: 高斯分布的协方差矩阵集合"""self.Data = Dataself.K = Kif weights is not None:self.weights = weightselse:self.weights = np.random.rand(self.K)self.weights /= np.sum(self.weights) # 归一化col = np.shape(self.Data)[1]if means is not None:self.means = meanselse:self.means = []for i in range(self.K):mean = np.random.rand(col)#mean = mean / np.sum(mean) # 归一化self.means.append(mean)if covars is not None:self.covars = covarselse:self.covars = []for i in range(self.K):cov = np.random.rand(col,col)#cov = cov / np.sum(cov) # 归一化self.covars.append(cov) # cov是np.array,但是self.covars是listdef Gaussian(self,x,mean,cov):"""这是自定义的高斯分布概率密度函数:param x: 输入数据:param mean: 均值数组:param cov: 协方差矩阵:return: x的概率"""dim = np.shape(cov)[0]# cov的行列式为零时的措施covdet = np.linalg.det(cov + np.eye(dim) * 0.001)covinv = np.linalg.inv(cov + np.eye(dim) * 0.001)xdiff = (x - mean).reshape((1,dim))# 概率密度prob = 1.0/(np.power(np.power(2*np.pi,dim)*np.abs(covdet),0.5))*\np.exp(-0.5*xdiff.dot(covinv).dot(xdiff.T))[0][0]return probdef GMM_EM(self):"""这是利用EM算法进行优化GMM参数的函数:return: 返回各组数据的属于每个分类的概率"""loglikelyhood = 0oldloglikelyhood = 1len,dim = np.shape(self.Data)# gamma表示第n个样本属于第k个混合高斯的概率gammas = [np.zeros(self.K) for i in range(len)]while np.abs(loglikelyhood-oldloglikelyhood) > 0.00000001:oldloglikelyhood = loglikelyhood# E-stepfor n in range(len):# respons是GMM的EM算法中的权重w,即后验概率respons = [self.weights[k] * self.Gaussian(self.Data[n], self.means[k], self.covars[k])for k in range(self.K)]respons = np.array(respons)sum_respons = np.sum(respons)gammas[n] = respons/sum_respons# M-stepfor k in range(self.K):#nk表示N个样本中有多少属于第k个高斯nk = np.sum([gammas[n][k] for n in range(len)])# 更新每个高斯分布的概率self.weights[k] = 1.0 * nk / len# 更新高斯分布的均值self.means[k] = (1.0/nk) * np.sum([gammas[n][k] * self.Data[n] for n in range(len)], axis=0)xdiffs = self.Data - self.means[k]# 更新高斯分布的协方差矩阵self.covars[k] = (1.0/nk)*np.sum([gammas[n][k]*xdiffs[n].reshape((dim,1)).dot(xdiffs[n].reshape((1,dim))) for n in range(len)],axis=0)loglikelyhood = []for n in range(len):tmp = [np.sum(self.weights[k]*self.Gaussian(self.Data[n],self.means[k],self.covars[k])) for k in range(self.K)]tmp = np.log(np.array(tmp))loglikelyhood.append(list(tmp))loglikelyhood = np.sum(loglikelyhood)for i in range(len):gammas[i] = gammas[i]/np.sum(gammas[i])self.posibility = gammasself.prediction = [np.argmax(gammas[i]) for i in range(len)]def run_main():"""这是主函数"""# 导入Iris数据集iris = load_iris()label = np.array(iris.target)data = np.array(iris.data)print("Iris数据集的标签:\n",label)# 对数据进行预处理data = Normalizer().fit_transform(data)# 解决画图是的中文乱码问题mpl.rcParams['font.sans-serif'] = [u'simHei']mpl.rcParams['axes.unicode_minus'] = False# 数据可视化plt.scatter(data[:,0],data[:,1],c = label)plt.title("Iris数据集显示")plt.show()# GMM模型K = 3gmm = GMM(data,K)gmm.GMM_EM()y_pre = gmm.predictionprint("GMM预测结果:\n",y_pre)print("GMM正确率为:\n",accuracy_score(label,y_pre))plt.scatter(data[:, 0], data[:, 1], c=y_pre)plt.title("GMM结果显示")plt.show()if __name__ == '__main__':run_main()

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
