text.html 12.0 KB
Newer Older
ToTensor's avatar
ToTensor 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
 
<p class="content"><span class="bold">聚类</span>是最常见的无监督学习算法。人有归纳和总结的能力,机器也有。聚类就是让机器把数据集中的样本按照特征的性质分组,这个过程中没有标签的存在。</p> 
<p class="content">聚类和监督学习中的分类问题有些类似,其主要区别在于:传统分类问题“<span class="bold">概念化在前</span>”。也就是说,在对猫狗图像分类之前,我们心里面已经对猫、狗图像形成了概念。这些概念指导着我们为训练集设定好标签。机器首先是学习概念,然后才能够做分类、做判断。分类的结果,还要接受标签,也就是已有概念的检验。</p> 
<p class="content">而聚类不同,虽然本质上也是“分类”,但是“<span class="bold">概念化在后</span>”或者“<span class="bold">不概念化</span>”,在给一堆数据分组时,没有任何此类、彼类的概念。譬如,漫天繁星,彼此之间并没有关联,也没有星座的概念,当人们看到它们,是先根据星星在广袤苍穹中的位置将其一组一组地“聚集”起来,然后才逐渐形成星座的概念。人们说,这一组星星是“大熊座”,那一组星星是“北斗七星”。这个先根据特征进行分组,之后再概念化的过程就是聚类。</p> 
<p class="content">聚类也有好几种算法,<span class="italic">K</span>均值(K-means)是其中最常用的一种。</p> 
<h3 class="thirdTitle" id="bw253"><a >10.1.1 K均值算法</a></h3> 
<p class="content">K均值算法是最容易理解的无监督学习算法。算法简单,速度也不差,但需要人工指定<span class="italic">K</span>值,也就是分成几个聚类。</p> 
<p class="content">具体算法流程如下。</p> 
<p class="content">(1)首先确定<span class="italic">K</span>的数值,比如5个聚类,也叫5个簇。</p> 
<p class="content">(2)然后在一大堆数据中随机挑选<span class="italic">K</span>个数据点,作为簇的<span class="bold">质心</span>(centroid)。这些随机质心当然不完美,别着急,它们会慢慢变得完美。</p> 
<p class="content">(3)遍历集合中每一个数据点,计算它们与每一个质心的距离(比如欧氏距离)。数据点离哪个质心近,就属于哪一类。此时初始的<span class="italic">K</span>个类别开始形成。</p> 
<p class="content">(4)这时每一个质心中都聚集了很多数据点,于是质心说,你们来了,我就要“退役”了(这个是伟大的“禅让制度”啊!),选一个新的质心吧。然后计算出每一类中最靠近中心的点,作为新的质心。此时新的质心会比原来随机选的靠谱一些(等会儿用图展示质心的移动)。</p> 
<p class="content">(5)重新进行步骤(3),计算所有数据点和新的质心的距离,在新的质心周围形成新的簇分配(“吃瓜群众”随风飘摇,离谁近就跟谁)。</p> 
<p class="content">(6)重新进行步骤(4),继续选择更好的质心(一代一代地“禅让”下去)。</p> 
<p class="content">(7)一直重复进行步骤(5)和(6),不断更新簇中的数据点,不断找到新的质心,直至收敛。</p> 
<p class="content_105">小冰说:“不好意思,这里的收敛是什么意思?”</p> 
<p class="content_105">咖哥说:“就是质心的移动变化后来很小很小了,已经在一个阈值之下,或者固定不变了,算法就可以停止了。这个无监督学习算法是不是超好理解?算法真的是很奇妙的东西,有点像变魔术。没有告诉你们其中奥秘之前,你们觉得怎么可能做得到呢?一旦揭秘之后,会有一种恍然大悟的感觉。”</p> 
<p class="content"> “哦,原来是这样!”小冰点头说道</p> 
<p class="content">通过下面这个图,可以看到聚类中质心的移动和簇形成的过程。</p> 
<div class="pic"> 
 <img src="http://csdn-ebook-resources.oss-cn-beijing.aliyuncs.com/images/b88b00f6ad14402ea66695d6809614da/figure-0309-0401.jpg"> 
 <p class="imgtitle">聚类中质心的移动和簇形成的过程</p> 
