机器学习:常用聚类算法

  聚类就是对大量未知标注的数据集,按数据的内在相似性将数据集划分为多个类别,使类别内的数据相似度较大而类别间的相似度较小。聚类是一种“无监督学习”任务。

1 常用距离计算及相似度方法

  在聚类任务中,通常是基于某种形式的距离或相似性度量来定义数据之间的相似度。当使用距离衡量样本相似性时,距离越大,相似度越低。给定样本 X i = ( x i 1 ; x i 2 ; …   ; x i n ) X_{i}=(x_{i1};x_{i2};\dots;x_{in}) Xi=(xi1;xi2;;xin) X j = ( x j 1 ; x j 2 ; …   ; x j n ) X_{j}=(x_{j1};x_{j2};\dots;x_{jn}) Xj=(xj1;xj2;;xjn),聚类中的常用的计算样本 X i X_{i} Xi X j X_{j} Xj的距离或相似度的方法主要有:

  • 闵可夫斯基距离:其计算公式如下: d i s t ( X , Y ) = ( ∑ k = 1 n ∣ x i k − x j k ∣ p ) 1 / p dist(X,Y)=(\sum_{k=1}^{n}|x_{ik}-x_{jk}|^{p})^{1/p} dist(X,Y)=(k=1nxikxjkp)1/p其中 p ≥ 1 p\geq1 p1。当 p = 1 p=1 p=1时,闵可夫斯基距离即为曼哈顿距离;当 p = 2 p=2 p=2时,闵可夫斯基距离即为欧式距离。闵可夫斯基距离主要应用于有序属性。
  • 杰卡德(Jaccard)距离:杰卡德距离是依据杰卡德系数来计算的。杰卡德系数的计算公式如下: J ( X i , X j ) = ∣ X i ⋂ X j ∣ ∣ X i ⋃ X j ∣ J(X_{i},X_{j})=\frac{|X_{i}\bigcap X_{j}|}{|X_{i}\bigcup X_{j}|} J(Xi,Xj)=XiXjXiXjJaccard距离的计算公式如下: d i s t ( X i , X j ) = 1 − J ( X i , X j ) dist(X_{i},X_{j})=1-J(X_{i},X_{j}) dist(Xi,Xj)=1J(Xi,Xj)Jaccard距离主要用于无序属性。
  • 切比雪夫距离:该度量将两个样本之间的距离定义为各坐标数值差绝对值的最大值。其计算公式如下: d ( X i , X j ) = m a x ( ∣ x i 1 − x j 1 ∣ , ∣ x i 2 − x j 2 ∣ , … , ∣ x i n − x j n ∣ ) d(X_{i},X_{j})=max(|x_{i1}-x_{j1}|,|x_{i2}-x_{j2}|,\dots,|x_{in}-x_{jn}|) d(Xi,Xj)=max(xi1xj1,xi2xj2,,xinxjn)
  • 余弦相似度:其计算公式如下: c o s ( X i , X j ) = X i T ⋅ X j ∣ X i ∣ ⋅ ∣ X j ∣ cos(X_{i},X_{j})=\frac{X_{i}^{T}\cdot X_{j}}{|X_{i}|\cdot |X_{j}|} cos(Xi,Xj)=XiXjXiTXj
  • Pearson相似系数:其计算公式如下: ρ X i X j = c o v ( X i , X j ) σ X i σ X j = ∑ k = 1 n ( x i k − X ‾ i ) ( x j k − X ‾ j ) ∑ k = 1 n ( x i k − X ‾ i ) 2 ∑ k = 1 n ( x j k − X ‾ j ) 2 \rho_{X_{i}X_{j}}=\frac{cov(X_{i},X_{j})}{\sigma_{X_{i}}\sigma_{X_{j}}}=\frac{\sum_{k=1}^{n}(x_{ik}-\overline X_{i})(x_{jk}-\overline X_{j})}{\sqrt{\sum_{k=1}^{n}(x_{ik}-\overline X_{i})^{2}}\sqrt{\sum_{k=1}^{n}(x_{jk}-\overline X_{j})^{2}}} ρXiXj=σXiσXjcov(Xi,Xj)=k=1n(xikXi)2 k=1n(xjkXj)2 k=1n(xikXi)(xjkXj)
