聚类算法
聚类的定义
- 一种典型的无监督学习算法,
- 主要用于将相似的样本自动归到一个类别中
- 计算样本和样本之间的相似性,一般使用欧式距离
聚类算法的概念
- 无监督学习,不需要y,将相似的样本自动归为一类
聚类算法与分类算法最大的区别
- 聚类是无监督 分类是有监督
- 聚类的类是未知的,不可解释;分类的类是已知的,可解释的
应用:
用户画像,广告推荐,Data Segmentation,搜索引擎的流量推荐,恶意流量识别
基于位置信息的商业推送,新闻聚类;离群点检测;信用卡异常消费;
聚类算法api初步使用
km=KMeans(n_clusters=4)#实例化对象
y_pred=km.fit_predict(X)#训练并预测
- sklearn.cluster.KMeans(n_clusters=8)
- 参数:
n_clusters:开始的聚类中心数量- 整型,缺省值=8,生成的聚类数,即产生的质心(centroids)数。
- 方法:
estimator.fit(x)
estimator.predict(x)
estimator.fit_predict(x)- 计算聚类中心并预测每个样本属于哪个类别,相当于先调用fit(x),然后再调用predict(x)
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs #生成球形数据
from sklearn.cluster import KMeans
from sklearn.metrics import calinski_harabaz_score
# 用Calinski-Harabasz Index评估的聚类分数
#创建数据集
X,y=make_blobs(n_samples=1000,n_features=2,
centers=[[-1, -1], [0, 0], [1, 1], [2, 2]],
cluster_std=[0.4,0.2,0.2,0.2],
random_state=9
)
X.shape
y[:10]
#绘制分布图
plt.figure(figsize=(10,10),dpi=100)
plt.scatter(X[:,0],X[:,1])
plt.show()
模型训练
km=KMeans(n_clusters=4)#实例化对象 分几簇
y_pred=km.fit_predict(X)#训练并预测 预测的结果是每个样本所属的簇下标
y_pred
#绘制图像
#绘制分布图
plt.figure(figsize=(10,10),dpi=100)
plt.scatter(X[:,0],X[:,1],c=y_pred) #c为不同类别设置不同颜色
plt.show()
print(calinski_harabaz_score(X, y_pred))
肘部法
sse=[]
#循环训练kmeans
for k in range(1,11):
km=KMeans(n_clusters=k)#设置不同的k值
km.fit(X)
#将每次训练得到的sse保存起来
sse.append(km.inertia_)
plt.plot(range(1,11),sse)
plt.show()
dir(km)
聚类算法实现流程
k-means其实包含两层内容:
K : 初始中心点个数(计划聚类数)
means:求中心点到其他数据点距离的平均值
k-means聚类步骤
EM算法阉割版 完整的em算法实现是GMM(高斯混合聚类)
EM算法思想是无监督学习的底层理论支撑
- 初始化k个中心点
- 聚簇 E
- 所有样本离谁近就给谁,分成k簇
- 更新中心点 M
- 计算每一簇样本的平均值
- 不断重复2-3步,知道满足条件
- 迭代步数
- 中心点不再发生偏移
模型评估
误差平方和(SSE \The sum of squares due to error)
- 条件固定情况下 越小越好
sse会随着簇的个数增加而不断减小
kmeans存在的问题 - 中心点的选择会影响聚类的结果
“肘”方法 (Elbow method) — K值确定
- 帮助我们确定最优k值
sse=[]
#循环训练kmeans
for k in range(1,11):
km=KMeans(n_clusters=k)#设置不同的k值
km.fit(X)
#将每次训练得到的sse保存起来
sse.append(km.inertia_)
plt.plot(range(1,11),sse)
plt.show()
- 选择肘部拐点作为最优k值
轮廓系数法(Silhouette Coefficient)
- [-1,1] 越大越好
- 求出所有样本的轮廓系数后再求平均值就得到了平均轮廓系数。
- 平均轮廓系数的取值范围为[-1,1],系数越大,聚类效果越好。
- 簇内样本的距离越近,簇间样本距离越远
- 最终求得是: 所有点的 平均轮廓系数
- 特点:计算量大
CH系数(Calinski-Harabasz Index)
- 分子:簇间方差 越大越好
- 分母:簇内方差 越小越好
- ch系数越大越好
- 为了抵消k值过大造成的影响,分母k-1
- 用尽量少的类别聚类尽量多的样本,同时获得较好的聚类效果。
hardvoting 和softvoting
- hard 不考虑概率
- 融合方式简单,模型就简单不容易过拟合
- soft 考虑概率
- 融合方式复杂,模型复杂,比hard更容易过拟合
算法优化
kmeans算法的优缺点:
- 优点
- 原理简单,容易实现
- 效果不错
- 样本数不多的情况下计算量小
- 算法复杂度 O(IkMN)
- I:迭代次数
- k:中心点个数
- M:样本数
- N:特征数
- 算法复杂度 O(IkMN)
- 缺点
- 容易受异常值影响 异常值会是的均值点发生偏移
- 不能够直观的对聚类结果进行观察
- 结果是局部最优(em算法本身的原因)
- 中心点的选择会影响聚类结果
Canopy算法配合初始聚类
Canopy原理
- T1,T2 T2>T1
- 不断的画小圆和大圆
- 作用:粗聚类,得到中心点和k值 喂给kmeans
K-means++
帮选择初始中心点的算法
sklearn中默认就是用kmeans++算法
- kmeans++目的,让选择的质心尽可能的分散
- 注意:sklearn中默认就是kmeans++
二分k-means
也是解决初始中心点的问题
- 不断的对sse最大的簇再次进行二分kmeans(k=2),知道簇数满足要求为止
k-medoids(k-中心聚类算法)
- 适用于小数据场景,解决kmeans对噪声敏感问题
- 均值对异常值敏感,中位数不受异常值影响
- 算法原理跟kmeans一样,除了中心点计算不一样,分簇都是一样的,离谁近给谁
- kmeans: 每个簇的均值点作为中心点 1,2,3,4,1000 均值=202
- 均值计算快
- k-mediods:每个簇的中位数点作为中心点 1,2,3,4,1000 中值=3
- 中位数计算需要排序
- 只适合小样本
- kmeans: 每个簇的均值点作为中心点 1,2,3,4,1000 均值=202
缺点:
- 效率低下: 中位数要排序,排序算法复杂度高
- 只适用于小数据集场景
- 大数据场景下,均值受异常值影响较小
Kernel k-means(了解)
将每个样本进行一个投射到高维空间的处理,然后再将处理后的数据使用普通的k-means算法思想进行聚类。
ISODATA(了解)—动态聚类
类别数目随着聚类过程而变化;
对类别数会进行合并,分裂,
“合并”:(当聚类结果某一类中样本数太少,或两个类间的距离太近时)
“分裂”:(当聚类结果中某一类的类内方差太大,将该类进行分裂)
Mini Batch K-Means(了解)
流程:
- 首先取出一批数据,做kmeans 得到k中心点
- E: 取出另一批数据,分配(离谁近给谁)
- M:更新中心点
- 循环迭代EM步 知道数据没有了
—解决大数据集场景的聚类
kmeans算法复杂度: O(IKMN)
- I 迭代次数
- K 簇数
- M 样本数
- N 特征数
特征降维
减少特征维度
-
特征选择— 保留的特征是原特征 A,B,C,D—>A,B,C
-
特征降维— 保留的特征不再是原特征 A,B,C,D—>a,b,c
-
特征选择: 减少维度,保留的特征还是原特征 A,B,C,D,E—特征选择—> A,C,D
- 过滤法
- 方差
- 相关性
- 递归消除法
- 最优子集搜索 遍历所有可能的特征子集,选一个最优的
- 局部最优子集搜索
- 正向特征选择
- 反向特征选择
- 嵌入法
- Lasso回归
- 决策树 feature_importances_
- 过滤法
-
特征降维:减少维度,保留的特征就不再是原特征了 A,B,C,D,E—特征降维—> x,y,z
- PCA主成分分析: 无监督
- LDA线性判别分析: 有监督
- smo自组织映射网络
- t-snet
特征选择——保留的特征是原来的特征
- 过滤法
- 通过某个指标过滤特征
- 指标:
- 单变量过滤
- 方差过滤 只看x本身 VarianceThreshold(threshold=1) 删掉方差小于阈值的列
- 多变量(x和y)
- x和y都连续数值
- 皮尔森相关系数—线性相关
- from scipy.stats import pearsonr
- 相关系数的值介于–1与+1之间,即–1≤ r ≤+1。其性质如下:
- 当r>0时,表示两变量正相关,r<0时,两变量为负相关
- 当|r|=1时,表示两变量为完全相关,当r=0时,表示两变量间无相关关系
- 当0<|r|<1时,表示两变量存在一定程度的相关。且|r|越接近1,两变量间线性关系越密切;|r|越接近于0,表示两变量的线性相关越弱
- 一般可按三级划分:|r|<0.4为低度相关;0.4≤|r|<0.7为显著性相关;0.7≤|r|<1为高度线性相关
- 斯皮尔曼相关系数— 非线性相关(秩相关)
- from scipy.stats import spearmanr
- 与之前的皮尔逊相关系数大小性质一样,取值 [-1, 1]之间
- 皮尔森相关系数—线性相关
- x和y都离散类别
- 卡方检验
- x和y都连续数值
- 单变量过滤
- 包装法
- 通过模型不断的筛选特征
- 方法:
- 递归特征消除法
- 最优子集搜索
- 局部最优子集搜索
- 嵌入法
- 利用模型输出特征的重要性,根据重要性选择特征
- 方法:
- 基于L1正则 L1正则可以让系数=0
- 基于树模型 feature_importances_属性
from sklearn.feature_selection import VarianceThreshold
import pandas as pd
# 方差过滤
data=pd.read_csv('data/factor_returns.csv')
data.head()
#拿到特征
x=data.iloc[:,1:10]
x.shape
x.var(0)
#进行选择
var=VarianceThreshold(threshold=1)
#过滤
new_x=var.fit_transform(x)
new_x.shape
new_x[:2]#保留的数据还是原数据 删掉了一列
皮尔森相关性
from scipy.stats import pearsonr,spearmanr
x1 = [12.5, 15.3, 23.2, 26.4, 33.5, 34.4, 39.4, 45.2, 55.4, 60.9]
x2 = [21.2, 23.9, 32.9, 34.1, 42.5, 43.2, 49.0, 52.8, 59.4, 63.5]
pearsonr(x1,x2)
spearmanr(x1,x2)
pca降维
x.shape
x.head()
#进行降维 指定的维数
from sklearn.decomposition import PCA
#实例化对象
pca=PCA(n_components=4)
#转换器
new_x=pca.fit_transform(x)
new_x.shape
new_x[:2]#保留的特征不再是原特征
#降到指定的百分比信息
#实例化对象
pca=PCA(n_components=0.99)#保留99%的方差
#转换器
new_x=pca.fit_transform(x)
new_x.shape
相关性补充
相关性
- 线性相关
- 皮尔森相关性
- [-1,1]
-
0正相关 <0负相关
- |r|<0.4为低度相关;0.4≤|r|<0.7为显著性相关;0.7≤|r|<1为高度线性相关
- 非线性相关
- 斯皮尔曼秩相关
- 肯德尔相关
- 相关性系数=0 并不一定意味着不相关
皮尔森相关系数
(Pearson Correlation Coefficient)
斯皮尔曼相关系数
(Rank IC)
n为等级个数,d为二列成对变量的等级差数
主成分分析pca
—保留的特征不再是原来的特征了 新特征是原特征的线性组合
- 特征选择
特征降维
pca=轴旋转(特征线性变换)+特征选择
sklearn.decomposition.PCA(n_components=None)
- 将数据分解为较低维数空间
- n_components:
- 小数:表示保留百分之多少的信息(方差)
- 整数:保留多少个特征
数据降维的技术:
- pca(无监督降维)
- lda(有监督降维)
- svd矩阵分解
- smo自组织映射网络
- 神经网络本质上也是特征映射和降维的技术
案例:探究用户对物品类别的喜好细分
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
1.获取数据
order_product = pd.read_csv("./data/instacart/order_products__prior.csv")
products = pd.read_csv("./data/instacart/products.csv")
orders = pd.read_csv("./data/instacart/orders.csv")
aisles = pd.read_csv("./data/instacart/aisles.csv")
2.数据基本处理
2.1 合并表格
# 2.1 合并表格
table1 = pd.merge(order_product, products, on=["product_id", "product_id"])
table2 = pd.merge(table1, orders, on=["order_id", "order_id"])
table = pd.merge(table2, aisles, on=["aisle_id", "aisle_id"])
2.2 交叉表合并 统计每个用户每个类别商品购买的次数
table = pd.crosstab(table["user_id"], table["aisle"])
2.3 数据截取
table = table[:1000]
3.特征工程 — pca 降维--因子分析
transfer = PCA(n_components=0.9)
data = transfer.fit_transform(table)
聚类分析
#分析特征的方差
new_x.var(axis=0)
#对特征进行标准化 kmeans是基于距离的算法
from sklearn.preprocessing import StandardScaler
sc=StandardScaler()
sc_x=sc.fit_transform(new_x)
4.机器学习(k-means) 聚类
estimator = KMeans(n_clusters=8, random_state=22)
km.fit(data)
评估
#轮廓系数
y_predict=km.predict(data)#预测样本的簇下标
#estimator.fit_predict(data)
5.模型评估
silhouette_score(data, y_predict)
分析结果
#聚类中心点
estimator.cluster_centers_#标准化后的聚类中心点
- 1.获取数据
- 2.数据基本处理
- 2.1 合并表格
- 2.2 交叉表合并
- 2.3 数据截取
- 3.特征工程 —
- pca
- 标准化
- 4.机器学习(k-means)
- 5.模型评估
- sklearn.metrics.silhouette_score(X, labels)
- 计算所有样本的平均轮廓系数
- X:特征值
- labels:被聚类标记的目标值
- sklearn.metrics.silhouette_score(X, labels)
- 6.分析聚类结果—— 分析各个簇的差异在哪里?
- 分析聚类中心点的特点
- 根据聚类标签分组统计进行分析