精通数据科学笔记 生成式模型

朴素贝叶斯:假设特征是条件独立,可用于文本分类,常作为原子模型与其他模型联结(connectionism)

判别式分析:假设特征类别已知的条件下服从正态分布,允许自变量之间有相关关系,只能处理连续型变量,常用来进行数据降维和联结其他模型,如 Gaussian HMM

隐马尔可夫模型:可用来处理序列数据,是在简单的生成式模型基础上加入马尔科夫链构成的简单图模型。可用于监督学习非监督学习


贝叶斯框架

条件概率:量化信息带来的价值

先验概率:P(X|y)

后验概率:P(y|X)

变量X,y的联合概率:

P(X,y)=P(X|y)P(y)

假设模型参数为\theta,则似然函数为

L=P(X|y,\theta )P(y|\theta )

参数的估计值为

\hat{\theta}=argmax_{\theta } P(X|y,\theta )P(y|\theta )

预测函数:最大化后验概率为

\hat{y}=argmax_{y}P(y|X),可简化为

\hat{y}=argmax_{y}P(X|y)P(y)

贝叶斯学派:根据新的信息,调整对模型参数的假设,理论严谨但实用性不强。

频率学派:认为模型参数不变,在求解模型时,参数的估计值是一个随机变量,它的随机性来自数据本身,可以通过假设检验或置信区间等统计工具来判断参数的估计值离真实值有多远。


朴素贝叶斯

朴素贝叶斯假设:各个特征独立同分布

朴素贝叶斯模型是一类简单的分类模型,包括伯努利模型多项式模型高斯模型,常用来进行文本分类

文本分类特征提取

文本分类属于自然语言处理(NLP),不同于字母语言,中文的语义单元包含词语,不仅仅是单个汉字。

用一系列变量表示文本或文字在学术上称为文字的特征提取。

首先对可能出现的文字组成一个字典,并对字典进行排序。则对于一个文本,可用字典长度大小的向量X表示,当文本中某个文字出现时,在这个文字的字典顺序对应位置上数字为1,否则为0.因此,多个文本可以构成高维稀疏矩阵。

伯努利模型

伯努利模型只能处理二值变量,且变量符合伯努利分布。参数估计值如下:

\hat{\theta _{l}}=\sum_{i=1}^{m}1_{\left \{ y_{i}=l \right \}}/m                          各类别文本数量训练数据中的占比

     某个文字出现的文本数量该类别文本数量中的占比

训练处模型参数以后,可以得到预测公式

\hat{y_{i}}=argmax_{l}\prod_{j=1}^{n}P(x_{i,j}|y_i=l)P(y_{i}=l)            找到一个使得概率最大类别

若预测文本中出现了字典中不存在的字(生僻字),会出现错误的预测结果,为避免这样的结果出现,需要引入平滑项(Laplace/Lidstone smoothing),平滑系数0<\alpha \leqslant 1,\alpha =1称为laplace smoothing,\alpha <1称为lidstone smoothing,将每个字的概率公式修改为:

多项式模型

一般来说,文本中一个字的出现次数越多,它与主题越相关,而伯努利模型不能处理这样的情况,引入多项式模型。

多项式模型的特征向量长度等于文本的字数长度,且向量第i个元素表示第i个位置上出现的文字序号(文字在字典中的序号)。

多项式模型假设,在文本类别已知的情况下,文本第i个位置出现某个字的概率只与字有关,与位置无关。(不管是哪个位置,只要是同一个字,那么就是同一个概率)

参数估计值为

\hat{\theta _{l}}=\sum_{i=1}^{m}1_{\left \{ y_{i}=l \right \}}/m                                                   某一类别文本数在训练集文本数中的占比

\hat{p_{k,l}}=\sum _{i,j}1_{\left \{ x_{i,j}=k,y_{i}=l \right \}}/\sum _{k}\sum _{i,j}1_{\left \{ x_{i,j}=k,y_{i}=l \right \}}           某一类别中某个字出现的次数在该类别所有字数中的占比

