基于 K-Means 算法的文本聚类

K-Means 算法的文本聚类

1、 能够从社交媒体或网上给定的数据集(数据集已给定),从中挖掘出新闻话题,如在线检测微博消息中大量突现的关键字,并将它们进行聚类,从而找到若干个新闻话题。 
2、 给定一个新闻信息或报道作为测试样本,测试其所属的报道分类。 
3、 最终要求有训练集,测试集,聚类模型和相关源码及简要说明。 
4、 系统实现包含预处理,特征提取,训练时采用的聚类模型,测试时采用的分类模型。 

实验预备知识: Python基本语法 
K-means聚类算法相关知识 
基于TF-IDF算法的特征提取 
文档相似度计算 
实验环境: Windows10操作系统Python2.7 IDLE

转载地址

一、 实现流程 
这里写图片描述 
二、 概要设计 
1、 读取训练集文本内容 
读取给定数据集文件夹中每一个文档后,将文本内容写入一个Result.txt,每一行为一个文档,方便后面词频矩阵的处理。
2、 文本预处理 
读取之前存放所有文本内容的Result.txt,将其内容去空格,去标点,并用结巴进行分词。 
3、 特征提取 
使用scikit-learn工具调用CountVectorizer()和TfidfTransformer()函数计算TF-IDF值,将文本转为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频。将词频矩阵保存在TF-IDF_Result文档中。 
4、 K-Means聚类 
,对文本根据浏览内容后的经验分为3类,调用sklearn.cluster实现,并保存该聚类模型,对测试集使用 
5、 测试集分类 
使用clf.fit_predict 方法测试测试集文本。 
三、 关键模块详细设计实现 
1、 特征提取

from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer

# 将文本中的词语转换为词频矩阵 矩阵元素a[i][j] 表示j词在i类文本下的词频
vectorizer = CountVectorizer()

# 该类会统计每个词语的tf-idf权值
transformer = TfidfTransformer()

# 第一个fit_transform是计算tf-idf 第二个fit_transform是将文本转为词频矩阵
tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))

# 获取词袋模型中的所有词语
word = vectorizer.get_feature_names()

# 将tf-idf矩阵抽取出来,元素w[i][j]表示j词在i类文本中的tf-idf权重
weight = tfidf.toarray()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2、 聚类模型

from sklearn.cluster import KMeans
from sklearn.externals import joblib

def K_Means(weight):
    print 'Start Kmeans:'

    # 选择3个中心点
    clf = KMeans(n_clusters=3)

    # clf.fit(X)可以把数据输入到分类器里
    clf.fit(weight)

    # 3个中心点
    print 'cluster_center:'
    print(clf.cluster_centers_)

    # 每个样本所属的簇
    # print(clf.labels_)
    print'list_number label  '
    i = 1
    while i <= len(clf.labels_):
        print i,'          ',clf.labels_[i - 1]
        i = i + 1

    # 用来评估簇的个数是否合适,距离越小说明簇分的越好,选取临界点的簇个数
    print 'inertia:'
    print(clf.inertia_)

    # 保存模型
    joblib.dump(clf, 'km.pkl')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

四、 结果展示 
1、聚类结果 
注:训练集在train文件夹中 
这里写图片描述 
这里写图片描述

2、 分类结果 
注:测试集在test文件夹中 
这里写图片描述

五、 参考资料 
【1】 http://blog.csdn.net/eastmount/article/details/50323063 
【2】 http://blog.itpub.net/12199764/viewspace-1479320/ 
【3】 http://blog.csdn.net/zouxy09/article/details/17589329 
【4】 http://www.cnblogs.com/meelo/p/4272677.html 
【5】 http://scikit-learn.org/stable/modules/clustering.html#clustering

六、实验源码

# *- coding: utf-8 -*-


import sys
import os
import jieba
import jieba.analyse
import codecs
import re
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
from zhon.hanzi import punctuation
from sklearn.cluster import KMeans
from sklearn.externals import joblib

reload(sys)
sys.setdefaultencoding('utf8')


# Step1:Read file

