以下是Python实现:

  1. 数据预处理

首先,需要从文件夹中读取所有的新闻,并将它们进行分词。这里可以使用jieba库进行中文分词。

import os
import jieba

# 读取新闻文件夹中的所有新闻
news_folder = './news/'
news = []
for folder in os.listdir(news_folder):
    folder_path = os.path.join(news_folder, folder)
    if os.path.isdir(folder_path):
        for file_name in os.listdir(folder_path):
            file_path = os.path.join(folder_path, file_name)
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
                news.append(content)

# 对每个新闻进行分词
news_tokens = []
for n in news:
    tokens = jieba.lcut(n)
    news_tokens.append(tokens)

这里使用了os库来遍历文件夹,jieba库进行分词。对于每个新闻,将其读取出来,然后分词并保存在一个列表中。

  1. 向量化

接下来,需要将每个新闻的内容向量化。这里可以使用onehot、TF-IDF和BoW等方法。

2.1 onehot

onehot方法是一种简单的向量化方法,它将每个词表示为一个独热向量,然后将每个句子表示为所有词的独热向量之和。

# 将每个词表示成独热向量
vocab = set()
for tokens in news_tokens:
    for token in tokens:
        vocab.add(token)
vocab = list(vocab)
vocab_size = len(vocab)
onehot_vectors = {}
for i, word in enumerate(vocab):
    vector = [0] * vocab_size
    vector[i] = 1
    onehot_vectors[word] = vector

# 将每个新闻表示为所有词的独热向量之和
onehot_vectors_list = []
for tokens in news_tokens:
    vector = [0] * vocab_size
    for token in tokens:
        if token in onehot_vectors:
            vector = [x + y for x, y in zip(vector, onehot_vectors[token])]
    onehot_vectors_list.append(vector)

这里先将所有的词表示成独热向量,然后将每个新闻表示为所有词的独热向量之和。最终得到的是一个向量列表,每个向量表示一篇新闻。

2.2 TF-IDF

TF-IDF方法则是将每个词表示成一个权重向量,其中权重由词频和文档频率计算得出。然后将每个句子表示为所有词的权重向量之和。

# 计算词频和文档频率
word_count = {}
doc_count = {}
for tokens in news_tokens:
    doc_count_set = set()
    for token in tokens:
        word_count[token] = word_count.get(token, 0) + 1
        if token not in doc_count_set:
            doc_count[token] = doc_count.get(token, 0) + 1
            doc_count_set.add(token)

# 计算TF-IDF权重
tfidf_vectors_list = []
for tokens in news_tokens:
    vector = [0] * vocab_size
    for token in tokens:
        if token in vocab:
            tf = tokens.count(token) / len(tokens)
            idf = 1 + math.log(len(news_tokens) / doc_count[token])
            tfidf = tf * idf
            index = vocab.index(token)
            vector[index] = tfidf
    tfidf_vectors_list.append(vector)

这里先计算每个词的词频和文档频率,然后根据公式计算TF-IDF权重。最终得到的是一个向量列表,每个向量表示一篇新闻。

2.3 BoW

BoW方法则是将每个词表示成一个计数向量,然后将每个句子表示为所有词的计数向量之和。

# 将每个词表示成计数向量
bow_vectors = {}
for tokens in news_tokens:
    for token in tokens:
        bow_vectors[token] = bow_vectors.get(token, 0) + 1

# 将每个新闻表示为所有词的计数向量之和
bow_vectors_list = []
for tokens in news_tokens:
    vector = [0] * vocab_size
    for token in tokens:
        if token in bow_vectors:
            index = vocab.index(token)
            vector[index] += 1
    bow_vectors_list.append(vector)

这里先将所有的词表示成计数向量,然后将每个新闻表示为所有词的计数向量之和。最终得到的是一个向量列表,每个向量表示一篇新闻。

  1. 网页相似度与聚类

有了向量化后的数据,就可以计算网页相似度和进行聚类了。这里可以使用scikit-learn库来进行计算。