文字加权技术TF-IDF

某个文字在单文本中出现的比例越高,它与文本主题越相关

某个文字出现的文本数占总文本数的比例越小,它与文本主题越相关

基于这两点的文字加权技术为

TF_{i,k}=x_{i,k}/\sum _{k}x_{i,k}

TFIDF_{i,k}=TF_{i,k}IDF_{k}

通常对文本变量进行文字加权技术变换后使用多项式模型,可提升模型分类效果。

模型联结

先试用random trees embedding将原始低维数据映射到高维空间,再使用BernoulliNB对变换后的数据分类

代码实现

伯努利模型,多项式模型,用文字加权技术以后的多项式模型效果如下:

Use Bernoulli naive Bayes: 
前国际米兰巨星雷科巴正式告别足坛 ==> C11-Space
达芬奇:伟大的艺术家 ==> C11-Space
              precision    recall  f1-score   support

   C11-Space       0.62      0.83      0.71       205
C19-Computer       0.89      0.88      0.89       382
      C3-Art       0.78      0.75      0.76       242
  C39-Sports       0.77      0.66      0.71       351

 avg / total       0.79      0.78      0.78      1180

Use multinomial naive Bayes: 
前国际米兰巨星雷科巴正式告别足坛 ==> C39-Sports
达芬奇:伟大的艺术家 ==> C3-Art
              precision    recall  f1-score   support

   C11-Space       0.83      0.77      0.80       205
C19-Computer       0.90      0.89      0.89       382
      C3-Art       0.88      0.98      0.93       242
  C39-Sports       0.89      0.86      0.87       351

 avg / total       0.88      0.88      0.88      1180

Use TFIDF + multinomial naive Bayes: 
前国际米兰巨星雷科巴正式告别足坛 ==> C39-Sports
达芬奇:伟大的艺术家 ==> C3-Art
              precision    recall  f1-score   support

   C11-Space       0.93      0.84      0.88       205
C19-Computer       0.92      0.94      0.93       382
      C3-Art       0.86      0.87      0.86       242
  C39-Sports       0.86      0.89      0.87       351

 avg / total       0.89      0.89      0.89      1180

def trainBernoulliNB(data):
    """
    使用伯努利模型对数据建模
    """
    vect = CountVectorizer(token_pattern=r"(?u)\b\w+\b", binary=True)
    X = vect.fit_transform(data["content"])
    le = LabelEncoder()
    Y = le.fit_transform(data["label"])
    model = BernoulliNB()
    model.fit(X, Y)
    return vect, le, model


def trainMultinomialNB(data):
    """
    使用多项式模型对数据进行建模
    """
    pipe = Pipeline([("vect", CountVectorizer(token_pattern=r"(?u)\b\w+\b")),
        ("model", MultinomialNB())])
    le = LabelEncoder()
    Y = le.fit_transform(data["label"])
    pipe.fit(data["content"], Y)
    return le, pipe
def trainMultinomialNBWithTFIDF(data):
    """
    使用TFIDF+多项式模型对数据建模
    """
    pipe = Pipeline([("vect", CountVectorizer(token_pattern=r"(?u)\b\w+\b")),
        ("tfidf", TfidfTransformer(norm=None, sublinear_tf=True)),
        ("model", MultinomialNB())])
    le = LabelEncoder()
    Y = le.fit_transform(data["label"])
    pipe.fit(data["content"], Y)
    return le, pipe

 使用random forest embedding+伯努利模型对数据建模

pipe = Pipeline([("embedding", RandomTreesEmbedding(random_state=1024)),
        ("model", BernoulliNB())])
    pipe.fit(data[["x1", "x2"]], data["y"])
    return pipe

精通数据科学笔记 生成式模型_第1张图片


判别分析

