K-Means聚类讲解:算法和Sklearn实现(附代码讲解)

K-Means聚类是机器学习领域中最强大的聚类算法之一。他的原因比较简单,但得出的结果也非常准确。聚类是理解数据集的非常重要的方式,因此在本文中,我们将讨论什么是聚类,为什么需要聚类以及什么是k-means聚类。

什么是聚类

聚类是根据数据的属性将数据分为两个或更多组的任务,更确切地说,是基于数据中或多或少明显的某些模式。目的是在数据中找到那些模式,以帮助我们确保在给定数据集中某个项目的情况下,我们能够正确地将该项目放置在正确的组中,从而使其与该组中的其他项目相似,但与其他组中的项目不同。这意味着聚类实际上由两部分组成:一个是识别组,另一个是尽可能地将每个项目放置在正确的组中。聚类算法的理想结果是,同一组中的两个项目彼此相似,而不同组中的两个项目则尽可能地不同。

K-Means聚类讲解:算法和Sklearn实现(附代码讲解)

一个真实的例子就是客户细分。作为一家销售各种产品或服务的企业,很难为每个客户找到理想的业务策略。但是我们可以尝试将客户分为几个子组,了解这些客户的共同点,并针对每个组调整我们的业务策略。而向客户提出错误的业务策略可能意味着失去该客户,因此,重要的一点是我们必须实现良好的市场集群。

什么是无监督机器学习

无监督机器学习是一种机器学习算法,试图在没有任何先验知识的情况下推断数据中的模式。与之相反的是有监督的机器学习,这里我们有一个训练集,该算法将尝试通过将输入与预定义的输出进行匹配来查找数据中的模式。

之所以这样说,是因为将无监督机器学习任务聚类。在应用聚类算法时,尽管我们可以设置要标识的类别数量,但我们也不会先验地知道类别。

类别将从分析数据的算法中得出。因此,我们可以将集群称为探索性机器学习任务,因为我们只知道类别的数量,但不知道其属性。然后,我们可以尝试使用不同数量的类别,看看是否可以更好地对数据进行聚类。

然后,我们必须了解我们的集群,这实际上可能是最不同的任务。让我们将示例与客户细分一起重用。假设我们已经运行了聚类算法,并且将客户分为三类。但是那些团体是什么?为什么算法会确定这些客户属于该组,而那些客户属于该组?这是需要我们非常丰富的经验以及非常了解业务的人员的任务。他们将查看数据,尝试分析每个类别中的一些项目并尝试猜测一些条件。然后,将在找到有效模式后进行推断。

当我们获得新客户时会发生什么?我们必须将该客户放入我们已经拥有的一个集群中,因此我们可以通过算法来运行有关该客户的数据,该算法将使我们的客户放入一个集群。另外,将来,在获得大量新客户之后,我们可能需要重建集群——也许新集群或旧集群会消失。

集群应用

有哪些常见的集群应用程序?

最常见的用例是我们已经讨论过的用例:客户/市场细分。公司一直在进行这些类型的分析,以便他们可以了解其客户和市场,并量身定制其业务战略,服务和产品,以更好地去适应需求。

另一个常见的用例是信息提取任务。在信息提取任务中,我们经常需要查找实体,单词,文档等之间的关系。现在,假设如果直觉发现,我们更有可能找到彼此之间更相似的项目之间的关系,那么这么做是可行的,因为对数据点进行聚类可以帮助我们找出在哪里寻找关系。

另一个非常流行的用例是使用聚类进行图像分割。图像分割是查看图像并尝试识别该图像中不同项目的任务。我们可以使用聚类分析图像的像素并确定图像中的哪个项目包含哪个像素。

K-均值聚类说明

K-Means聚类算法是一种迭代聚类算法,它试图将数据点准确分配给我们预定义的K个聚类中的一个聚类。

与其他任何聚类算法一样,它试图使一个聚类中的项目尽可能相似,同时也使聚类之间彼此尽可能不同。通过确保群集中的数据点与该群集的质心之间的平方距离之和最小。群集的质心是群集中所有值的

平均值。也可以从本段获得K-Means名称的来源。

用更多的技术术语,我们尝试使数据尽可能地同质化,而使集群尽可能不异质。该ķ号码是我们试图获得集群的数量。我们可以和K一起玩直到对结果满意为止。

K均值聚类算法

K-Means聚类算法只需几个简单步骤即可工作。

  1. 分配K个集群
  2. 随机整理数据,并将每个数据点随机分配给K个聚类之一,并分配初始随机质心。
  3. 计算每个数据点和所有质心之间的平方和。
  4. 根据步骤3的计算,将每个数据点重新分配给最近的质心。
  5. 通过计算每个群集的平均值来重新分配质心
  6. 重复步骤3、4、5,直到我们不再需要更改集群中的任何内容

