生成式模型

生成式模型本文通过分类问题讲解判别式和生成式模型,会用到LogisticsRegression和几率模型首先介绍一下,判别式模型是完全根据数据得出结果,而生成式模型会有人为设定的条件建立模型,再通过利用假设建立的模型得出结果。Generative(生成式模型)例:利用iris数据进行分类本文

大家好,欢迎来到IT知识分享网。

本文通过分类问题讲解判别式和生成式模型,会用到Logistics Regression 和 几率模型

首先介绍一下,判别式模型是完全根据数据得出结果,而生成式模型会有人为设定的条件建立模型,再通过利用假设建立的模型得出结果。

Generative (生成式模型)

例: 利用iris数据进行分类
本文仅仅才用了target0和target1,且仅仅利用了前两种属性(便于可视化)

数据可视化
在这里插入图片描述
利用生成式建立模型,首先假设每一种花的属性服从高斯分布,即

\[f(x) = \frac{1}{\sqrt{2 \pi}\sigma}e^{-\frac{(x-u)^2}{2\sigma^2}} \]

相当于每一种属性主要分布在在以\(u\)为中心,以\(\sigma\)为半径的圆中。
这样就可以利用概率的大小来判断图中对应的点应该属于哪一个分组。例如此例中在这里插入图片描述
越靠近某类中心,该点为此类的概率越大。(本文假设其服从高斯分布,也可以假设其为其他分布,这也是生成式模型与判别式模型的不同之处

首先看蓝色的点,由于我们假设其为高斯分布,也就是说,某一个高斯分布会产生如此分布的点。很明显,这样高斯分布有无穷多个,我们需要找到一个高斯分布能够最大概率的生成这样分布的点。这就需要用到最大似然估计。

首先对于一个高斯分布的模型(参数为\(u,\sigma\)),图中的任何一个点都会产生一个概率,我们只需要找到一个模型,让产生这些点的概率最大即可(最大似然估计),公式化即为

\[\begin{aligned} L(u,\sigma) &= f_{u,\sigma}(x^1)f_{u,\sigma}(x^2)\cdots f_{u,\sigma}(x^n) \\ &= \prod_{i=1}^{n} f_{u,\sigma}(x^i) \end{aligned} \]

极大似然函数

\[u^{‘} ,\sigma^{‘} = \mathop{\arg \max_{u, \sigma}(L(u,\sigma))} \]

明显对于连乘的问题取对数变为连加问题

\[L(u,\sigma) = \sum_{i=0}^{n}f_{u,\sigma}(x^i) \]

将偏导数等于0,求得\((u^{‘},\sigma^{‘})\)


这部分可跳过。

以下为 \(u\) 的推导过程,(字很丑,请忽略,,,)

打开链接即可,,,csdn总是加载失败,,emmm
http://img.caohongchuan.cn/picgo/20190708203542.jpg

得出

\[u^{‘} = \frac{1}{n} \sum_{i=1}^{n}x^i \]

\[\sigma^{‘} = \frac{1}{n} \sum_{i=1}^{n}(x^i-u^{‘})^2 \]

分别求出attribute0和attribute1,得出
在这里插入图片描述
这即为蓝色点的中心。
其各自的方差为:
在这里插入图片描述


上面的推导过程都是利用1元高斯分布求得的,但是本文有2个自变量,\(attribute_0,attribute_1\),需要使用多元高斯分布。可参考博客

多元高斯分布

\[f(x) = \frac{1}{(\sqrt{2\pi})^n |\sum |^{\frac{1}{2}}}e^{-(x-u_x)^T \sum^{-1} (x-u_x)} \]

其中\(\sum\)为协方差矩阵,\(n\)为自变量的个数,\(u_x\)为每个自变量的均值
其中各个变量的均值和方差在一元高斯分布中已经求出。

之后,由贝叶斯公式

\[P(blue|x) =\frac{P(x|blue)P(blue)}{P(x|blue)P(blue)+P(x|green)P(green)} \]

其中\(P(blue) = \frac{N(blue)}{N(blue)+N(green)},P(green) = \frac{N(green)}{N(blue)+N(green)}\), 其中的\(P(x|blue),P(x|green)\)的概率由我们上方假定的高斯分布模型求出。

至此为止,我们已经能够得到 \(P(blue|x)\) 即选择一个x,其为blue类的概率。假设此概率大于0.5,我们就认为这个x属于blue类,否则不属于。

画出blue的高斯分布等高线
在这里插入图片描述

这样就可以求出两类的分界线。或许概率为0.6为分界线对上图更加合适(仅仅根据图做出的判断)一般都选0.5作为分界点。

分类问题结束。
总结一下 : 生成式模型最大的特点是假设了各个变量之间的联合分布函数\(f(attribute_0,attribue_1)\)——其服从高斯分布且两者相互独立。之后再利用贝叶斯公式,求得对于每个点其为blue类的概率。

对于判别式模型将利用Logistics Regression进行讲解

判别式模型讲解链接生成式模型


附上本文的代码(代码写的很烂,而且没有注释,,请大佬们勿笑,,)
为自己洗白一发,,这个代码没有通用性,所以我也懒得美化了,,就这样,,

# classification
# @author Hongchuan CAO
# @date 2019-7-8

from numpy.core.multiarray import ndarray
from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt
import copy

class Genrative:

    def __init__(self):
        self.iris = datasets.load_iris()
        self.part = [[],[],[]]


    def classify(self):
        for i in range(len(self.iris.target)):
            self.part[self.iris.target[i]].append(self.iris.data[i,:2])

        # change list to array
        for i in range(0,3):
            self.part[i] = np.array(self.part[i])

    def cal_par(self):
        u0 = np.mean(self.part[0],axis=0)
        u1 = np.mean(self.part[1],axis=0)

        record = copy.deepcopy(self.part)

        for i in range(len(record[0])):
            record[0][i][0] = (record[0][i][0] - u0[0])**2
            record[0][i][1] = (record[0][i][1] - u0[1])**2

        v0 = np.mean(record[0],axis=0)
        v1 = np.mean(record[1],axis=0)

        self.u = u0
        self.v = v0
        self.uu = u1
        self.vv = v1

    def f1(self,xx):
        u0 = self.u
        v0 = self.v

        summ = np.zeros([2,2])
        summ[0][0] = v0[0]
        summ[1][1] = v0[1]

        xx = xx-u0
        z = np.dot(np.dot(xx,np.linalg.inv(summ)),xx.T)
        zz = np.sqrt(np.linalg.det(summ))

        return 1.0/(zz*np.sqrt(2*np.pi)**2)*np.exp(-1/2*z)

    def f2(self,xx):
        u1 = self.uu
        v1 = self.vv

        summ = np.zeros([2,2])
        summ[0][0] = v1[0]
        summ[1][1] = v1[1]

        xx = xx-u1
        z = np.dot(np.dot(xx,np.linalg.inv(summ)),xx.T)
        zz = np.sqrt(np.linalg.det(summ))

        return 1.0/(zz*np.sqrt(2*np.pi)**2)*np.exp(-1/2*z)

    def pobablity(self,xx):
        p1 = len(self.part[0])/(len(self.part[0]+self.part[1]))
        p2 = len(self.part[1])/(len(self.part[0]+self.part[1]))

        return self.f1(xx)*p1/(self.f1(xx)*p1+self.f2(xx)*p2)

    def plot1(self):

        x_a = [x for x in np.arange(3,8,0.1)]
        y_a = [y for y in np.arange(1,6,0.1)]
        z_a = [[self.pobablity([xx,yy]) for xx in x_a] for yy in y_a]
        print(z_a)
        X,Y = np.meshgrid(x_a,y_a)
        cntr1 = plt.contourf(X,Y,z_a)
        plt.clabel(cntr1, colors='k', inline_spacing=3, fmt='%.1f', fontsize=10)

        plt.plot(self.part[0][:,0], self.part[0][:,1], 'b.', label='0')
        plt.plot(self.part[1][:,0], self.part[1][:,1], 'g.', label='1')
        # plt.plot(self.part[2][:,0], self.part[2][:,1], 'r.', label='2')
        plt.legend()
        plt.xlabel('attribute0')
        plt.ylabel('attribute1')
        plt.show()

if __name__ == '__main__':
    obj = Genrative()
    obj.classify()
    obj.cal_par()
    obj.plot1()

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/32395.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信