Practice-8 K-means

1.实验目的

学习K-means理论,并使用K-means对文本进行分类

2.理论方法介绍

对于"监督学习"(supervised learning),其训练样本是带有标记信息的,并且监督学习的目的是:对带有标记的数据集进行模型学习,从而便于对新的样本进行分类。而在“无监督学习”(unsupervised learning)中,训练样本的标记信息是未知的,目标是通过对无标记训练样本的学习来揭示数据的内在性质及规律,为进一步的数据分析提供基础。对于无监督学习,应用最广的便是"聚类"(clustering)。
“聚类算法”试图将数据集中的样本划分为若干个通常是不相交的子集,每个子集称为一个“簇”(cluster),通过这样的划分,每个簇可能对应于一些潜在的概念或类别。
kmeans算法又名k均值算法。其算法思想大致为:先从样本集中随机选取 k 个样本作为簇中心,并计算所有样本与这 k 个“簇中心”的距离,对于每一个样本,将其划分到与其距离最近的“簇中心”所在的簇中,对于新的簇计算各个簇的新的“簇中心”。
根据以上描述,我们大致可以猜测到实现kmeans算法的主要三点:

  1. 簇个数 k 的选择
  2. 各个样本点到“簇中心”的距离
  3. 根据新划分的簇,更新“簇中心”

K-means算法要点
(1) k值得选择
k 的选择一般是按照实际需求进行决定,或在实现算法时直接给定 k 值。
(2) 距离的度量
给定样本 x ( i ) = { x 1 ( i ) , x 2 ( i ) , , . . . , x n ( i ) , } 与 x ( j ) = { x 1 ( j ) , x 2 ( j ) , , . . . , x n ( j ) , } x^{(i)} = \lbrace x_1^{(i)},x_2^{(i)},,...,x_n^{(i)}, \rbrace 与 x^{(j)} = \lbrace x_1^{(j)},x_2^{(j)},,...,x_n^{(j)}, \rbrace x(i)={x1(i),x2(i),,...,xn(i),}x(j)={x1(j),x2(j),,...,xn(j),},其中 i,j=1,2,…,m,表示样本数,n表示特征数。距离的度量方法主要分为以下几种:
有序属性距离度量:
闵可夫斯基距离(Minkowski distance):
d i s t m k ( x ( i ) , x ( j ) ) = ( ∑ u = 1 n ∣ x u ( i ) − x u ( j ) ∣ p ) 1 p dist_{mk}(x^{(i)},x^{(j)})=(\sum_{u=1}^n |x_u^{(i)}-x_u^{(j)}|^p)^{\frac{1}{p}} distmk(x(i),x(j))=(u=1nxu(i)xu(j)p)p1
欧氏距离(Euclidean distance),即当 p=2 时的闵可夫斯基距离:
d i s t e d ( x ( i ) , x ( j ) ) = ∣ ∣ x ( i ) − x ( j ) ∣ ∣ 2 = ∑ u = 1 n ∣ x u ( i ) − x u ( j ) ∣ 2 dist_{ed}(x^{(i)},x^{(j)})=||x^{(i)}-x^{(j)}||_2=\sqrt{\sum_{u=1}^n |x_u^{(i)}-x_u^{(j)}|^2} disted(x(i),x(j))=x(i)x(j)2=u=1nxu(i)xu(j)2
曼哈顿距离(Manhattan distance),即当 p=1 时的闵可夫斯基距离:
d i s t m a n ( x ( i ) , x ( j ) ) = ∣ ∣ x ( i ) − x ( j ) ∣ ∣ 1 = ∑ u = 1 n ∣ x u ( i ) − x u ( j ) ∣ dist_{man}(x^{(i)},x^{(j)})=||x^{(i)}-x^{(j)}||_1=\sum_{u=1}^n |x_u^{(i)}-x_u^{(j)}| distman(x(i),x(j))=x(i)x(j)1=u=1nxu(i)xu(j)
无序属性距离度量:
VDM(Value Difference Metric):
V D M p ( x u ( i ) , x u ( j ) ) = ∑ z = 1 k ∣ m u , x u ( i ) , z m u , x u ( i ) − m u , x u ( j ) , z m u , x u ( j ) ∣ p VDM_p(x_u^{(i)},x_u^{(j)}) = \sum_{z=1}^k \left|\frac{m_{u,x_u^{(i)},z}}{m_{u,x_u^{(i)}}} - \frac{m_{u,x_u^{(j)},z}}{m_{u,x_u^{(j)}}} \right|^p VDMp(xu(i),xu(j))=z=1kmu,xu(i)mu,xu(i),zmu,xu(j)mu,xu(j),zp
混合属性距离度量
M i n k o v D M p ( x ( i ) , x ( j ) ) = ( ∑ u = 1 n c ∣ x u ( i ) − x u ( j ) ∣ p + ∑ u = n c + 1 n V D M p ( x u ( i ) , x u ( j ) ) ) 1 p MinkovDM_p(x^{(i)},x^{(j)}) = \left( \sum_{u=1}^{n_c} | x_u^{(i)} - x_u^{(j)} | ^p + \sum_{u=n_c +1}^n VDM_p (x_u^{(i)},x_u^{(j)}) \right) ^{\frac{1}{p}} MinkovDMp(x(i),x(j))=(u=1ncxu(i)xu(j)p+u=nc+1nVDMp(xu(i),xu(j)))p1
Kmeans算法过程
在这里插入图片描述