2 常用聚类算法
2.1 k-均值算法

  k-均值(k-means)算法是一种常用的基于欧式距离的聚类算法。给定样本集 D = { x 1 , x 2 , … , x m } D=\{x_{1},x_{2},\dots,x_{m}\} D={x1,x2,,xm},k-means算法针对聚类所得簇划分 C = { C 1 , C 2 , … , C k } C=\{C_{1},C_{2},\dots,C_{k}\} C={C1,C2,,Ck}最小化平方误差: E = ∑ i = 1 k ∑ x ∈ C i ∥ x − μ i ∥ 2 E=\sum_{i=1}^{k}\sum_{x\in C_{i}}\|x-\mu_{i}\|^{2} E=i=1kxCixμi2其中 μ i = 1 ∣ C i ∣ ∑ x ∈ C i x \mu_{i}=\frac{1}{|C_{i}|}\sum_{x\in C_{i}}x μi=Ci1xCix是簇 C i C_{i} Ci的均值向量。k-means算法通过贪心策略求解上式。其算法流程如下:

  1. 从数据集 D D D中随机选择 k k k个样本作为初始均值向量 { μ 1 , μ 2 , … , μ k } \{\mu_{1},\mu_{2},\dots,\mu_{k}\} {μ1,μ2,,μk}
  2. 对于每个样本 x i x_{i} xi将其标记为距离类别中心最近的类别,即: l a b e l i = arg ⁡ min ⁡ 1 ≤ j ≤ k ∥ x i − μ j ∥ label_{i}=\arg\min\limits_{1\leq j\leq k}\|x_{i}-\mu_{j}\| labeli=arg1jkminxiμj
  3. 更新每个类别中心的值,其公式为: μ j = 1 ∣ C j ∣ ∑ i ∈ C j x i \mu_{j}=\frac{1}{|C_{j}|}\sum_{i\in C_{j}} x_{i} μj=Cj1iCjxi
  4. 重复以上两步,直到类别中心的变化小于某阈值或达到最大迭代次数等。

  k-means算法的优点主要包括有:原理简单,收敛速度快;算法的可解释性比较强;算法的参数少,只有一个簇数 k k k。其缺点主要有以下几个方面:

  • 在k-means算法中的 k k k是事先给定的,这个值的选定是非常难以估计;(目前可以使用轮廓系数等方法来帮助选择合适的 k k k值)
  • 在k-means算法中,首先需要根据初始聚类中心来确定一个初始划分,然后对初始划分进行优化。这个初始聚类中心的选择对聚类结果有较大的影响,一旦初始值选择的不好,可能无法得到有效的聚类结果;
  • 该算法需要不断地进行样本分类调整,不断地计算调整后的新的聚类中心,因此当数据量非常大时,算法的时间开销是非常大的;
  • 异常数据会对聚类结果产生较大影响;
  • 如果各隐含类别的数据不平衡,比如各隐含类别的数据量严重失衡,或者各隐含类别的方差不同,则聚类效果不佳;
  • 该算法不能处理非球状簇、不同尺寸和不同密度的簇;

  针对k-means算法的缺点,分别从以下几个方面对该算法进行了改进:

  • 为了降低初始聚类中心对聚类结果的影响,提出了k-means++算法。该算法按照如下思想选取聚类中心:假设已经选取了 n n n个初始聚类中心 ( 0 < n < k ) (0<n<k) (0<n<k),则在选取第 n + 1 n+1 n+1个聚类中心时:距离当前 n n n个聚类中心越远的点会有更高的概率被选为第 n + 1 n+1 n+1个聚类中心。在选取第一个聚类中心( n = 1 n=1 n=1)时同样采用随机的方法。
  • 为了降低异常值对聚类结果的影响,提出了k-mediods(k-中值聚类)。k-mediods算法选择簇中位置最接近簇中心的对象(称为中心点)作为簇的代表点。
