课前问答
问:在22.6代码中往LDA中喂数据的时候,为什么要计算TF/ IDF?
答:一会解释,不算也可以
主要内容
2019-02-12 10_33_11-机器学习第七期升级版.png做LDA的时候,可以用TF-IDF做一个变换。
在给LDA喂数据的时候,我们认为整个LDA是一个词袋模型,每一个词是独立的,将该词出现的次数数出来,其实就是各个词的强度。
提到通过爬虫爬数据,获取数据源
朴素贝叶斯
2019-02-12 11_29_11-机器学习第七期升级版.png 2019-02-12 14_41_23-机器学习第七期升级版.png比如鸢尾花数据,有四个特征,即花萼长度,花萼宽度,花瓣长度,花瓣宽度,利用这四个特征,进行分类,分类结果为y(零散的0,1, 2三个值)。
利用贝叶斯公式可得:
P(y|花萼长度,花萼宽度,花瓣长度,花瓣宽度) = P(y)P(花萼长度,花萼宽度,花瓣长度,花瓣宽度|y) / P(花萼长度,花萼宽度,花瓣长度,花瓣宽度)
P(y)的含义:决定了y到底是0,1, 2哪一个的发生概率。
比如在150个鸢尾花数据中,有:
100: 0
30: 1
20: 2
假定从这个150个数据,随机拿出一条数据,是0的概率是2/3, 1的概率是1/5, 2的概率是2/15
即P(y)是先验概率。
P(xi|y)的含义,假定y是女生,xi是身高,且假定符合高斯分布,假定女生的身高均值是1.62米,如果xi是1.86米,则P(xi|y)的值就会低一些。
一般来说P(y)的概率,可以简单计算可得;
但是P(xi|y)就需要建模,但是需要建模成什么样的分布(高斯分布,多项分布,伯努利分布。。。)
2019-02-12 15_03_25-机器学习第七期升级版.png 2019-02-12 15_04_38-机器学习第七期升级版.png
对于多项式分布来说,如果xi的个数是n,y的类别离散值为k,则有Kxn个参数
比如,P(x=3|y=0),表示(y=0时,x=3出现了多少次)/ (y=0一共出现多少次),这个值就是频率,即用频率估计概率。
分子加上α, 分母加上α x n(为了保证加和为1),因此公式有可能是这样子的,对于文档做LDA的意义:第一,为了防止过拟合;第二,为了避免出现未登录词,分母为0.
即,如上图的公式。
附注:拉普拉斯平滑
2019-02-12 15_22_17-机器学习第七期升级版.png
通过高斯朴素贝叶斯,对鸢尾花做分类
以下代码,对邹博原有的代码做了一些修正:
- feature_names加入了“类别”,修正串列的问题
- features修改为花瓣长度与花瓣宽度,因为鸢尾花数据的花瓣长度起到分类决定性的作用
问答
2019-02-12 15_25_43-机器学习第七期升级版.png
问:朴素贝叶斯,朴素的点在哪?
答:之所以朴素,因为我们认为特征是相对条件独立的。但对于现实世界的认识,说实话是不对的。比如用身高、体重、腰围,推断某人性别,用朴素贝叶斯的话,根据公式:
可以推导,如果y是男性,其身高的概率密度,体重的概率密度,腰围的概率密度,但是根据朴素贝叶斯的定义,身高,体重,腰围应该是独立的,但从实际情况出发,从来不是。比如体重如果比较重,腰围一般粗一些;身高如果比较高,体重一般不会太轻,比如身高1米9,体重80斤的概率就非常非常小。
但是我们又可以通过假设的发散性,来解释朴素贝叶斯的应用: 2019-02-12 15_29_52-机器学习第七期升级版.png
此外,还有假设的内涵型: 2019-02-12 15_31_17-机器学习第七期升级版.png
假设的简化性: 2019-02-12 15_31_58-机器学习第七期升级版.png
朴素贝叶斯,还有一个特性是特征是均衡的。即它认为这些数是直接相乘的出来的: 2019-02-12 15_25_43-机器学习第七期升级版.png
问:朴素贝叶斯与贝叶斯有什么不同?
答:完全是两个东西啊。朴素贝叶斯是应用贝叶斯公式得出结论的。贝叶斯,我们往往指贝叶斯先验,就是说我们想求取参数,并不认为参数是未知或定知,而是认为其实随机变量,那么就是属于贝叶斯了。
问:如果有新词会不会就有某个p(x)=0?
答:是的,多项式朴素贝叶斯公式中的分子加α,分母加上α x n就是为了处理这种情况的。
问:如果考虑相关性呢?
答:如果考虑相关性,我们就退化为普通的贝叶斯网络了,特征间有连接了。所以朴素贝叶斯,就是贝叶斯网络的一个特殊情况,没有边,只有y与xi的连接,弧段的简单的贝叶斯网络。
问:如何去训练那个beta参数呢?
答:是有可能的。可以先验去训练一个beta参数,我们认为beta本身是服从一个分布,就可以训练。
问:有些独立假设在各个分类之间的分布都是均匀的,所以对于似然的相对大小不产生影响。即便不是如此,也有很大可能性,各个独立假设所产生的消极影响或积极影响互相抵消,最终导致结果受到的影响不大?
答:前面一句没什么问题。但是后面一句,不能说相互抵消,不一定这么乐观的去想,不能说相互抵消,而是发生震荡。对于复杂模型,需要验证是否能够做独立假设的前提。
在scikit-learn中,一共有3个朴素贝叶斯的分类算法类。分别是GaussianNB,MultinomialNB和BernoulliNB。其中GaussianNB就是先验为高斯分布的朴素贝叶斯,MultinomialNB就是先验为多项式分布的朴素贝叶斯,而BernoulliNB就是先验为伯努利分布的朴素贝叶斯。
这三个类适用的分类场景各不相同,一般来说,如果样本特征的分布大部分是连续值,使用GaussianNB会比较好。如果样本特征的分布大部分是多元离散值,使用MultinomialNB比较合适。而如果样本特征是二元离散值或者很稀疏的多元离散值,应该使用BernoulliNB。
#!/usr/bin/python
# -*- coding:utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn.preprocessing import StandardScaler, MinMaxScaler, PolynomialFeatures
# GaussianNB, 先验为高斯分布的朴素贝叶斯
# MultinomialNB, 先验为多项式分布的朴素贝叶斯
from sklearn.naive_bayes import GaussianNB, MultinomialNB
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
def iris_type(s):
it = {'Iris-setosa': 0, 'Iris-versicolor': 1, 'Iris-virginica': 2}
return it[s]
if __name__ == "__main__":
data_type = 'iris' # iris
if data_type == 'car':
colmun_names = 'buying', 'maint', 'doors', 'persons', 'lug_boot', 'safety', 'acceptability'
data = pd.read_csv('car.data', header=None, names=colmun_names)
for col in colmun_names:
data[col] = pd.Categorical(data[col]).codes
x = data[list(colmun_names[:-1])]
y = data[colmun_names[-1]]
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=0)
model = MultinomialNB(alpha=1)
model.fit(x_train, y_train)
y_train_pred = model.predict(x_train)
print('CAR训练集准确率:', accuracy_score(y_train, y_train_pred))
y_test_pred = model.predict(x_test)
print('CAR测试集准确率:', accuracy_score(y_test, y_test_pred))
else:
feature_names = '花萼长度', '花萼宽度', '花瓣长度', '花瓣宽度', '类别'
data = pd.read_csv('..\\9.Regression\\iris.data', header=None, names=feature_names)
x, y = data[list(feature_names[:-1])], data[feature_names[-1]]
y = pd.Categorical(values=data['类别']).codes
# features = ['花萼长度', '花萼宽度']
# 鸢尾花数据,花瓣长度起到决定性的作用
features = ['花瓣长度', '花瓣宽度']
x = x[features]
x, x_test, y, y_test = train_test_split(x, y, test_size=0.3, random_state=0)
priors = np.array((1,2,4), dtype=float)
priors /= priors.sum()
gnb = Pipeline([
('sc', StandardScaler()),
('poly', PolynomialFeatures(degree=1)),
('clf', GaussianNB(priors=priors))]) # 由于鸢尾花数据是样本均衡的,其实不需要设置先验值
# gnb = KNeighborsClassifier(n_neighbors=3).fit(x, y.ravel())
gnb.fit(x, y.ravel())
y_hat = gnb.predict(x)
print('IRIS训练集准确度: %.2f%%' % (100 * accuracy_score(y, y_hat)))
y_test_hat = gnb.predict(x_test)
print('IRIS测试集准确度:%.2f%%' % (100 * accuracy_score(y_test, y_test_hat))) # 画图
N, M = 500, 500 # 横纵各采样多少个值
x1_min, x2_min = x.min()
x1_max, x2_max = x.max()
t1 = np.linspace(x1_min, x1_max, N)
t2 = np.linspace(x2_min, x2_max, M)
x1, x2 = np.meshgrid(t1, t2) # 生成网格采样点
x_grid = np.stack((x1.flat, x2.flat), axis=1) # 测试点
mpl.rcParams['font.sans-serif'] = ['simHei']
mpl.rcParams['axes.unicode_minus'] = False
cm_light = mpl.colors.ListedColormap(['#77E0A0', '#FF8080', '#A0A0FF'])
cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])
y_grid_hat = gnb.predict(x_grid) # 预测值
y_grid_hat = y_grid_hat.reshape(x1.shape)
plt.figure(facecolor='w')
plt.pcolormesh(x1, x2, y_grid_hat, cmap=cm_light) # 预测值的显示
plt.scatter(x[features[0]], x[features[1]], c=y, edgecolors='k', s=30, cmap=cm_dark)
plt.scatter(x_test[features[0]], x_test[features[1]], c=y_test, marker='^', edgecolors='k', s=40, cmap=cm_dark)
plt.xlabel(features[0], fontsize=13)
plt.ylabel(features[1], fontsize=13)
plt.xlim(x1_min, x1_max)
plt.ylim(x2_min, x2_max)
plt.title('GaussianNB对鸢尾花数据的分类结果', fontsize=18)
plt.grid(True, ls=':', color='#202020')
plt.show()
结果如下:
IRIS训练集准确度: 96.19%
IRIS测试集准确度:97.78%
2019-02-12 11_27_42-Figure 1.png
LDA的实现
2019-02-12 15_44_43-机器学习第七期升级版.pngVBEM:变分期望最大化
Gensim:LDA的实现,是改进了David Blei的LDA-C的算法,并且使用了在线变分。
2019-02-12 18_20_03-机器学习第七期升级版.png
LSI/ LFM/ ICA本质都可以看做一个矩阵的分解。
只要求出语料的LDA,就能计算出任意两个语料之间的相似度
2019-02-12 18_22_28-机器学习第七期升级版.png
我们使用余弦相似度的话,其实余弦相似度0~180,取值范围是1~-1的,负值的概念是不止不相似,甚至相反,即背道而驰的两个方向。
类似于:终结者 与 武侠两个词,一个属于科幻,一个属于传统,它们的套路与想法完全不同。也许就是负的。
2019-02-12 18_25_52-机器学习第七期升级版.png
不管用LDA还是LSA,都能算出任何一个文档,属于某个主题的概率
以及某主题,前n个重要的词
2019-02-12 18_28_10-机器学习第七期升级版.png
通过爬虫爬出新闻语料
2019-02-12 18_29_27-机器学习第七期升级版.png
通过TF/ IDF模型得到文档的每一个词的向量,然后喂给LDA,就能够做每一个文档的主题分布,以及观察每个主题分布在哪
2019-02-12 18_30_41-机器学习第七期升级版.png
2019-02-12 18_31_37-机器学习第七期升级版.png
图形化主题与主题分布。
如图,可以观察各个文档,最突出的主题是什么
也可以观察每个主题的词分布情况
2019-02-12 18_32_30-机器学习第七期升级版.png
示例:
2019-02-12 18_36_09-机器学习第七期升级版.png
2019-02-12 18_37_27-机器学习第七期升级版.png
网友评论