1.前言

最近在学习python词库的可视化,其中有一个依据共现矩阵制作的可视化,感觉十分炫酷,便以此复刻。
python 共现矩阵的实现_python

2.项目背景

本人利用爬虫获取各大博客网站的文章,在进行jieba分词,得到每篇文章的关键词,对这些关键词进行共现矩阵的可视化。

3.什么是共现矩阵

比如我们有两句话:

ls = ['我永远喜欢三上悠亚', '三上悠亚又出新作了']

在jieba分词下我们可以得到如下效果:
python 共现矩阵的实现_python_02
我们就可以构建一个以关键词的共现矩阵:

['',    '我', '永远', '喜欢', '三上', '悠亚', '又', '出', '新作', '了']['我',    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,并依次类推。
基于这个原因,我们可以发现,共现矩阵的特点是:

  1. 共现矩阵的[0][0]为空。
  2. 共现矩阵的第一行第一列是关键词。
  3. 对角线全为0。
  4. 共现矩阵其实是一个对称矩阵。

当然,在实际的操作中,这些关键词是需要经过清洗的,这样的可视化才干净。

4.共现矩阵的构建思路

  1. 每篇文章关键词的二维数组data_array。
  2. 所有关键词的集合set_word。
  3. 建立关键词长度+1的矩阵matrix。
  4. 赋值矩阵的第一行与第一列为关键词。
  5. 设置矩阵对角线为0。
  6. 遍历formated_data,让取出的行关键词和取出的列关键词进行组合,共现则+1。

5.共现矩阵的代码实现

# coding:utf-8import numpy as npimport pandas as pdimport jieba.analyseimport 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 matrixdef 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()