2.2 DBSCAN算法

  DBSCAN是一种基于密度的聚类算法。该类算法假设聚类结构能通过样本分布的紧密程度确定。通常情况下,密度聚类算法从样本密度的角度来考察样本之间的可连接性,并基于可连接样本不断扩展聚类簇以获得最终的聚类结果。
  DBSCAN算法基于一组“邻域”参数 ( ϵ , M i n P t s ) (\epsilon,MinPts) (ϵ,MinPts)来刻画样本分布的紧密程度。给定数据集 D = { x 1 , x 2 , … , x m } D=\{x_{1},x_{2},\dots,x_{m}\} D={x1,x2,,xm},定义如下概念:

  • ϵ \epsilon ϵ邻域:对 x j ∈ D x_{j}\in D xjD,其 ϵ \epsilon ϵ邻域包含样本集 D D D中与 x j x_{j} xj的距离不大于 ϵ \epsilon ϵ的样本。即 N ϵ ( x j ) = { x i ∈ D ∣ d i s t ( x i , x j ) ≤ ϵ } N_{\epsilon}(x_{j})=\{x_{i}\in D|dist(x_{i},x_{j})\leq\epsilon\} Nϵ(xj)={xiDdist(xi,xj)ϵ};
  • 核心对象:若 x j x_{j} xj ϵ \epsilon ϵ-邻域至少包含 M i n P t s MinPts MinPts个样本,则称 x j x_{j} xj是一个核心对象;
  • 密度直达:若 x j x_{j} xj位于 x i x_{i} xi ϵ − \epsilon- ϵ邻域中,且 x i x_{i} xi核心对象,则称 x j x_{j} xj可由 x i x_{i} xi密度直达。
  • 密度相连:对 x i x_{i} xi x j x_{j} xj,若存在 x k x_{k} xk使得 x i x_{i} xi x j x_{j} xj均有 x k x_{k} xk密度可达,则称 x i x_{i} xi x j x_{j} xj密度相连。

  基于这些概念,DBSCAN算法将“簇”定义为:由密度可达关系导出的最大的密度相连的样本集合。DBSCAN算法的优点主要有以下几点:

  • 与k-means算法相比,不需要事先确定簇数 k k k;
  • 与k-means算法相比,DBSCAN可以发现任意形状的簇;
  • DBSCAN算法能够识别出噪声点,对异常值点不敏感;

  DBSCAN算法的缺点主要有以下几点:

  • 算法聚类效果依赖于距离公式的选取。实际应用中常用欧式距离,对于高维数据,存在“维数灾难”;
  • 当数据量较大时,需要较大的I/O和内存开销;
  • 当空间聚类的密度不均匀、聚类间距差相差很大时,聚类质量较差,因为这种情况下参数 M i n P t s MinPts MinPts ϵ \epsilon ϵ选取困难;
2.3 层次聚类

  层次聚类(Hierarchical clustering)试图在不同层次对数据集进行划分,从而形成树形的聚类结构。数据集的划分可采用“自底向上”的聚合策略,也可以采用“自顶向下”的分拆策略。
  AGNES算法是一种采用自底向上聚合策略的层次聚类算法,该算法先将数据集中的每个样本看作一个初始聚类簇,然后在算法运行的每一步中找出距离最近的两个聚类簇进行合并,该过程不断重复,直至达到预设的聚类簇个数。该算法中可以使用三种公式来计算聚类簇 C i C_{i} Ci C j C_{j} Cj之间的距离,其公式如下: d m i n ( C i , C j ) = min ⁡ x ∈ C i , z ∈ C j d i s t ( x , z ) d_{min}(C_{i},C_{j})=\min\limits_{x\in C_{i},z\in C_{j}}dist(x,z) dmin(Ci,Cj)=xCi,zCjmindist(x,z) d m a x ( C i , C j ) = max ⁡ x ∈ C i , z ∈ C j d i s t ( x , z ) d_{max}(C_{i},C_{j})=\max\limits_{x\in C_{i},z\in C_{j}}dist(x,z) dmax(Ci,Cj)=xCi,zCjmaxdist(x,z) d a v g ( C i , C j ) = 1 ∣ C i ∣ ∣ C j ∣ ∑ x ∈ C i ∑ z ∈ C j d i s t ( x , z ) d_{avg}(C_{i},C_{j})=\frac{1}{|C_{i}||C_{j}|}\sum_{x\in C_{i}}\sum_{z\in C_{j}}dist(x,z) davg(Ci,Cj)=CiCj1xCizCjdist(x,z)

3 效果评价指标

  依据是否需要真实的类别标签,可以将聚类算法的效果评价指标分为两类:内部评价指标(不需要真实的类别信息)和外部评价指标(需要真实的类别信息)。