3.实验数据及方法

本实验使用数据为中文文本分类数据集
THUCNews是根据新浪新闻RSS订阅频道2005~2011年间的历史数据筛选过滤生成,包含74万篇新闻文档(2.19 GB),均为UTF-8纯文本格式。在原始新浪新闻分类体系的基础上,重新整合划分出14个候选分类类别:财经、彩票、房产、股票、家居、教育、科技、社会、时尚、时政、体育、星座、游戏、娱乐。
本实验使用其中家居、彩票、房产、股票、财经5类,各50篇作为数据集。
1.导入必要的工具包

import os
import jieba
jieba.setLogLevel(20) #使jieba分词不显示日志
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
import warnings
warnings.filterwarnings('ignore')

2.将文件地址储存到数组

import os
path_list_all = []
for a, b, c in os.walk('D:\Working\THUCNews', topdown=False):
    path_list = []
    for files in c:
        path = a+'\\'+files
        path_list.append(path)
        path_list = path_list[:50]
    if path_list != []:
        path_list_all.append(path_list)
path_list_all = np.array(path_list_all)
print('包含文件数量:({},{})'.format(len(path_list_all),len(path_list_all[0])))
#包含文件数量:(5,50)

3.储存停用词

# 将停用词记录到列表stopWords中
stopWords = []
infile = open("D:\workspace\机器学习实验(课堂)\基于NBC的文本分类\stop_word_list.txt", 
               encoding='utf-8')
stopwords_lst = infile.readlines()
for word in stopwords_lst:
 stopWords.append(word.strip())

4.分词、去停用词,将处理后的文本储存到X_list中,标签储存到y_list中

X_list = [] # 储存处理好的文本,字符串形式
y_list = [] # 储存标签
for path in path_list_all:
    for n in range(len(path)):
        with open(path[n],mode='r',encoding='utf-8') as note:
            note = note.read()
            note_1 = note.replace('\n','')
            # print(note_1)
            seglist = jieba.lcut(note_1)
            # 去停用词
            newSent = []
            for word in seglist:
                word = word.strip()
                if word not in stopWords:
                    if word != '\t' and word != '\n':
                        newSent.append(word)
            label = path[n].split('\\')[-2]
            # print(label)
            text_str = ' '.join(newSent)
            X_list.append(text_str)
            y_list.append(label)

5.统计词频

# 统计词频
vectorizer = CountVectorizer( )  
# 计算个词语出现的次数  
X = vectorizer.fit_transform(X_list)
# 获取词袋中所有文本关键词  
word = vectorizer.get_feature_names()  
print('共有多少文本关键字:', len(word))  
# 查看词频结果  
print('词频矩阵的维度:', X.toarray().shape)
'''
共有多少文本关键字: 16857
词频矩阵的维度: (250, 16857)
'''

6.计算TF-IDF值

# 计算tfidf值
from sklearn.feature_extraction.text import TfidfTransformer  

# 类调用  
transformer = TfidfTransformer()   
# 将词频矩阵X统计成TF-IDF值  
tfidf = transformer.fit_transform(X)  
# 查看数据结构 tfidf[i][j]表示i类文本中的tf-idf权重  
X_data = tfidf.toarray()

7.使用K-means进行聚类

from sklearn.cluster import KMeans
estimator = KMeans(n_clusters=5)
estimator.fit(X_data)#聚类

4.实验结果及分析

1.输出分类结果

print(estimator.labels_)
'''
[0 0 3 3 3 3 3 3 3 3 3 3 3 0 3 0 3 3 3 0 3 3 3 0 3 3 3 3 3 3 2 2 2 2 2 2 0
 2 2 2 2 2 2 2 2 2 2 2 3 3 0 1 0 0 1 0 2 1 2 1 0 1 0 1 1 1 1 1 1 0 0 1 1 1
 1 0 0 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 0 1 1 0 0 1 0 3 3 3 3 3 0 0 3 3 0
 3 3 0 3 3 3 3 3 3 0 3 0 3 0 0 3 3 3 3 3 0 0 0 0 3 0 0 0 3 0 3 3 3 3 0 3 3
 0 0 0 4 4 0 4 0 4 4 0 4 4 4 0 4 4 4 0 4 4 4 0 4 4 4 0 4 4 4 4 4 4 4 4 4 4
 4 4 4 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0
 0 0 0 0 0 3 3 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 '''

2.统计一下每类文本个数

from collections import Counter
print(Counter(estimator.labels_))
# Counter({3: 118, 1: 39, 2: 32, 0: 31, 4: 30})
类别数量
3118
139
232
031
430

仅从分类数量上来看,文本聚类的准确度有待增强。在对文本进行聚类时应考虑其他分类方法,以达到更好的分类效果。无监督学习由于其没有标签,也无法较好的评判其分类准确度。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值