1.前言
最近在學習python詞庫的可視化,其中有一個依據共現矩陣制作的可視化,感覺十分炫酷,便以此復刻。
2.項目背景
本人利用爬蟲獲取各大博客網站的文章,在進行jieba分詞,得到每篇文章的關鍵詞,對這些關鍵詞進行共現矩陣的可視化。
3.什么是共現矩陣
比如我們有兩句話:
ls = ['我永遠喜歡三上悠亞', '三上悠亞又出新作了']
在jieba分詞下我們可以得到如下效果:
我們就可以構建一個以關鍵詞的共現矩陣:
['', '我', '永遠', '喜歡', '三上', '悠亞', '又', '出', '新作', '了']
['我', 0, 1, 1, 1, 1, 0, 0, 0, 0]
['永遠', 1, 0, 1, 1, 1, 0, 0, 0, 0]
['喜歡' 1, 1, 0, 1, 1, 0, 0, 0, 0]
['三上', 1, 1, 1, 0, 1, 1, 1, 1, 1]
['悠亞', 1, 1, 1, 1, 0, 1, 1, 1, 1]
['又', 0, 0, 0, 1, 1, 0, 1, 1, 1]
['出', 0, 0, 0, 1, 1, 1, 0, 1, 1]
['新作', 0, 0, 0, 1, 1, 1, 1, 0, 1]
['了', 0, 0, 0, 1, 1, 1, 1, 1, 0]]
解釋一下,“我永遠喜歡三上悠亞”,這一句話中,“我”和“永遠”共同出現了一次,在共現矩陣對應的[ i ] [ j ]和[ j ][ i ]上+1,並依次類推。
基於這個原因,我們可以發現,共現矩陣的特點是:
- 共現矩陣的[0][0]為空。
- 共現矩陣的第一行第一列是關鍵詞。
- 對角線全為0。
- 共現矩陣其實是一個對稱矩陣。
當然,在實際的操作中,這些關鍵詞是需要經過清洗的,這樣的可視化才干凈。
4.共現矩陣的構建思路
- 每篇文章關鍵詞的二維數組formated_data。
- 所有關鍵詞的集合set_word。
- 建立關鍵詞長度+1的矩陣matrix。
- 賦值矩陣的第一行與第一列為關鍵詞。
- 設置矩陣對角線為0。
- 遍歷formated_data,讓取出的行關鍵詞和取出的列關鍵詞進行組合,共現則+1。
5.共現矩陣的代碼實現
```
# coding:utf-8
import numpy as np
import pandas as pd
import jieba.analyse
import os
# 獲取關鍵詞
def Get_file_keywords(dir):
data_array = [] # 每篇文章關鍵詞的二維數組
set_word = [] # 所有關鍵詞的集合
try:
fo = open('dic_test.txt', 'w+', encoding='UTF-8')
# keywords = fo.read()
for home, dirs, files in os.walk(dir): # 遍歷文件夾下的每篇文章
for filename in files:
fullname = os.path.join(home, filename)
f = open(fullname, 'r', encoding='UTF-8')
sentence = f.read()
words = " ".join(jieba.analyse.extract_tags(sentence=sentence, topK=30, withWeight=False,
allowPOS=('n'))) # TF-IDF分詞
words = words.split(' ')
data_array.append(words)
for word in words:
if word not in set_word:
set_word.append(word)
set_word = list(set(set_word)) # 所有關鍵詞的集合
return data_array, set_word
except Exception as reason:
print('出現錯誤:', reason)
return data_array, set_word
# 初始化矩陣
def build_matirx(set_word):
edge = len(set_word) + 1 # 建立矩陣,矩陣的高度和寬度為關鍵詞集合的長度+1
'''matrix = np.zeros((edge, edge), dtype=str)''' # 另一種初始化方法
matrix = [['' for j in range(edge)] for i in range(edge)] # 初始化矩陣
matrix[0][1:] = np.array(set_word)
matrix = list(map(list, zip(*matrix)))
matrix[0][1:] = np.array(set_word) # 賦值矩陣的第一行與第一列
return matrix
# 計算各個關鍵詞的共現次數
def count_matrix(matrix, formated_data):
for row in range(1, len(matrix)):
# 遍歷矩陣第一行,跳過下標為0的元素
for col in range(1, len(matrix)):
# 遍歷矩陣第一列,跳過下標為0的元素
# 實際上就是為了跳過matrix中下標為[0][0]的元素,因為[0][0]為空,不為關鍵詞
if matrix[0][row] == matrix[col][0]:
# 如果取出的行關鍵詞和取出的列關鍵詞相同,則其對應的共現次數為0,即矩陣對角線為0
matrix[col][row] = str(0)
else:
counter = 0 # 初始化計數器
for ech in formated_data:
# 遍歷格式化后的原始數據,讓取出的行關鍵詞和取出的列關鍵詞進行組合,
# 再放到每條原始數據中查詢
if matrix[0][row] in ech and matrix[col][0] in ech:
counter += 1
else:
continue
matrix[col][row] = str(counter)
return matrix
def main():
formated_data, set_word = Get_file_keywords(r'D:\untitled\test')
print(set_word)
print(formated_data)
matrix = build_matirx(set_word)
matrix = count_matrix(matrix, formated_data)
data1 = pd.DataFrame(matrix)
data1.to_csv('data.csv', index=0, columns=None, encoding='utf_8_sig')
main()
```