-
K均值聚类
什么是K均值聚类
K均值聚类(k-means)是基于样本集合划分的聚类算法。K均值聚类将样本集合划分为k个子集,构成k个类,将n个样本分到k个类中,每个样本到其所属类的中心距离最小,每个样本仅属于一个类,这就是k均值聚类,同时根据一个样本仅属于一个类,也表示了k均值聚类是一种硬聚类算法。
k均值聚类的算法过程
输入:n个样本的集合
输出:样本集合的聚类
过程:
(1)初始化。随机选择k的样本作为初始聚类的中心。
(2)对样本进行聚类。针对初始化时选择的聚类中心,计算所有样本到每个中心的距离,默认欧式距离,将每个样本聚集到与其最近的中心的类中,构成聚类结果。
(3)计算聚类后的类中心,计算每个类的质心,即每个类中样本的均值,作为新的类中心。
(4)然后重新执行步骤(2)(3),直到聚类结果不再发生改变。
K均值聚类算法的时间复杂度是O(nmk),n表示样本个数,m表示样本维数,k表示类别个数。
-
K均值聚类是生成式还是判别式方法?
既不是生成式也不是判别式
-
KNN VS. K-means
K-Means和KNN的区别和联系
区别:
K-Means是无监督学习的聚类算法,没有样本输入;KNN是有监督学习的分类算法,有对应的类别输出。
KNN基本不需要训练,对测试集里的点只需要找到在训练集中最接近的k kk个点,用这最近的k kk个点的类别来决定测试点的类别;K-Means则有明显的训练过程,找到k kk个类别的最佳质心,从而决定样本簇类别。
联系:
两个算法都包含一个过程,即找出和某一点最近的点
两者都利用了最近邻的思想
K-近邻(K-nearest neighbor,KNN)
K-近邻算法的伪代码:
对未知类别属性的数据集中的每个点依次执行以下操作:
计算已知类别数据集中的点与当前点之间的距离;
按照距离递增次序排序;
选取与当前点距离最小的K个点;
确定前K个点所在类别出现的概率;
返回前K个点出现频率最高的类别作为当前点的预测分类。
K-均值聚类算法
K-均值聚类算法的伪代码:
创建K个点作为起始质心(经常是随机选择);
将数据集中的每一个点分配到一个簇中,具体来讲,为每个点找距其最近的质心,并将其分配给该质心所对应的簇;
上步完成之后,更新质心,每个簇的质心更新为该簇所有点的平均值;
当任意一个点的簇分配结果发生改变时,对数据集中的每个数据点,对每个质心,计算质心与数据点之间的距离,将数据点分配到距离其最近的簇,对每一个簇,计算簇中所有点的均值并将均值作为质心;
-
主成分分析
主成分分析法(无监督降维)是一个非监督学习的机器学习算法,主要用于数据的降维,对于高维数据,通过降维,可以发现更便于人类理解的特征。
降维:
降维有两种方法,一种是特征消除,另一种是特征提取
特征消除:将会在直接消除那些我们觉得不重要的特征,这会使我们对视这些特征中的很多信息。
特征提取:通过组合现有特征来创建新变量,可以尽量保存特征中存在的信息
PCA(主成分分析)就是一种常见的特征提取方法,PCA会将关系紧密的变量变成尽可能少的新变量,使这些新变量是两两不相关的,于是就可以用较少的综合指标分别代表存在于各个变量中的各类信息。
主成分分析
主成分分析的目的与功能
目的:
在多变量分析中,分析者所面临的的最大难题是解决众多变量之间的关系问题
解决多元回归分析中的多重共线性问题
主成分分析可以把这众多指标所蕴含的信息压缩到少数几个成分指标,然后给出这几个只成分指标的去那种,综合到一个评价指标中
主要功能:
数据降维
变量筛选
主成分是原始变量的线性组合
- 第一个主成分具有最大的方差值
- 第二主成分试图解释数据集中的剩余方差,并且与第一主成分不相关(正交)
- 第三主成分试图解释前两个主成分等没解释的方差
具体计算时根据方差来计算的
-
LDA VS. PCA
PCA与LDA的区别
所以PCA和LDA虽然都用到数据降维的思想,但是监督方式不一样,目的也不一样。
PCA是为了去除原始数据集中冗余的维度,让投影子空间的各个维度的方差尽可能大,也就是熵尽可能大。
LDA是通过数据降维找到那些具有discriminative的维度,使得原始数据在这些维度上的投影,不同类别尽可能区分开来。
PCA与LDA的相同点
均是降维方法
降维时均使用了矩阵特征分解的思想
两者都假设数据符合高斯分布
-
奇异值分解(SVD)
奇异值分解(Singular-Value Decomposition,简称SVD)是一种矩阵分解算法,用于将矩阵简化为其组成部分,以使某些后续矩阵计算更简单。
SVD中数据压缩上起着很重要的作用。比如一个典型的机器学习问题可能有着几百个或者更多的变量,而许多机器学习算法如果出现超过几十个就会崩溃,这使得奇异值分解在ML中对于变量减少是必不可少的。SVD将矩阵分解为一组向量v(可以看成多个列向量)、一组向量u(可以看成多个行向量)和一个对角矩阵(可以看成多个标量),即将矩阵分解为多项式。
-
特征人脸方法(Eigenface)
人脸识别之特征人脸方法是一种应用主成份分析来实现人脸图像降维的方法,其本质是用一种称为“特征人脸(eigenface)”的特征向量按照线性组合形式来表达每一张原始人脸图像,进而实现人脸识别。 基于奇异值分解(SVD)的思想,通过计算训练集中人脸图像的主成分,从而得到一组人脸特征向量,这些特征向量被称为Eigenface。
-
潜在语义分析 (LSA)
一种无监督学习方法,主要用于文本的话题分析
其特点是通过矩阵分解发现文本与单词之间的基于话题的语义关系
最初应用于文本信息检索,也被称为潜在语义索引(latent semantic indexing,LSI),在推荐系统、图像处理、生物信息学等领域也有广泛应用
文本信息处理中:
传统的方法以单词向量表示文本的语义内容,以单词向量空间的度量表示文本之间的语义相似度
潜在语义分析 旨在 解决这种方法不能准确表示语义的问题,试图从大量的文本数据中发现潜在的话题
以话题向量表示文本的语义内容,以话题向量空间的度量更准确地表示文本之间的语义相似度
-
期望最大化算法(EM)
们知道最大似然估计的根本目的是根据抽样的到的样本(即数据),反推出最有可能的分布参数(即模型),这是一个非常典型的机器学习的思想。所以在很多领域最大似然估计有着极为广泛的应用。然而,如果已知的数据中含有某些无法观测的隐藏变量时,直接使用最大似然估计是不足以解决问题的。这个时候就要依靠最大化期望(EM)算法了。
简单的说,EM算法是在依赖于无法观测的隐藏变量的概率模型中,寻找参数最大似然估计或者最大后验估计的算法。它通过迭代的方式,交替进行两个步骤:E步骤和M步骤,从而不断更新模型参数,直到收敛。
-
K-means是最简单的EM算法?
K-means可以理解为一种特殊的EM算法,并不是完全的属于EM算法。但其确实是一种最简单的特殊的EM算法
-
编程实现EM算法
# -*- coding: utf-8 -*-
import numpy as np
import math
import copy
import matplotlib.pyplot as plt
isdebug = True
# 指定k个高斯分布参数,这里指定k=2。注意2个高斯分布具有相同均方差Sigma,均值分别为Mu1,Mu2。
def init_data(Sigma,Mu1,Mu2,k,N):
global X
global Mu
global Expectations
X = np.zeros((1,N))
Mu = np.random.random(k)
Expectations = np.zeros((N,k))
for i in range(0,N):
if np.random.random(1) > 0.5:
X[0,i] = np.random.normal(Mu1, Sigma)
else:
X[0,i] = np.random.normal(Mu2, Sigma)
if isdebug:
print("***********")
print("初始观测数据X:")
print(X )
# EM算法:步骤1,计算E[zij]
def e_step(Sigma, k, N):
global Expectations
global Mu
global X
for i in range(0,N):
Denom = 0
Numer = [0.0] * k
for j in range(0,k):
Numer[j] = math.exp((-1/(2*(float(Sigma**2))))*(float(X[0,i]-Mu[j]))**2)
Denom += Numer[j]
for j in range(0,k):
Expectations[i,j] = Numer[j] / Denom
if isdebug:
print("***********")
print("隐藏变量E(Z):")
print(Expectations)
# EM算法:步骤2,求最大化E[zij]的参数Mu
def m_step(k,N):
global Expectations
global X
for j in range(0,k):
Numer = 0
Denom = 0
for i in range(0,N):
Numer += Expectations[i,j]*X[0,i]
Denom +=Expectations[i,j]
Mu[j] = Numer / Denom
# 算法迭代iter_num次,或达到精度Epsilon停止迭代
def run(Sigma,Mu1,Mu2,k,N,iter_num,Epsilon):
init_data(Sigma,Mu1,Mu2,k,N)
print("初始<u1,u2>:", Mu)
for i in range(iter_num):
Old_Mu = copy.deepcopy(Mu)
e_step(Sigma,k,N)
m_step(k,N)
print(i,Mu)
if sum(abs(Mu - Old_Mu)) < Epsilon:
break
if __name__ == '__main__':
sigma = 6 # 高斯分布具有相同的方差
mu1 = 40 # 第一个高斯分布的均值 用于产生样本
mu2 = 20 # 第二个高斯分布的均值 用于产生样本
k = 2 # 高斯分布的个数
N = 1000 # 样本个数
iter_num = 1000 # 最大迭代次数
epsilon = 0.0001 # 当两次误差小于这个时退出
run(sigma,mu1,mu2,k,N,iter_num,epsilon)
plt.hist(X[0,:],50)
plt.show()