def read_file():
    path = "train\\C4-Literature\\"
    resName = "Result.txt"
    if os.path.exists(resName):
        os.remove(resName)
    result = codecs.open(resName, 'w', 'utf-8')

    num = 1
    while num <= 33:
        name = "C4-Literature%d" % num
        fileName = path + str(name) + ".txt"
        source = open(fileName, 'r')
        line = source.readline().decode('GB2312')
        line = line.strip('\n')
        line = line.strip('\r')

        while line != "":
            line = line.encode('utf-8')
            line = line.replace('\n', ' ')
            line = line.replace('\r', ' ')
            result.write(line + ' ')
            line = source.readline().decode('GB2312')
        else:
            result.write('\r\n')
            source.close()
        num = num + 1

    else:
        result.close()

    return resName

# Step2:cut file and get feature vector matrixes
def get_TFIDF(resname,filename):
    corpus = []  # 语料库 空格连接

    # 读取语料  一行为一个文档
    for line in open(resname, 'r').readlines():
        line=line.strip() # 删除末尾的'/n'
        string = re.sub(ur"[%s]+" % punctuation, "", line.decode("utf-8"))  # 去标点
        seg_list = jieba.cut(string,cut_all=False) # 结巴分词
        corpus.append(' '.join(seg_list))

    # 将文本中的词语转换为词频矩阵 矩阵元素a[i][j] 表示j词在i类文本下的词频
    vectorizer = CountVectorizer()

    # 该类会统计每个词语的tf-idf权值
    transformer = TfidfTransformer()

    # 第一个fit_transform是计算tf-idf 第二个fit_transform是将文本转为词频矩阵
    tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))

    # 获取词袋模型中的所有词语
    word = vectorizer.get_feature_names()

    # 将tf-idf矩阵抽取出来,元素w[i][j]表示j词在i类文本中的tf-idf权重
    weight = tfidf.toarray()

    # fileName = "TF-IDF_Result.txt"
    result = codecs.open(filename, 'w', 'utf-8')
    for j in range(len(word)):
        result.write(word[j] + ' ')
    result.write('\r\n\r\n')

    # 打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重
    for i in range(len(weight)):
        for j in range(len(word)):
            result.write(str(weight[i][j]) + ' ')
        result.write('\r\n\r\n')

    result.close()
    return weight

# Step3:Clustering
def K_Means(weight):
    print 'Start Kmeans:'

    # 选择3个中心点
    clf = KMeans(n_clusters=3)

    # clf.fit(X)可以把数据输入到分类器里
    clf.fit(weight)

    # 3个中心点
    print 'cluster_center:'
    print(clf.cluster_centers_)

    # 每个样本所属的簇
    # print(clf.labels_)
    print'list_number label  '
    i = 1
    while i <= len(clf.labels_):
        print i,'          ',clf.labels_[i - 1]
        i = i + 1

    # 用来评估簇的个数是否合适,距离越小说明簇分的越好,选取临界点的簇个数
    print 'inertia:'
    print(clf.inertia_)

    # 保存模型
    joblib.dump(clf, 'km.pkl')

# Step4:Test
def test():
    path = "test\\"
    test_name = "test_result.txt"
    file_name = "test_TF-IDF.txt"
    if os.path.exists(test_name):
        os.remove(test_name)
    test_result = codecs.open(test_name,'w','utf-8')

    for file in os.listdir(path):
        source = open(path + file,'r')
        line = source.readline().decode('GB2312')
        line = line.strip('\n')
        line = line.strip('\r')

        while line !="":
            line = line.encode('utf-8')
            line = line.replace('\n',' ')
            line = line.replace('\r',' ')
            test_result.write(line + ' ')
            line=source.readline().decode('GB2312')

        else:
            test_result.write('\n\r')
            source.close()
    test_result.close()

    test_weight = get_TFIDF(test_name,file_name)

    # 载入保存的模型
    clf = joblib.load('km.pkl')

    clf.fit_predict(test_weight)

    print'list_number label  '
    i = 1
    while i <= len(clf.labels_):
        print i, '          ', clf.labels_[i - 1]
        i = i + 1


if __name__ == '__main__':
    resName = read_file()
    filename = "TF-IDF_Result.txt"
    weight=get_TFIDF(resName,filename)
    K_Means(weight)
    test()
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值