目录

1、KMeans算法

(1)KMeans算法的原理介绍

(2)KMeans算法的代码实现

(3)案例 - 银行客户分群模型

1、背景

2、读取银行客户数据

3、模型搭建与使用

2、DBSCAN算法

(1)DBSCAN算法的原理介绍

(2)DBSCAN算法的代码实现

(3)KMeans VS DBSCAN

3、案例 - 新闻聚类分群模型

(1)背景

(2)文本数据的读取与处理

 1、读取数据

2、中文分词

3、文本向量化基础:建立词频矩阵

4、文本向量化实战:构造特征变量

(3)模型搭建与使用

1、通过KMeans算法进行聚类分群

2、通过DBSCAN算法进行聚类分群


1、KMeans算法

(1)KMeans算法的原理介绍

       KMeans算法的K代表类别数量,Means代表每个类别内样本的均值,所以KMeans算法又称为K-均值算法。KMeans算法以距离作为样本间相似度的度量标准,将距离相近的样本分配至同一个类别。样本间距离的计算方式可以是欧氏距离,曼哈顿距离,余弦相似度等,KMeans算法通常采用欧氏距离来度量各样本间的距离

       KMeans算法的核心思想是:对每个样本点计算离各个中心点的距离,并将该样本点分配给最近中心点代表的类别,一次迭代完成后,根据聚类结果更新每个类别的中心点,然后重复之前操作再次迭代,直到前后两次分类结果没有差别。下面我们以一个简单案例对KMeans算法的原理进行解释,该案例目的是将样本点聚成3个类别(K=3

(2)KMeans算法的代码实现

       使用一些简单的二维数据来说明如何在Python当中实现KMeans算法

import numpy as np
data = np.array([[3, 2], [4, 1], [3, 6], [4, 7], [3, 9], [6, 8], [6, 6], [7, 7]])
import matplotlib.pyplot as plt
plt.scatter(data[:, 0], data[:, 1], c="red", marker='o', label='samples')  
plt.legend()  
plt.show()

       data[:,0]表示的则是X列的数,同理data[:, 1]表示的则是Y列的数。此外散点图函数scatter()中的参数c表示颜色,maker表示形状,label则表示数据标签,散点图如下所示:

       调用Python已经开发好的相关库来进行KMeans的聚类运算,代码如下

from sklearn.cluster import KMeans
kms = KMeans(n_clusters=2)
kms.fit(data)

       使用散点图展示KMeans算法的聚类结果:

plt.scatter(data[label == 0][:, 0], data[label == 0][:, 1], c="red", marker='o', label='class0') 
plt.scatter(data[label == 1][:, 0], data[label == 1][:, 1], c="green", marker='*', label='class1') 
plt.legend() 

       使用散点图展示KMeans算法的聚类结果:

       我们将K值设为3

kms_3 = KMeans(n_clusters=3)
kms_3.fit(data)
label_3 = kms_3.labels_
print(label_3)
plt.scatter(data[label_3 == 0][:, 0], data[label_3 == 0][:, 1], c="red", marker='o', label='class0')  
plt.scatter(data[label_3 == 1][:, 0], data[label_3 == 1][:, 1], c="green", marker='*', label='class1') 
plt.scatter(data[label_3 == 2][:, 0], data[label_3 == 2][:, 1], c="blue", marker='+', label='class2') 
plt.legend()  

       散点图如下所示:

(3)案例 - 银行客户分群模型

1、背景

       银行通常拥有海量的客户,对于不同的客户,银行需要进行不同的营销与工作开展策略,例如对于高收入且风险承受能力强的客户,可以进行重点挖掘业务机会,例如可以给他推销一些收益率高但周期相对较长的理财产品;而对于低收入且风险承受能力较弱的客户,则需要制定不同的营销与工作策略。因此对于银行来说,通常需要将客户进行分群处理,对于不同分群的客户进行不同的处理。

2、读取银行客户数据

       读取数据和创建散点图代码如下:

import pandas as pd 
data = pd.read_excel('客户信息.xlsx')
data.head()
import matplotlib.pyplot as plt
plt.scatter(data.iloc[:, 0], data.iloc[:, 1], c="green", marker='*') 
plt.xlabel('age') 
plt.ylabel('salary')  
plt.show()

       散点图如下所示:

3、模型搭建与使用
from sklearn.cluster import KMeans
kms = KMeans(n_clusters=3, random_state=123)
kms.fit(data)
label = kms.labels_
label = kms.fit_predict(data)
plt.scatter(data[label == 0].iloc[:, 0], data[label == 0].iloc[:, 1], c="red", marker='o', label='class0')  
plt.scatter(data[label == 1].iloc[:, 0], data[label == 1].iloc[:, 1], c="green", marker='*', label='class1')  
plt.scatter(data[label == 2].iloc[:, 0], data[label == 2].iloc[:, 1], c="blue", marker='+', label='class2')  
plt.xlabel('age')
plt.ylabel('salary')  
plt.legend() 

2、DBSCAN算法

       DBSCAN (Density-Based Spatial Clustering of Applications with Noise)是一种以密度为基础的空间聚类算法,可以用密度的概念剔除不属于任意类别的噪声点。该算法将簇定义为密度相连的点的最大集合,将具有足够密度的区域划分为簇,并可以发现任意形状的簇。

(1)DBSCAN算法的原理介绍

       下面我们以一个简单案例对DBSCAN算法的原理进行解释,我们设定画圆半径为1,圆内最小样本点数为3

(2)DBSCAN算法的代码实现

       演示完DBSCAN算法的原理之后,我们先看两张KMeansDBSCAN聚类的对比图片:

      创建KMeans与DBSCAN散点图,首先让我们创建原始的散点图:

import pandas as pd
data = pd.read_excel('演示数据.xlsx')
data.head()
import matplotlib.pyplot as plt
plt.scatter(data.iloc[:, 0], data.iloc[:, 1], c="green", marker='*')  
plt.xlabel('x')
plt.ylabel('y') 
plt.show()

       原始的散点图:

       创建DBSCAN散点图

from sklearn.cluster import DBSCAN
dbs = DBSCAN()
dbs.fit(data)
label_dbs = dbs.labels_
plt.scatter(data[label_dbs == 0].iloc[:, 0], data[label_dbs == 0].iloc[:, 1], c="red", marker='o', label='class0')  
plt.scatter(data[label_dbs == 1].iloc[:, 0], data[label_dbs == 1].iloc[:, 1], c="green", marker='*', label='class1') 
plt.xlabel('x')  
plt.ylabel('y')  
plt.legend()  

(3)KMeans VS DBSCAN

       创建KMeans散点图:

from sklearn.cluster import KMeans
KMs = KMeans(n_clusters=2)
KMs.fit(data)
label_kms = KMs.labels_
10]
plt.scatter(data[label_kms == 0].iloc[:, 0], data[label_kms == 0].iloc[:, 1], c="red", marker='o', label='class0')  
plt.scatter(data[label_kms == 1].iloc[:, 0], data[label_kms == 1].iloc[:, 1], c="green", marker='*', label='class1')  
plt.xlabel('x')  
plt.ylabel('y')  
plt.legend()  

       对于形状类似同心圆的数据,KMeans算法聚类效果较差,只能机械地将数据分为左右两部分,而无法以外圆内圆的方式进行区分。