判别分析放弃了条件独立的假设,允许变量间存在关联关系,这使得它的适用场景更多。主要包括两个模型:线性判别分析和二次判别分析

线性判别分析

模型假设,在类别已知的条件下,自变量X服从正态分布

对于不同的类别,自变量的协方差相同,期望不同。对于正态分布,协方差决定分布的形状,期望决定分布的中心位置

若协方差是对角矩阵,则自变量相互独立,否则,有相关性。

线性判别分析模型参数表达式为

\hat{\theta _{l}}=\frac{1}{m}\sum_{i=1}^{m}1_{\left \{ y_{i}=l \right \}}                             各类别在训练数据中的占比

\hat{\mu _{l}}=\sum_{i=1}^{m}X_{i}1_{\left \{ y_{i}=l \right \}}/\sum_{i=1}^{m}1_{\left \{ y_{i}=l \right \}}          各类别的中心位置,等于训练集中各个类别的平均值(自变量X的平均值)

\hat{\Sigma }=\frac{1}{m}\sum_{i=1}^{m}(X_{i}-\hat{\mu _{yi}})^{T}(X_{i}-\hat{\mu _{yi}})    各变量的协方差,它等于各个类别内部协方差的加权平均,权重为类别内数据的个数

从预测角度看,线性判别分析和逻辑回归是一样的。但逻辑回归不要求数据服从正态分布,在满足线性判别分析假设的条件下,线性判别分析的效果更高效。

自变量服从的先验分布类型可推导出逻辑回归的预测公式。

相比于判别式模型,生成式模型是“小而精”的模型。它们的模型假设更强,往往适用场景不多,一旦满足特定的假设,生成式模型的预测效果往往更好。

由模型决定的类别分离面(决策边界)是空间中的超平面,比如在二维空间中的一条直线。


数据降维

线性判别分析除了用于解决分类问题外还被用于数据降维,数据降维通常有3个目的:

  • 消除随机因素干扰
  • 避免过拟合问题
  • 降低工程实现难度

降维后的数据需要满足两个条件

  • 各类别中心越近越好
  • 各类别内部方差越小越好

但实际上这两个条件是相互矛盾的,如何寻求一个平衡?需要最大化“类别距离”

max_{k}(\mu _{0}-\mu _{1})^{2}/(\upsilon _{0}+\upsilon _{1})

公式中分子表示类别中心的距离,分母表示类别协方差

对于有标签的数据

线性判别分析:最大化后验概率

数据降维:最大化类别距离

二者殊途同归

代码实现

def dimensionReduction(X, y):
    """
    使用LDA模型将数据降到3维
    """
    model = LinearDiscriminantAnalysis(n_components=3)
    model.fit(X, y)
    newX = model.transform(X)
    return newX

精通数据科学笔记 生成式模型_第2张图片

二次判别分析

二次判别模型区分类别的中心位置,也区分不同类别在形状上的差异,与线性判别分析相比,不要求类别的协方差相同。

当协方差矩阵是对角矩阵时,二次判别分析就是朴素贝叶斯里的高斯模型,一般二次判别分析不用来数据降维。


隐马尔可夫模型

序列数据:数据间的顺序对数据本身有影响。

隐马尔可夫模型:是一类模型,不是单个模型。是一个基于贝叶斯框架的网络,被称为图模型(graphical model).

马尔科夫链

马尔科夫链描述一个随机过程,它的当前状态只与前一个状态有关系。

P(y_{i}|y_{i-1},y_{i-2},...,y_{0})=P(y_{i}|y_{i-1})

在已知当前状态的条件下,未来和过去是相互独立的

P(y_{0},...,y_{i-1},y_{i+1},..,y_{n}|y_{i})=P(y_{0},...,y_{i-1}|y_{i})P(y_{i+1},...,y_{n}|y_{i})

\left \{ y_{i} \right \}取值离散时,相应的马尔科夫链可由转移矩阵和初始分布(随机变量y_{0}的分布)表示。

