机器学习总结(四)

聚类算法

之前我们学习的都是有监督学习,这里我们要进入无监督的学习

无监督问题:没有标签

聚类:把相似的东西分为一组

K-means算法:

1.要得到簇的个数需要指定k值,例如k为5就分为5个簇

2.质心,就是向量各维度取的平均值

3.距离度量,常用欧几里得距离和余弦相似度,注意要先标准化

4.优化目标,找一个目标函数不断优化

优点:简单,快速,适用常规数据集

缺点:

1.k值难确定

2.复杂度与样本呈线性关系(因为到最后都要计算点到质心的距离,样本越多,计算量也就越大)

3.很难发现任意形状的簇

注意:k-means受初始值的影响很大(例如初始的质心位置选取不好,结果会很差)

k-means是基于距离进行聚类

DBSCAN算法:

当数据不规则时,DBSCAN效果比K-MEANS算法好的多

优点:1.不需要指定簇的个数

2.可以发现任意形状的簇

3.擅长找离群点(检测任务)

4.两个参数就够了

缺点:1.高维数据有些困难(可以做降维)

2.参数难以选择(参数对结果的影响非常大)

3.Sklearn中效率很慢(可以做数据消减策略)

一旦数据分布比较密集,它会把所有数据都圈成一个簇

能用分类就不要用聚类,如果数据集没有标签,也打不了标签,再考虑聚类

k-means比较适用于已经按堆排好的数据集

评估方法:

inertia每个样本与其质心的距离 (不是准确的)

对于k值如何选择

我们知道随着k的不断增大,inertia肯定是逐渐减小的,但是如何选择合适的k值呢

1.通过拐点(不一定)

将k值一个个带入,绘制图像,看图像中哪个k值有明显的变化,就可以选择其k值,或其附近的k值

2.轮廓系数

轮廓系数(Silhouette Coefficient)结合了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果。该值处于-1~1之间,值越大,表示聚类效果越好。具体计算方法如下:

  1. 对于每个样本点i,计算点i与其同一个簇内的所有其他元素距离的平均值,记作a(i),用于量化簇内的凝聚度。
  2. 选取i外的一个簇b,计算i与b中所有点的平均距离,遍历所有其他簇,找到最近的这个平均距离,记作b(i),即为i的邻居类,用于量化簇之间分离度。
  3. 对于样本点i,轮廓系数s(i) = (b(i) – a(i))/max{a(i),b(i)}
  4. 计算所有i的轮廓系数,求出平均值即为当前聚类的整体轮廓系数,度量数据聚类的紧密程度

从上面的公式,不难发现若s(i)小于0,说明i与其簇内元素的平均距离小于最近的其他簇,表示聚类效果不好。如果a(i)趋于0,或者b(i)足够大,即a(i)<<b(i),那么s(i)趋近与1,说明聚类效果比较好。

半监督学习:

数据集一部分有标签,一部分没有标签

kmeans算法来解决聚类问题:

注意:数据集是自制的

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs  # 生成用于聚类的各向同性高斯斑点
from sklearn.cluster import KMeans
blob_center = np.array(
    [[0.2,2.3],
     [-1.5,2.3],
     [-2.8,1.8],
     [-2.8,2.8],
     [-2.8,1.3]
    ]
)  # 以这5个点为中心,将来会向外发散,构建数据集
blob_std = np.array([0.4,0.3,0.1,0.1,0.1])
X, y = make_blobs(n_samples=2000, centers=blob_center,cluster_std=blob_std,
                  random_state=7)  # y值是所画的点所属于的簇的标签,再无监督学习里面,我们不用y值
print(X)
print(y)
# 绘制所自制的数据集的散点图
def plot_clusters(X,y=None):
    plt.scatter(X[:,0],X[:,1],c=y,s=1)
    plt.xlabel("$x_1$",fontsize=14)  # 这样会打印出来小写的x1
    plt.ylabel("$x_2$", fontsize=14,rotation=0)
plt.figure(figsize=(8,4))
plot_clusters(X)
plt.show()

k=5  # 自制的数据集,我们暂且未卜先知一下
kmeans = KMeans(n_clusters=k,random_state=42)
y_pred = kmeans.fit_predict(X)  # 这种方法不但训练了,还预测了结果
print(y_pred)
# 同时改类还有很多属性,我们可以一一调用
print(kmeans.labels_)  # 训练样本预测的标签
print(kmeans.cluster_centers_)  # 每个簇的质心位置

# 构建测试数据,看看它们分别属于什么簇
X_new = np.array([[0,2],[3,2],[-3,3],[-3,2.5]])
print(kmeans.predict(X_new))
print(kmeans.transform(X_new)) # 当前每个样本到各个簇质心的距离

# 可视化展示
def plot_data(X):
    plt.plot(X[:,0],X[:,1],'k.',markersize=2)
def plot_centroids(centroids,weights=None,circle_color='w',cross_color='k'):
    if weights is not None:
        centroids = centroids[weigths > weights.max() / 10]
    plt.scatter(centroids[:,0],centroids[:,1],marker='o',s=30,linewidths=8,
                color=circle_color,zorder=10,alpha=0.9)
    plt.scatter(centroids[:,0],centroids[:,1],marker='x',s=50,linewidths=50,
                color=cross_color,zorder=11,alpha=1)
def plot_decision_boundaries(clusterer,X,resolution=1000,show_centroids=True,
                             show_xlabels=True,show_ylabels=True):
    mins = X.min(axis=0) - 0.1
    maxs = X.max(axis=0) + 0.1
    xx,yy = np.meshgrid(np.linspace(mins[0],maxs[0],resolution),
                        np.linspace(mins[1], maxs[1], resolution))
    print(xx.shape)
    print(yy.shape)
    Z = clusterer.predict(np.c_[xx.ravel(),yy.ravel()])
    Z = Z.reshape(xx.shape)
    plt.contourf(Z,extent=(mins[0],maxs[0],mins[1],maxs[1]),  # 加f对决策边界里的内容进行填充
    cmap='Pastel2')
    plt.contour(Z, extent=(mins[0], maxs[0], mins[1], maxs[1]),
                linewidths=1,colors='k')
    plot_data(X)
    if show_centroids:
        plot_centroids(clusterer.cluster_centers_)
    if show_xlabels:
        plt.xlabel("$x_1$",fontsize=14)
    else:
        plt.tick_params(labelbottom='off')
    if show_ylabels:
        plt.ylabel("$x_2$", fontsize=14,rotation=0)
    else:
        plt.tick_params(labelleft='off')

plt.figure(figsize=(8,4))
plot_decision_boundaries(kmeans,X)
plt.show()

 

 

 dbscan解决聚类问题:

注意:数据集也是自制的,一切都是为了看出聚类算法的效果

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.cluster import DBSCAN
X,y = make_moons(n_samples=1000,noise=0.05,random_state=42)
plt.plot(X[:,0],X[:,1],'b.')
plt.show()

dbscan = DBSCAN(eps=0.2,min_samples=5)  # 主要就是这两个参数的选择,特别是半径
dbscan.fit(X)

# 调用一些属性值
print(dbscan.labels_)  # 查看训练之后的样本标签,-1代表离群点
print(np.unique(dbscan.labels_))  # 返回一共有多少个簇

 

我们是想找到合适的参数,使得样本分为上述两个簇

注意:dbscan可以理解为传销,不断的发展下线,从而找到所属的簇的范围

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值