3、案例 - 新闻聚类分群模型

(1)背景

       新闻种类繁复多样,可以分为军事,政治,娱乐,财经,体育,科技,历史等等题材,我们需要将每条新闻划分成合适的类别,匹配到正确的版面,以便读者阅读,因此新闻的聚类分群显得十分重要。

(2)文本数据的读取与处理

 1、读取数据
import pandas as pd
df = pd.read_excel('新闻.xlsx')
df.head()

       df.head()用来展示前五行数据。运行结果如下图所示:

2、中文分词

       本节中的新闻标题文本,而Python是不能直接处理这种文本数据的,我们需要将其进行数值转换。需要利用到的两个核心技术为:中文分词文本向量化。中文分词:所谓中文分词就是将一句话拆分成一些词语,例如“我爱北京天安门”就可以拆分成“我”、“爱”、“北京”、“天安门”。中文分词后就可以进行文本向量化,搭建词频矩阵从而将文字转为数字了。Python有专门处理中文分词的库:jieba库,这里主要讲解下jieba库的核心知识点。

       首先通过如下代码简单显示下jieba库在中文分词方面的使用

import jieba
word = jieba.cut('我爱北京天安门')
for i in word:
    print(i)

       打印分词后的结果如下所示:

我
爱
北京
天安门

       这里先来将第一条新闻标题进行分词,代码如下:

