使用sklearn進行K Means文字聚類

2021-09-02 22:59:38 字數 2621 閱讀 9709

k-means演算法:中文名字叫做k-均值演算法,演算法的目的是將n個向量分別歸屬到k個中心點裡面去。演算法首先會隨機選擇k個中心向量,然後通過迭代計算以及重新選擇k個中心向量,使得n個向量各自被分配到距離最近的k中心點,並且所有向量距離各自中心點的和最小。

步驟一:在輸入資料集裡面隨機選擇k個向量作為初始中心點。 

步驟二:將每個向量分配到離各自最近的中心點,從而將資料集分成了k個類。 

步驟三:計算得到上步得到聚類中每一聚類觀測值的中心,作為新的均值點。 

步驟四:重複步驟三,直至結果收斂,這裡的收斂是指所有點到各自中心點的距離的和收斂。

k-means演算法的原理比較簡單,但是值得注意的是,有兩個地方是需要演算法使用者去自己選擇的:第乙個就是k的值,簡而言之就是資料集應該被分成多少個類,在k-means演算法裡面是要求先給出k值的; 第二個就是距離函式,即如何計算向量和向量或者向量和中心點之間的距離,這裡也有很多選擇,最常見的自然是歐式距離,也可以用余弦相似度來作為距離函式,還有其他的一些方法等等。以上兩個需要注意的選擇必然會對聚類結果產生影響,尤其是k值的選擇,這裡就需要演算法使用者根據自身需要來做出仔細衡量。

scikit-learn:

scikit-learn 是乙個基於python的machine learning模組,裡面給出了很多machine learning相關的演算法實現,其中就包括k-means演算法。

在做k-means聚類之前,我們首先需要對將文字轉化成向量的形式,轉換文字的第一步,自然是分詞,這裡可以直接使用jieba分詞,分完詞過後再將詞轉換成向量,或者說轉換成bag-of-words模型,這裡可以採用tf-idf演算法,tf-idf就是從兩個方面對文字中的詞進行加權:

詞在當前文字中出現的次數。

總文字數包含詞的數目。

前者越高越好,後者越低越好,比如說「你」,「我」這些詞,在乙個文字中出現的次數很多,總文字包含這些詞的數目也會很多,那麼這些詞自然無法作為當前文字的代表性內容,如果乙個文字中某個詞大量出現,但是在總文字中出現的次數又不多,那麼這個詞對於文字來說很有可能是很重要的。

在scikit-learn裡面,同樣也實現了tf-idf演算法,我們可以直接呼叫。

import jieba 

from sklearn.feature_extraction.text import tfidfvectorizer

from sklearn.cluster import kmeans

from sklearn.externals import joblib

def jieba_tokenize(text):

return jieba.lcut(text)

tfidf_vectorizer = tfidfvectorizer(tokenizer=jieba_tokenize,lowercase=false)

'''tokenizer: 指定分詞函式

lowercase: 在分詞之前將所有的文字轉換成小寫,因為涉及到中文文字處理,

所以最好是false

'''text_list = ["今天天氣真好啊啊啊啊",

"小明上了清華大學",

"我今天拿到了google的offer",

"清華大學在自然語言處理方面真厲害"]

#需要進行聚類的文字集

tfidf_matrix = tfidf_vectorizer.fit_transform(text_list)

num_clusters = 3

km_cluster = kmeans(n_clusters=num_clusters, max_iter=300, n_init=40,

init='k-means++',n_jobs=-1)

'''n_clusters: 指定k的值

max_iter: 對於單次初始值計算的最大迭代次數

n_init: 重新選擇初始值的次數

init: 制定初始值選擇的演算法

n_jobs: 程序個數,為-1的時候是指預設跑滿cpu

注意,這個對於單個初始值的計算始終只會使用單程序計算,

平行計算只是針對與不同初始值的計算。比如n_init=10,n_jobs=40,

伺服器上面有20個cpu可以開40個程序,最終只會開10個程序

'''#返回各自文字的所被分配到的類索引

result = km_cluster.fit_predict(tfidf_matrix)

print("predicting result:", result)

'''每一次fit都是對資料進行擬合操作,

所以我們可以直接選擇將擬合結果持久化,

然後**的時候直接載入,進而節省時間。

'''joblib.dump(tfidf_vectorizer, 'tfidf_fit_result.pkl')

joblib.dump(km_cluster, 'km_cluster_fit_result.pkl')

#程式下一次則可以直接load

tfidf_vectorizer = joblib.load('tfidf_fit_result.pkl')

km_cluster = joblib.load('km_cluster_fit_result.pkl')

predicting result: [0 1 2 1]

使用sklearn進行增量學習

sklearn.bayes.bernoullinb sklearn.linear model.perceptron sklearn.linear model.sgdclassifier sklearn.linear model.passiveaggressiveclassifier regressi...

使用sklearn進行增量學習

sklearn.bayes.bernoullinb sklearn.linear model.perceptron sklearn.linear model.sgdclassifier sklearn.linear model.passiveaggressiveclassifier regressi...

使用sklearn進行mnist資料集分類

深度之眼 西瓜書課後 import time import matplotlib.pyplot as plt import numpy as np from sklearn.datasets import fetch openml from sklearn.linear model import l...