3.1 内部评价指标

  给定数据集 D = { x 1 , x 2 , … , x m } D=\{x_{1},x_{2},\dots,x_{m}\} D={x1,x2,,xm},其聚类操作后形成的簇为 C = { C 1 , C 2 , … , C k } C=\{C_{1},C_{2},\dots,C_{k}\} C={C1,C2,,Ck}。内部评价指标主要有:轮廓系数和CH指标。

  • 轮廓系数(Silhouette Coefficient):对于数据集 D D D中的每个样本点 x i x_{i} xi,其轮廓系数的计算公式为: s ( i ) = b ( i ) − a ( i ) m a x ( b ( i ) , a ( i ) ) s(i)=\frac{b(i)-a(i)}{max(b(i),a(i))} s(i)=max(b(i),a(i))b(i)a(i)其中 a ( i ) a(i) a(i)为样本 x i x_{i} xi与其所在簇内的其他样本的平均距离; b ( i ) b(i) b(i)为样本 x i x_{i} xi与其他簇内的样本的平均距离。样本的总的轮廓系数为所有样本点轮廓系数的平均值 S = 1 m ∑ i = 1 m s ( i ) S=\frac{1}{m}\sum_{i=1}^{m}s(i) S=m1i=1ms(i)轮廓系数 S ∈ [ − 1 , 1 ] S\in[-1,1] S[1,1],值越大聚类效果越好。
  • CH(Calinski-Harabaz)指标:通过计算簇中各样本点 x i x_{i} xi与簇中心 c i c_{i} ci的距离平方和来度量类内的紧密度,各簇中心点 c i c_{i} ci与数据集中心点 c c c的距离平方和来度量数据集的分离度。CH指标由分离度与紧密度的比值得到。CH越大代表着类自身越紧密,类与类之间越分散,聚类效果更好。其计算公式如下: C H = ( ∑ i = 1 k ∥ c i − c ∥ 2 ) / ( k − 1 ) ( ∑ i = 1 k ∑ x ∈ C i ∥ x − c i ∥ 2 ) / ( m − k ) CH=\frac{(\sum_{i=1}^{k}\|c_{i}-c\|^{2})/(k-1)}{(\sum_{i=1}^{k}\sum_{x\in C_{i}}\|x-c_{i}\|^{2})/(m-k)} CH=(i=1kxCixci2)/(mk)(i=1kcic2)/(k1)