运行K-Means聚类算法所需的时间取决于数据集的大小,我们定义的K数和数据中的模式。

使用Scikit-Learn和Python的K-Means聚类实现

我们将使用Sckikit-Learn Python库在较小的数据集上运行K-Means聚类算法。

K均值聚类算法的数据集

数据包含有关伦敦,巴黎和柏林的3种文字。我们将提取有关这3个城市的Wikipedia文章的摘要部分,并通过我们的聚类算法运行它们。

然后,我们将提供我们自己的3个新句子,并检查它们是否正确分配给各个群体。如果发生这种情况,那么我们将知道我们的聚类算法有效。

K-Means聚类实施

首先,让我们安装依赖项。

<code> 

pip3

install scikit-learn

pip3

install nltk

pip3

install wikipedia

/<code>

现在,让我们定义一个小类,以帮助从Wikipedia页面收集文本。我们会将文本存储到本地的3个文件中,以便在每次运行算法时都不会再次下载文本。第一次使用该算法时,请立即使用class,第二次使用时,可以注释第8-12行和取消注释第13-15行。

<code>import wikipedia

class

TextFetcher

:

def

__init__

(

self

, title)

:

self

.title = title page = wikipedia.page(title) f = open(title +

".txt"

,

"w"

) f.write(page.summary) f.close()

self

.text = page.summary

def

getText

(

self

)

:

return

self

.text /<code>

现在,我们来构建数据集。我们将获取有关每个城市的文字,并删除停用词 停用词是我们通常在每个文本处理任务之前过滤掉的词。它们是英语中非常常见的单词,不会给文本带来任何价值和意义。由于它们大多数都在各处使用,因此它们将阻止我们正确地对文本进行聚类。

<code>

from

text_fetcher

import

TextFetcher

from

nltk.corpus

import

stopwords

from

nltk.tokenize

import

word_tokenize

from

sklearn.feature_extraction.text

import

TfidfVectorizer

from

sklearn.cluster

import

KMeans

import

nltk

def

preprocessor

(text)

:

nltk.download(

'stopwords'

) tokens = word_tokenize(text)

return

(

" "

).join([word

for

word

in

tokens

if

word

not

in

stopwords.words()])

if

__name__ ==

"__main__"

: textFetcher = TextFetcher(

"London"

) text1 = preprocessor(textFetcher.getText()) textFetcher = TextFetcher(

"Paris"

) text2 = preprocessor(textFetcher.getText()) textFetcher = TextFetcher(

"Berlin"

) text3 = preprocessor(textFetcher.getText()) docs = [text1, text2, text3]/<code>

词向量化技术

众所周知,计算机在理解文本方面非常差,但是在处理数字方面却表现得更好。因为我们的数据集是由单词组成的,所以我们需要将单词转换为数字。

词嵌入或词向量化表示用于将词分配给实数向量的技术的集合,机器学习可将这些词用于某些目的,其中之一是文本聚类。

Scikit-Learn库包含一些单词向量器,但是对于本文,我们将选择TfidfVectorizer。

<code>

tfidf_vectorizer

= TfidfVectorizer()

tfidf

= tfidf_vectorizer.fit_transform(docs)/<code>

现在是时候应用我们的K-Means聚类算法了。我们很幸运,Scikit-Learn很好地实现了K-Means算法,我们将使用它。因为我们知道我们要将文本分为3类(每个城市一个),所以我们将K值定义为3。

<code>

kmeans

=

KMeans(n_clusters

=

3

).fit(tfidf)

print(kmeans)

#输出:[0

1

2

]

/<code>

简而言之,这3个值就是我们的3个类。

为了测试它们,我们现在可以提供3个文本,我们可以肯定地知道它们应该在不同的群集中,并查看它们是否分配正确。我们必须确保不要忘记也将这三个文本向量化,以便我们的算法能够理解它们。

<code>    

test

= [

"This is one is about London."

,

"London is a beautiful city"

,

"I love London"

] results = kmeans.predict(tfidf_vectorizer.transform(

test

))

print

(results)

test

= [

"This is one is about Paris."

,

"Paris is a beautiful city"

,

"I love Paris"

] results = kmeans.predict(tfidf_vectorizer.transform(

test

))

print

(results)

test

= [

"This is one is about Berlin."

,

"Berlin is a beautiful city"

,

"I love Berlin"

] results = kmeans.predict(tfidf_vectorizer.transform(

test

))

print

(results)

test

= [

"This is about London"

,

"This is about Paris"

,

"This is about Vienna"

] results = kmeans.predict(tfidf_vectorizer.transform(

test

))

print

(results) /<code>

假设会得到另一条我们什么都不知道的文本。我们可以将该文本通过分类器,然后查看其适合的类别。而这是一个非常有效的文本分类器。


分享到:


相關文章: