基本k mean聚類的文字聚類演算法原理和例子

2021-06-27 11:06:52 字數 3261 閱讀 2497

基於質心的劃分方法是研究最多的演算法,包括k-mean聚類演算法及其各種變體,這些變體依據初始簇的選擇,物件的劃分、相識度的計算方法、簇中心的計算方法不同而不同。基於質心的劃分方法將簇中所有物件的平均值看做簇的質心,根據乙個資料物件與簇質心的距離,將該物件賦予最近的簇。在這類方法中,需要給定劃分的簇個數k,首先得到k個初始劃分的集合,然後採用地帶重定位技術,通過將物件從乙個簇移到另外乙個簇來改進劃分的質量。

演算法:k-mean

輸入:資料集d,劃分簇的個數k

輸出:k個簇的集合

從資料集合d中任意選擇k個物件作為初始簇中心;、

repeat

for 資料集d中每個物件p do

計算物件p到k個簇中心的距離

將物件p指派到與其最近(距離最短)的簇

end for

計算每個簇中心物件的均值,作為新的簇的中心

until k個簇的簇中心不再發生變化

(2)對於文字聚類,使用中科院的分詞庫ictclas,介面封裝在split.h和split.cpp中,在分詞時,本例子只選用了動詞和名詞

(3)特徵詞選取使用tf-idf方法來提取每篇文章的前100個根據tf-idf大小排序的特徵詞

詞頻tf(term frequency)是指乙個詞條在乙個文字出現的頻數。頻數越大,則該詞語對文字的貢獻度越大。其重要可表示為

tf=n/n (n是指單詞w在文字di中出現的次數,ni是指文字di中所有詞語出現的總數)

逆文字頻度idf(inverse document frequency)表示詞語在整個文字集中的分布情況,包含該詞語的文字數目越少,則idf越大,數目該詞語具有較強的類別區別能力。

idf=log2(n/m) (n是文字集合的總個數,m是包含該詞語的文字個數)

最後將兩者相乘。

演算法實現思路是掃瞄所有的文章,對於每一篇文章都用乙個map來記錄單詞的頻數,掃瞄完一篇文章,就使用map來記錄文件頻數

/*

統計單詞頻數和文件頻數

*/void tfidfmeasure::statistics(void)

}map::iterator it_tf=tf.begin();

map::iterator it_end_tf=tf.end();

int wordsize=0;

for(;it_tf!=it_end_tf;it_tf++)

} //記錄文章的總單詞數目

it_document->wordsize=wordsize;

}}

/*

將it-idf的前100個作為文件的特徵向量如:(坦克:0.32;團長:0.02;...)

*/void tfidfmeasure::calcultfidf(void)

//排序

sort(vector_sort.begin(),vector_sort.end(),sort_keyword);

int size=limited>vector_sort.size()?vector_sort.size():limited;

//提取前100個

double absolute=0.0;

for(int i=0;ifeatrue.insert(make_pair(vector_sort[i].word,vector_sort[i].tf_idf));

}it_document->absolute=absolute;

} cout<

(4)兩篇文章之間的距離,本文使用余弦相似度來計算,將兩個向量相乘

//計算其餘弦相似度

double kmean::calculcosim(document &document1,document &document2)

for(map::iterator it_document2=document2.featrue.begin();it_document2!=document2.featrue.end();it_document2++)

//計算向量絕對值

absolute2+=(it_document2->second*it_document2->second);

} //cout

/*重新計算該簇的質心向量

*/void kmean::calculmean(vector&classes)

}

}vector> vector_sort;

for(map::iterator it=allfeatrue.begin();it!=allfeatrue.end();it++)

//取前面100個

sort(vector_sort.begin(),vector_sort.end(),cmp_featrue);

int size=limited>vector_sort.size()?vector_sort.size():limited;

int same=0;

for(int k=0;k::iterator it_find=classes[i].featrue.find(vector_sort[k].first);

if(it_find!=classes[i].featrue.end())

}cout<

void kmean::calculkmean(int times)

bool flag=true;

double maxcosvalue=0.0;

int maxindex=0;

for(int i=0;imaxcosvalue)

} //將文章放到對於的簇

myclasses[maxindex].document.push_back(documents[i]);

cout<

結果分析

選取第一遍遞迴後的準確率和質心相似率

第二遍遞迴後

可以看出第二遍後質心相似率達到了90%,準確率也有80%左右,對於該演算法還有很多研究的地方,比如初始k的選擇,質心的計算方法等,有興趣的同學可以交流一下。

K mean聚類演算法

k mean演算法屬於非監督類演算法,模型相對簡單。目標函式 j sum dj i 演算法 1 初始化k個點 2 樣本xi,到k個點的距離為 dk xi uk j argmin j dk xi屬於cj 3 更新引數 uk sum xi i sum i 重複2和3,終止條件j的變化很小或者uk變化很小...

kmean聚類python實現

import pandas as pd import numpy as np import xlrd 匯入資料 df2 pd.read excel test2.xlsx data np.array df2 去掉前兩列 data data 2 分為k類 k 3 臨近均值e e 0.00001 獲得行數...

聚類及K mean演算法

首先什麼是聚類,和分類有什麼區別,這裡講乙個例子,比如有一群學生考完期末考試,現在要根據他們的成績把他們劃分成幾個小組,讓老師分別進行輔導,這時候,你不知道要劃分幾個小組比較好,但你可以根據他們的成績,比較成績接近的歸到乙個小組,這個過程就是聚類,另一種情況是直接給出了90分段的乙個小組,80分段的...