</div> 
<h3 class="thirdTitle" id="bw254"><a >10.1.2 K值的选取:手肘法</a></h3> 
<p class="content">聚类问题的关键在于<span class="italic">K</span>值的选取。也就是说,把一批数据划分为多少个簇是最合理的呢?当数据特征维度较少、数据分布较为分散时,可通过数据可视化的方法来人工确定<span class="italic">K</span>值。但当数据特征维度较多、数据分布较为混乱时,数据可视化帮助不大。</p> 
<p class="content">当然,也可以经过多次实验,逐步调整,使簇的数目逐渐达到最优,以符合数据集的特点。</p> 
<p class="content">这里我介绍一种直观的手肘法(elbow method)进行簇的数量的确定。手肘法是基于对聚类效果的一个度量指标来实现的,这个指标也可以视为一种损失。在<span class="italic">K</span>值很小的时候,整体损失很大,而随着<span class="italic">K</span>值的增大,损失函数的值会在逐渐收敛之前出现一个拐点。此时的<span class="italic">K</span>值就是比较好的值。</p> 
<p class="content">大家看下面的图,损失随着簇的个数而收敛的曲线有点像只手臂,最佳<span class="italic">K</span>值的点像是手肘,因此取名为手肘法。</p> 
<div class="pic"> 
 <img src="http://csdn-ebook-resources.oss-cn-beijing.aliyuncs.com/images/b88b00f6ad14402ea66695d6809614da/figure-0310-0402.jpg"> 
 <p class="imgtitle">手肘法—确定最佳K值</p> 
</div> 
<p class="content">同学们认真地观察着图中被称为“手臂”的曲线,并没觉得特别像。</p> 
<h3 class="thirdTitle" id="bw255"><a >10.1.3 用聚类辅助理解营销数据</a></h3> 
<p class="content_105">咖哥忽然发现小冰的手已经举了好久了。咖哥说:“小冰,有什么问题,说吧。”</p> 
<p class="content_105">小冰说:“咖哥啊,这个聚类问题太适合帮我给客户分组了!这样我才好对隶属于不同‘簇’的客户进行有针对性的营销啊!”</p> 
<p class="content_105">咖哥说:“完全可以啊。看一下你的数据。”</p> 
<p class="content_101">1.问题定义:为客户分组</p> 
<p class="content">小冰打开她收集的数据集,如下图所示。小冰攒到了200个客户的信息,主要信息有以下4个方面。</p> 
<div class="pic"> 
 <img src="http://csdn-ebook-resources.oss-cn-beijing.aliyuncs.com/images/b88b00f6ad14402ea66695d6809614da/figure-0310-0403.jpg"> 
 <p class="imgtitle">小冰收集的客户数据(未显示完)</p> 
</div> 
<p class="content">■Gender:性别。</p> 
<p class="content">■Age:年龄。</p> 
<p class="content">■Income年收入(这可是很不好收集的信息啊!)。</p> 
<p class="content">■Spending Score:消费分数。这是客户们在我的网店里面花费多少、购物频率的综合指标。这是我从后台数据中整理出来的,已经归一化成一个0~1的分数。</p> 
<p class="content">那么这个案例的目标如下。</p> 
<p class="content">(1)通过这个数据集,理解<span class="italic">K</span>均值算法的基本实现流程。</p> 
<p class="content">(2)通过<span class="italic">K</span>均值算法,给小冰的客户分组,让小冰了解每类客户消费能力的差别。</p> 
<p class="content_101">2.数据读入</p> 
<p class="content">参考第10课源码包中的“教学用例1客户聚类”目录下的数据文件,创建Customer Cluster数据集,或在Kaggel中根据关键字Customer Cluster搜索该数据集。这里只选择两个特征,即年收入和消费分数,并对进行聚类。</p> 
<p class="content">示例代码如下:</p> 
<div class="content_106"> 
 <p class="content_105">import numpy as np # 导入Num Py库</p> 
 <p class="content_105">import pandas as pd # 导入pandas库</p> 
 <p class="content_105">dataset = pd.read_csv('../input/customer-cluster/Customers Cluster.csv')</p> 
 <p class="content_105">dataset.head() # 显示一些数据</p> 
 <p class="content_105"># 只针对两个特征进行聚类, 以方便二维展示</p> 
 <p class="content_105">X = dataset.iloc[:, [3, 4]].values</p> 