import jieba
word = jieba.cut(df.iloc[0]['标题'])
result = ' '.join(word)
print(result)

       结果如下所示:

信托公司 2019 年 上半年 经营 业绩 概览

       通过for循环遍历整张表格,将所有的新闻的标题都进行分词,完整代码如下

import jieba
words = []
for i, row in df.iterrows():
    word = jieba.cut(row['标题'])
    result = ' '.join(word) 
    words.append(result)
words = []
for i, row in df.iterrows():
    words.append(' '.join(jieba.cut(row['标题'])))

       因为words涵盖了所有新闻标题的分词结果,内容较多,这里通过print(words[0:3])来查看前3条评论的分词结果,如下图所示,每个分词由空格隔开。

['信托公司 2019 年 上半年 经营 业绩 概览',
 '首单 信托 型 企业 ABS 获批',
 '华能 贵 诚信 托孙磊 : 金融 科技 助力 打造 开放 信托 生态']

       pandas库中iterrows()函数,它用来遍历DataFrame的每一行,演示代码如下

for i, row in df.iterrows():
    print(i)
    print(row)
3、文本向量化基础:建立词频矩阵

       下面就需要把这些文字类型的数据转换成数值类型的数据,从而方便构造特征变量,方便模型的训练。在Python中,有一个文本向量化函数CountVectorizer()函数,它可以将文本方便地转换成数值,演示代码如下

from sklearn.feature_extraction.text import CountVectorizer
test = ['金融 科技 厉害', '华能 信托 厉害']
vect = CountVectorizer()
X = vect.fit_transform(test)
X = X.toarray()

       这5个不同的词便构成了这两句话的词袋,CountVectorizer()函数会自动将词袋中的词语进行编号,这里可以通过以下代码来进行验证:

words_bag = vect.vocabulary_
print(words_bag)

4、文本向量化实战:构造特征变量

       通过CountVectorizer()文本向量化函数将之前所有分词后的新闻标题进行文本向量化了,代码如下:

from sklearn.feature_extraction.text import CountVectorizer
vect = CountVectorizer()
X = vect.fit_transform(words)
X = X.toarray()

       我们可以vect.vocabulary_代码查看其文本向量化后的词袋:

words_bag = vect.vocabulary_
print(words_bag)

       如果只想看到词,而不想看到编号,可以通过get_feature_names()函数实现,代码如下

words_bag2 = vect.get_feature_names() 
print(words_bag2) 

       获得结果如下,此时便只展示词而不展示词对应的编号了,并且词已经按编号顺序排好了。

       我们将文本向量化的代码整合并通过pandas库来更加好的查看整个词频矩阵,代码如下:

from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
vect = CountVectorizer()
X = vect.fit_transform(words) 
X = X.toarray()
words_bag2 = vect.get_feature_names()  
df = pd.DataFrame(X, columns=words_bag2)
df.head()

(3)模型搭建与使用

1、通过KMeans算法进行聚类分群

       我们提到过我们是根据10个关键词爬取的新闻,那么现在就来利用KMeans算法来搭建模型进行分群聚类,看看它是否能准确地将来自10个不同板块的数据分门别类:

from sklearn.cluster import KMeans
kms = KMeans(n_clusters=10, random_state=123)
k_data = kms.fit_predict(df)

       通过代码"print(k_data)"KMeans算法聚类后的结果展示出来,如下图所示:

       其中每一个数字标签就表示一个分类,可以看到通过KMeans算法,所有新闻被分成了10[0:9]我们打印标签为1的数据来查看该分类中对应的新闻标题内容。

import numpy as np
words_ary = np.array(words)
print(words_ary[k_data == 1]) 

       这里引入Numpy库,将之前13.3.2节存储分词完毕后新闻标题内容的words转换成array数组,然后以逻辑判断的方式提取分类标签为1的数据,结果如下,可以看到分类标签为1的新闻大多都是和Python相关的。

2、通过DBSCAN算法进行聚类分群

       DBSCAN 代码如下:

from sklearn.cluster import DBSCAN
dbs = DBSCAN(eps=1, min_samples=3)
d_data = dbs.fit_predict(df)

       其中设置模型的参数eps(画圆半径)为1,参数min_samples(圆内最小样本数)为3

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