假设y_{i}可能的取值有n个,则转移矩阵是n阶方阵,矩阵元素表示为状态i转移到状态j的概率

Q_{i,j}=P(y_{i}=j|y_{i-1}=i)

显然,状态转移矩阵的行和是1,表示状态i转移到其他所有状态的概率和。

模型架构

离散情况下的隐马尔可夫模型参数分为3部分:

  • 先验概率P(X_{i}|y_{i}):常用朴素贝叶斯模型来处理P(X_{i}|y_{i})
  • 初始分布P(y_{0}):离散状态下,它是一个多项式分布
  • 转移矩阵P(y_{i}|y_{i-1}):它与初始状态分布一起组成内在状态(hidden status)的马尔科夫链

数据的联合概率

P(X,y)=P(y_{0})P(y_{1}|y_{0})...P(y_{i}|y_{i-1})\prod _{j}P(X_{j}|y_{j})

参数的估计原则是最大化联合概率,预测公式为

\hat{Y}=argmax_{Y}P(y_{0},y_{1},...,y_{T}|X_{1},X_{2},...,X_{T})

预测公式的求解需要用维特比(Viterbi)算法,其中Y=(y_{0},...,y_{T})

中文分词:监督式学习

假设中文文字有四种状态:B,M,E,S,分别表示开头,中间,结尾和单独词,这样就把中文分词转换成了多元分类问题。用y_{i}表示第i个字的状态(B,M,E,S其中一个),x_{i}表示第i个字具体是什么文字,搭建模型如下:

先验概率P(X_{i}|y_{i}):在已知文字状态的情况下,每个汉字出现的概率,多用多项式模型的特征提取方法

初始分布P(y_{0}):每句话第一个字的状态分布

转移矩阵P(y_{i}|y_{i-1}):表示4种状态间相互转移的可能性

股票市场:非监督学习

若训练数据没有标签,即y_{i}是观测不到的,只有自变量X_{i},定义模型的似然函数如下

P(X|y,\theta )=P(y_{0}|\theta )\prod _{j}P(y_{i}|y_{i-1},\theta )\prod _{j}P(X_{j}|y_{j},\theta )

\hat{\theta },\hat{y}=argmax_{\theta ,y}P(X|y,\theta )

模型求解采用最大期望(EM)算法

只要给定y_{i}的取值(可随机生成),就能估算相应的模型参数

如果有模型参数(可随机生成),就能用维特比算法得到相应的预测值y_{i}

重复交叉使用这两步就是EM算法,第一步称为M step,第二步称为E step

用Gaussiain HMM对股票市场数据建模,结果如下

def transFeature(data):
    """
    提取特征,5日收益率,20日收益率,5日成交量增长率以及20日成交量增长率
    """
    data[["amount", "close_price"]] = data[["amount", "close_price"]].apply(pd.to_numeric)
    data["a_5"] = np.log(data["amount"]).diff(-5)
    data["a_20"] = np.log(data["amount"]).diff(-20)
    data["r_5"] = np.log(data["close_price"]).diff(-5)
    data["r_20"] = np.log(data["close_price"]).diff(-20)
    data["date2num"] = data["date"].apply(lambda x: date2num(datetime.strptime(x, "%Y-%m-%d")))
    data = data[data["date"] > "2005-06-01"]
    return data


def getHiddenStatus(data):
    """
    使用Gaussian HMM对数据进行建模,并得到预测值
    """
    cols = ["r_5", "r_20", "a_5", "a_20"]
    model = GaussianHMM(n_components=3, covariance_type="full", n_iter=1000,
        random_state=2010)
    model.fit(data[cols])
    hiddenStatus = model.predict(data[cols])
    return hiddenStatus

精通数据科学笔记 生成式模型_第3张图片

 

 

你可能感兴趣的:(精通数据科学笔记 生成式模型)