概述
根据新闻标题,对新闻进行聚类,注意这是无监督学习的范畴。
新闻内容是文本,因此核心是结巴分词和文本向量化的操作。
结巴分词
信托公司2019年上半年经营业绩概览,结巴分词为:信托公司 2019 年 上半年 经营 业绩 概览,注意分成了词。
文本向量化
例如:第1条新闻标题中识别出“金融”,“科技”,“厉害”这3个词,从第2条新闻标题中识别出“华能”,“信托”“厉害”这3个词,这2条标题一共能识别出“金融”,“科技”,“华能”,“信托”,“厉害”这5个不同的词。这5个词便构成了这2条新闻标题的词袋,CountVectorizer()函数会自动对词袋中的词进行编号,通过vocabulary_属性便能获取词袋的内容及相应编号。
{'金融': 4, '科技': 3, '厉害': 2, '华能': 1, '信托': 0}
可以看到,词袋是一个字典,每个词是字典的键,词对应的编号是字典的值。这些不同的词其实就代表着不同的特征,第几个编号就代表第几个特征。有了上面的词袋,就可以构建如下表所示的词频矩阵,表中的数值即为相关标题中对应特征词的出现频次。
标题1为“金融科技厉害”,特征3、4、5对应的词在标题1中各出现1次,上表中在特征3、4、5处对应的值就是1,特征1、2对应的词在标题1中出现0次,对应的值就是0,所以标题1对应的数值数组就是[00111]。同理,标题2对应的数值数组是[11100],这样便完成了文本数据的数值化。如果一个词出现了不止一次,例如,在某个标题中“金融”这个词出现了2次,那么其对应的值就是2。此外,CountVectorizer()函数会自动过滤掉一个字的词,这样会过滤掉“的”“之”等没有重要含义的词,不过同时也会过滤掉“爱”“坑”等可能有重要含义的词,因此,这个特点既是一个优势,也是一个劣势。
如此就完成了文本向量化,然后就可以根据据此进行聚类了。
代码实战
# # 1.读取数据
import pandas as pd
df = pd.read_excel('新闻.xlsx')
df.head()
import jieba
words = []
for i, row in df.iterrows():
words.append(' '.join(jieba.cut(row['标题'])))
print(words[0:3])
# ### 3.4 将所有新闻文本向量化并展示
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
vect = CountVectorizer()
X = vect.fit_transform(words) # 将分词后的内容文本向量化
X = X.toarray()
words_bag2 = vect.get_feature_names() # 第二种查看词袋的方法
df = pd.DataFrame(X, columns=words_bag2)
df.head()
# # 如果想显示pandas中DataFrmae所有行,或者所有列,可以采用下面的代码
# import pandas as pd
# pd.set_option('display.max_columns', None)
# pd.set_option('display.max_rows', None)
# df = pd.DataFrame(X, columns=words_bag2)
# df.head()
# # 13.3.3 模型搭建与使用
# # 1.通过KMeans算法进行聚类分群
from sklearn.cluster import KMeans
kms = KMeans(n_clusters=10, random_state=123)
k_data = kms.fit_predict(df)
print(k_data)
import numpy as np
words_ary = np.array(words)
print(words_ary[k_data == 1]) # ,查看分为1类别的的新闻标题有哪些,可以把数字1改成其他数字看看效果
# # 2.通过DBSCAN算法进行聚类分群,效果不好
# 说明了对于特征变量较多的数据,KMeans算法的聚类效果要优于DBSCAN算法的聚类效果。
from sklearn.cluster import DBSCAN
dbs = DBSCAN(eps=1, min_samples=3)
d_data = dbs.fit_predict(df)
print(d_data)
# 以下是补充知识点==================
# # 13.3.4 模型优化(利用余弦相似度进行优化)
# 1.余弦相似度基本概念
words_test = ['想去 华能 信托', '华能 信托 很好 想去', '华能 信托 很好 想去 华能 信托 很好 想去']
vect = CountVectorizer()
X_test = vect.fit_transform(words_test) # 将分词后的内容文本向量化
X_test = X_test.toarray()
words_bag2 = vect.get_feature_names() # 第二种查看词袋的方法
df_test = pd.DataFrame(X_test, columns=words_bag2)
df_test.head()
# 补充知识点:通过numpy库计算欧式距离
import numpy as np
dist = np.linalg.norm(df_test.iloc[0] - df_test.iloc[1])
print(dist)
from sklearn.metrics.pairwise import cosine_similarity
cosine_similarities = cosine_similarity(df_test)
print(cosine_similarities)
# 2.余弦相似度实战 - 模型优化,实战中可以使用这个,更加好
from sklearn.metrics.pairwise import cosine_similarity
cosine_similarities = cosine_similarity(df)
print(cosine_similarities)
from sklearn.cluster import KMeans
kms = KMeans(n_clusters=10, random_state=123)
k_data = kms.fit_predict(cosine_similarities)
print(k_data)
print(k_data == 3)
print(words[0:3])
words_ary = np.array(words)
print(words_ary[0:3])
import numpy as np
words_ary = np.array(words)
print(words_ary[k_data == 3]) # 可以把数字3改成其他数字看看效果
#补充知识点==================