3.2 外部评价指标

  给定数据集 D = { x 1 , x 2 , … , x m } D=\{x_{1},x_{2},\dots,x_{m}\} D={x1,x2,,xm},其聚类算法形成的簇集合为 C = { C 1 , C 2 , … , C k } C=\{C_{1},C_{2},\dots,C_{k}\} C={C1,C2,,Ck},该数据集 D D D对应的真实簇集合为 Ω = { Ω 1 , Ω 2 , … , Ω j } \Omega=\{\Omega_{1},\Omega_{2},\dots,\Omega_{j}\} Ω={Ω1,Ω2,,Ωj}
  以下几个指标都是建立在条件熵基础上的,具体包括互信息、规范化互信息、同质性及完整性评分等。

  • 归一化互信息(NMI):其计算公式如下: N M I ( Ω , C ) = I ( Ω ; C ) ( H ( Ω ) + H ( C ) ) / 2 NMI(\Omega,C)=\frac{I(\Omega;C)}{(H(\Omega)+H(C))/2} NMI(Ω,C)=(H(Ω)+H(C))/2I(Ω;C)其中
    H ( C ) = − ∑ i = 1 k ∣ C i ∣ m l o g ∣ C i ∣ m H(C)=-\sum_{i=1}^{k}\frac{|C_{i}|}{m}log\frac{|C_{i}|}{m} H(C)=i=1kmCilogmCi I ( Ω ; C ) = ∑ i = 1 k ∑ p = 1 j ∣ Ω p ⋂ C i ∣ m l o g m ∣ Ω p ⋂ C i ∣ ∣ Ω p ∣ ∣ C i ∣ I(\Omega;C)=\sum_{i=1}^{k}\sum_{p=1}^{j}\frac{|\Omega_{p}\bigcap C_{i}|}{m}log\frac{m|\Omega_{p}\bigcap C_{i}|}{|\Omega_{p}||C_{i}|} I(Ω;C)=i=1kp=1jmΩpCilogΩpCimΩpCi N M I ∈ [ 0 , 1 ] NMI\in [0,1] NMI[0,1],值越大聚类效果越好。
  • 同质性(Homogeneity)分数:如果一个簇 C i C_{i} Ci中的所有成员都来自同一个类 Ω p \Omega_{p} Ωp中,则称满足同质性。其评分计算公式如下: h = { 1 i f H ( Ω , C ) = 0 1 − H ( Ω ∣ C ) H ( Ω ) e l s e h=\begin{cases} 1& if H(\Omega,C)=0\\ 1-\frac{H(\Omega|C)}{H(\Omega)} & else \end{cases} h={11H(Ω)H(ΩC)ifH(Ω,C)=0else
  • 完整性(Completeness)分数:如果一个类 Ω p \Omega_{p} Ωp中的所有样本都被分配到了同一个簇 C i C_{i} Ci中,则称满足完整性。其计算公式如下: c = { 1 H ( C , Ω ) = 0 1 − H ( C ∣ Ω ) H ( C ) e l s e c=\begin{cases} 1 & H(C,\Omega)=0\\ 1-\frac{H(C|\Omega)}{H(C)} & else \end{cases} c={11H(C)H(CΩ)H(C,Ω)=0else
  • v_score:该值为同质性和完整性评分的调和平均值。其计算公式如下: v = ( 1 + β ) × H o m o g e n e i t y × C o m p l e t e n e s s β × H o m o g e n e i t y + C o m p l e t e n e s s v=\frac{(1+\beta)\times Homogeneity\times Completeness}{\beta\times Homogeneity+Completeness} v=β×Homogeneity+Completeness(1+β)×Homogeneity×Completeness

  对于数据集 D D D中的任意两个样本,依据其真实类别标记及聚类结果对其进行分类,分别统计以下几种情况的样本对数:

TP:实际在同一个簇中的两个样本预测也在同一个簇中;
FP:实际不在同一个簇中的两个样本被预测到了同一个簇中;
TN:实际不在同一个簇中的两个样本也没有被预测到同一个簇中;
FN:实际在同一个簇中的两个样本被预测到了不同的簇中;

显然, T P + F P + T N + F N = m ( m − 1 ) / 2 TP+FP+TN+FN=m(m-1)/2 TP+FP+TN+FN=m(m1)/2。并据此延伸出了以下几个评价指标:

  • FMI(Fowlkes_Mallow Index)指数: F M I = T P ( T P + F P ) + ( T P + F N ) FMI=\frac{TP}{\sqrt{(TP+FP)+(TP+FN)}} FMI=(TP+FP)+(TP+FN) TP
  • RI(兰德指数): 该指数计算正确决策的比例,其计算公式如下: R I = T P + T N m ( m − 1 ) / 2 RI=\frac{TP+TN}{m(m-1)/2} RI=m(m1)/2TP+TN
  • ARI(调整的兰德指数):因为RI不是一个接近0的常数,所以引进ARI。其计算公式如下: A R I = R I − E x p e c t e d R I m a x ( R I ) − E x p e c t e d R I ARI=\frac{RI-ExpectedRI}{max(RI)-ExpectedRI} ARI=max(RI)ExpectedRIRIExpectedRI A R I ∈ [ − 1 , 1 ] ARI\in[-1,1] ARI[1,1]值越大聚类效果越好。

  以上这些指标,sklearn.metrics中都已经提供了函数接口,可以直接使用。

4 案例
import numpy as np
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import matplotlib as mpl
import warnings
warnings.filterwarnings('ignore')
from sklearn.metrics import silhouette_score
from sklearn.metrics import normalized_mutual_info_score
from sklearn.metrics import adjusted_rand_score


data,y=make_blobs(400,n_features=2,centers=4,random_state=2)
data2,y2=make_blobs(400,n_features=2,centers=4,cluster_std=[1,0.5,2,2.5],
                    random_state=2)
std=StandardScaler()
data=std.fit_transform(data)
data2=std.fit_transform(data2)

data3=data.copy()
data3[:,1]=data3[:,1]*5+100

#1.Kmeans聚类
km=KMeans(n_clusters=4)
km.fit(data)
label_pred=km.predict(data)
sil_score=silhouette_score(data,label_pred)
NMI=normalized_mutual_info_score(y,label_pred)
ARI=adjusted_rand_score(y, label_pred)

#2.DBSCAN聚类
db=DBSCAN(eps=0.5,min_samples=2).fit(data2)
label_pred2=db.fit_predict(data2)
sil_score2=silhouette_score(data2,label_pred2)
NMI2=normalized_mutual_info_score(y2,label_pred2)
ARI2=adjusted_rand_score(y2, label_pred2)

#3.验证如果两个特征的取值范围差别很大时,和第1部分结合,可以观察归一化对聚类结果的影响
km.fit(data3)
label_pred3=km.predict(data3)
sil_score3=silhouette_score(data3,label_pred3)
NMI3=normalized_mutual_info_score(y,label_pred3)
ARI3=adjusted_rand_score(y, label_pred3)

print("KMeans在数据集data(归一化之后)上的聚类效:轮廓系数={:.3f},NMI={:.3f},ARI={:.3f}".\
      format(sil_score,NMI,ARI))
print("DBSCAN在数据集data2上的聚类效:轮廓系数={:.3f},NMI={:.3f},ARI={:.3f}".\
      format(sil_score2,NMI2,ARI2))
print("KMeans在数据集data3(归一化之前)上的聚类效:轮廓系数={:.3f},NMI={:.3f},ARI={:.3f}".\
      format(sil_score3,NMI3,ARI3))

#画图
mpl.rcParams['font.sans-serif']=['Arial Unicode MS']
plt.figure(figsize=(9,10),facecolor='w')
x1_min,x2_min=np.min(data,axis=0)
x1_max,x2_max=np.max(data,axis=0)
plt.subplot(321)
plt.scatter(data[:,0],data[:,1],c=y,s=30,edgecolors='none')
plt.title('真实类别')
plt.xlim(x1_min,x1_max)
plt.ylim(x2_min,x2_max)
plt.grid(True)

plt.subplot(322)
plt.scatter(data[:,0],data[:,1],c=label_pred,s=30,edgecolors='none')
plt.title('K-Means聚类结果')
plt.xlim(x1_min,x1_max)
plt.ylim(x2_min,x2_max)
plt.grid(True)

x1_min,x2_min=np.min(data2,axis=0)
x1_max,x2_max=np.max(data2,axis=0)
plt.subplot(323)
plt.scatter(data2[:,0],data2[:,1],c=y2,s=30,edgecolors='none')
plt.title('真实类别')
plt.xlim(x1_min,x1_max)
plt.ylim(x2_min,x2_max)
plt.grid(True)

plt.subplot(324)
plt.scatter(data2[:,0],data2[:,1],c=label_pred2,s=30,edgecolors='none')
plt.title('DBSCAN聚类结果')
plt.xlim(x1_min,x1_max)
plt.ylim(x2_min,x2_max)
plt.grid(True)

x1_min,x2_min=np.min(data3,axis=0)
x1_max,x2_max=np.max(data3,axis=0)
plt.subplot(325)
plt.scatter(data3[:,0],data3[:,1],c=y,s=30,edgecolors='none')
plt.title('真实类别')
plt.xlim(x1_min,x1_max)
plt.ylim(x2_min,x2_max)
plt.grid(True)

plt.subplot(326)
plt.scatter(data3[:,0],data3[:,1],c=label_pred3,s=30,edgecolors='none')
plt.title('归一化之前的k-means聚类结果')
plt.xlim(x1_min,x1_max)
plt.ylim(x2_min,x2_max)
plt.grid(True)

plt.tight_layout(2)
plt.suptitle('结果对比')
plt.subplots_adjust(top=0.92)
plt.show()

(1).聚类效果如下:

KMeans在数据集data(归一化之后)上的聚类效:轮廓系数=0.603,NMI=0.913,ARI=0.918
DBSCAN在数据集data2上的聚类效:轮廓系数=0.090,NMI=0.029,ARI=0.000
KMeans在数据集data3(归一化之前)上的聚类效:轮廓系数=0.630,NMI=0.862,ARI=0.862

(2).效果展示
在这里插入图片描述

参考资料
  1. 《机器学习》
  2. https://blog.csdn.net/gaobellen/article/details/45024663
  3. https://zhuanlan.zhihu.com/p/53840697
  4. https://www.cnblogs.com/xingnie/p/10334572.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值