</div> 
<p class="content_101">3.聚类的拟合</p> 
<p class="content">下面尝试用不同的K值进行聚类的拟合:</p> 
<div class="content_106"> 
 <p class="content_105">from sklearn.cluster import KMeans # 导入聚类模型</p> 
 <p class="content_105">cost=[] # 初始化损失(距离)值</p> 
 <p class="content_105">for i in range(1, 11): # 尝试不同的K值</p> 
 <p class="content_121">kmeans = KMeans(n_clusters= i, init='k-means++', random_state=0)</p> 
 <p class="content_121">kmeans.fit(X)</p> 
 <p class="content_121">cost.append(kmeans.inertia_) #inertia_是我们选择的方法, 其作用相当于损失函数</p> 
</div> 
<p class="content_101">4.绘制手肘图</p> 
<p class="content">下面绘制手肘图:</p> 
<div class="content_106"> 
 <p class="content_105">import matplotlib.pyplot as plt # 导入Matplotlib库</p> 
 <p class="content_105">import seaborn as sns # 导入Seaborn库</p> 
 <p class="content_105"># 绘制手肘图找到最佳K值</p> 
 <p class="content_105">plt.plot(range(1, 11), cost)</p> 
 <p class="content_105">plt.title('The Elbow Method')#手肘法</p> 
 <p class="content_105">plt.xlabel('No of clusters')#聚类的个数</p> 
 <p class="content_105">plt.ylabel('Cost')#成本</p> 
 <p class="content_105">plt.show()</p> 
</div> 
<p class="content">生成的手肘图如下图所示。</p> 
<div class="pic"> 
 <img src="http://csdn-ebook-resources.oss-cn-beijing.aliyuncs.com/images/b88b00f6ad14402ea66695d6809614da/figure-0311-0404.jpg"> 
 <p class="imgtitle">生成的手肘图</p> 
</div> 
<p class="content">从手肘图上判断,肘部数字大概是3或4,我们选择4作为聚类个数:</p> 
<div class="content_106"> 
 <p class="content_105">kmeansmodel = KMeans(n_clusters= 4, init='k-means++') # 选择4作为聚类个数</p> 
 <p class="content_105">y_kmeans= kmeansmodel.fit_predict(X) # 进行聚类的拟合和分类</p> 
</div> 
<p class="content_101">5.把分好的聚类可视化</p> 
<p class="content">下面把分好的聚类可视化:</p> 
<div class="content_106"> 
 <p class="content_105"># 下面把分好的聚类可视化</p> 
 <p class="content_105">plt.scatter(X[y_kmeans == 0, 0], X[y_kmeans == 0, 1],</p> 
 <p class="content_111">s = 100, c = 'cyan', label = 'Cluster 1')#聚类1</p> 
 <p class="content_105">plt.scatter(X[y_kmeans == 1, 0], X[y_kmeans == 1, 1],</p> 
 <p class="content_111">s = 100, c = 'blue', label = 'Cluster 2')#聚类2</p> 
 <p class="content_105">plt.scatter(X[y_kmeans == 2, 0], X[y_kmeans == 2, 1],</p> 
 <p class="content_111">s = 100, c = 'green', label = 'Cluster 3')#聚类3</p> 
 <p class="content_105">plt.scatter(X[y_kmeans == 3, 0], X[y_kmeans == 3, 1],</p> 
 <p class="content_111">s = 100, c = 'red', label = 'Cluster 4')#聚类4</p> 
 <p class="content_105">plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1],</p> 
 <p class="content_111">s = 200, c = 'yellow', label = 'Centroids')#质心</p> 
 <p class="content_105">plt.title('Clusters of customers')#客户形成的聚类</p> 
 <p class="content_105">plt.xlabel('Income')#年收入</p> 
 <p class="content_105">plt.ylabel('Spending Score')#消费分数</p> 
 <p class="content_105">plt.legend()</p> 
 <p class="content_105">plt.show()</p> 
</div> 
<p class="content">客户形成的聚类如下图所示。</p> 
<div class="pic"> 
 <img src="http://csdn-ebook-resources.oss-cn-beijing.aliyuncs.com/images/b88b00f6ad14402ea66695d6809614da/figure-0312-0405.jpg"> 
 <p class="imgtitle">客户形成的聚类</p> 
 <p class="imgtitle">(请见340页彩色版插图)</p> 
</div> 
<p class="content">这个客户的聚类问题就解决了。其中,黄色高亮的大点是聚类的质心,可以看到算法中的质心并不止一个。</p>