3.1 网页相似度

首先,可以使用余弦相似度来计算两个向量的相似度。

from sklearn.metrics.pairwise import cosine_similarity

# 计算余弦相似度
similarity_matrix = cosine_similarity(tfidf_vectors_list)

这里使用了cosine_similarity函数来计算余弦相似度矩阵。得到的similarity_matrix是一个矩阵,其中每个元素表示两篇新闻的相似度。

3.2 聚类

接下来,可以使用聚类算法将新闻进行聚类。这里可以使用KMeans算法来进行聚类。

from sklearn.cluster import KMeans

# 使用KMeans算法进行聚类
kmeans = KMeans(n_clusters=4, random_state=0).fit(tfidf_vectors_list)
labels = kmeans.labels_

这里使用了KMeans算法,将新闻分为4个簇。得到的labels是一个列表,其中每个元素表示一篇新闻所属的簇。

完整代码如下:

import os
import jieba
import math
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.cluster import KMeans

# 读取新闻文件夹中的所有新闻
news_folder = './news/'
news = []
for folder in os.listdir(news_folder):
    folder_path = os.path.join(news_folder, folder)
    if os.path.isdir(folder_path):
        for file_name in os.listdir(folder_path):
            file_path = os.path.join(folder_path, file_name)
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
                news.append(content)

# 对每个新闻进行分词
news_tokens = []
for n in news:
    tokens = jieba.lcut(n)
    news_tokens.append(tokens)

# 将每个词表示成独热向量
vocab = set()
for tokens in news_tokens:
    for token in tokens:
        vocab.add(token)
vocab = list(vocab)
vocab_size = len(vocab)
onehot_vectors = {}
for i, word in enumerate(vocab):
    vector = [0] * vocab_size
    vector[i] = 1
    onehot_vectors[word] = vector

# 将每个新闻表示为所有词的独热向量之和
onehot_vectors_list = []
for tokens in news_tokens:
    vector = [0] * vocab_size
    for token in tokens:
        if token in onehot_vectors:
            vector = [x + y for x, y in zip(vector, onehot_vectors[token])]
    onehot_vectors_list.append(vector)

# 计算词频和文档频率
word_count = {}
doc_count = {}
for tokens in news_tokens:
    doc_count_set = set()
    for token in tokens:
        word_count[token] = word_count.get(token, 0) + 1
        if token not in doc_count_set:
            doc_count[token] = doc_count.get(token, 0) + 1
            doc_count_set.add(token)

# 计算TF-IDF权重
tfidf_vectors_list = []
for tokens in news_tokens:
    vector = [0] * vocab_size
    for token in tokens:
        if token in vocab:
            tf = tokens.count(token) / len(tokens)
            idf = 1 + math.log(len(news_tokens) / doc_count[token])
            tfidf = tf * idf
            index = vocab.index(token)
            vector[index] = tfidf
    tfidf_vectors_list.append(vector)

# 将每个词表示成计数向量
bow_vectors = {}
for tokens in news_tokens:
    for token in tokens:
        bow_vectors[token] = bow_vectors.get(token, 0) + 1

# 将每个新闻表示为所有词的计数向量之和
bow_vectors_list = []
for tokens in news_tokens:
    vector = [0] * vocab_size
    for token in tokens:
        if token in bow_vectors:
            index = vocab.index(token)
            vector[index] += 1
    bow_vectors_list.append(vector)

# 计算余弦相似度
similarity_matrix = cosine_similarity(tfidf_vectors_list)

# 使用KMeans算法进行聚类
kmeans = KMeans(n_clusters=4, random_state=0).fit(tfidf_vectors_list)
labels = kmeans.labels_

通过以上代码,就可以完成新闻文本的聚类分析。在实际应用中,可以根据具体的需求调整向量化方法、相似度计算方法和聚类算法,以便获得最佳的聚类结果。

Python实现新闻文本聚类:基于Onehot、TF-IDF和BoW向量化方法

原文地址: https://www.cveoy.top/t/topic/n2LM 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录