Python构建关键词共现矩阵完整版

Posted 兔子爱读书

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python构建关键词共现矩阵完整版相关的知识,希望对你有一定的参考价值。

有个网友写了一个帖子叫做:

python构建关键词共现矩阵,里面构造了完整的代码框架,可测试,有两个版本(numpy版和list版可用)。优点是完整可测试,缺点是速度较慢。

后来有网友改进了这个代码:

python构建关键词共现矩阵速度优化,里面对代码进行了优化,优点是能把几个小时能优化到3分钟,缺点是只贴出一部分代码。

我综合了这两个人的代码,构造出一个终版可用的版本。优点有:无需导入原始依赖的reader函数、速度快、可运行、去除了空关键词。代码如下:

# -*- coding: utf-8 -*-
# @ChangedDate    : 2021-07-15 19:23:00
# @Author  : Alan Lau (rlalan@outlook.com)
import numpy as np
import time
from pprint import pprint as p


def log(func):
    def wrapper(*args, **kwargs):
        now_time = str(time.strftime('%Y-%m-%d %X', time.localtime()))
        print('------------------------------------------------')
        print('%s func [%s] called' % (now_time, func.__name__))
        print('# %s' % func.__doc__)
        print('%s returns:' % func.__name__)
        re = func(*args, **kwargs)
        p(re)
        return re
    return wrapper


def readxls(path):
    import xlrd
    xl = xlrd.open_workbook(path)
    sheet = xl.sheets()[0]
    data = []
    for i in range(0, sheet.ncols):
        data.append(list(sheet.col_values(i)))
    return (data[0])


@log
def get_set_key(data, threshold=2):
    '''选取频数大于等于Threshold的关键词构建一个集合,用于作为共现矩阵的首行和首列'''
    all_key = '/'.join(data)
    key_list = [it.strip() for it in all_key.strip().split('/')]
    keys = set(key_list)
    dic = dict(zip(keys, [key_list.count(k) for k in keys]))
    
    wf = {k: v for k, v in dic.items() if k!='' and v >= threshold}
    set_key_list=[]
    for a in sorted(wf.items(), key=lambda item: item[1], reverse=True):
        set_key_list.append(a[0])
    return set_key_list


@log
def format_data(data, set_key_list):
    '''格式化需要计算的数据,将原始数据格式转换成二维数组'''
    formated_data = []
    for ech in data:
        ech_line = ech.split('/')

        temp=[]            # 筛选出format_data中属于关键词集合的词
        for e in ech_line:
            if e in set_key_list:
                temp.append(e)
        ech_line=temp

        ech_line = list(set(filter(lambda x: x != '', ech_line))) #set去掉重复数据
        formated_data.append(ech_line)
    return formated_data


@log
def build_matirx(set_key_list):
    '''建立矩阵,矩阵的高度和宽度为关键词集合的长度+1'''
    edge = len(set_key_list)+1
    # matrix = np.zeros((edge, edge), dtype=str)
    matrix = [[0 for j in range(edge)] for i in range(edge)]
    return matrix


@log
def init_matrix(matrix, set_key_list):
    '''初始化矩阵,将关键词集合赋值给第一列和第二列'''
    matrix[0][1:] = np.array(set_key_list)
    matrix = list(map(list, zip(*matrix)))
    matrix[0][1:] = np.array(set_key_list)
    return matrix

@log
def count_matrix(matrix, formated_data):
    '''计算各个关键词共现次数'''
    keywordlist=matrix[0][1:]  #列出所有关键词
    appeardict={}  #每个关键词与 [出现在的行(formated_data)的list] 组成的dictionary
    for w in keywordlist:
        appearlist=[]
        i=0
        for each_line in formated_data:
            if w in each_line:
                appearlist.append(i)
            i +=1
        appeardict[w]=appearlist
    for row in range(1, len(matrix)):
        # 遍历矩阵第一行,跳过下标为0的元素
        for col in range(1, len(matrix)):
                # 遍历矩阵第一列,跳过下标为0的元素
                # 实际上就是为了跳过matrix中下标为[0][0]的元素,因为[0][0]为空,不为关键词
            if col >= row:
                #仅计算上半个矩阵
                if matrix[0][row] == matrix[col][0]:
                    # 如果取出的行关键词和取出的列关键词相同,则其对应的共现次数为0,即矩阵对角线为0
                    matrix[col][row] = 0
                else:
                    counter = len(set(appeardict[matrix[0][row]])&set(appeardict[matrix[col][0]]))

                    matrix[col][row] = counter
            else:
                matrix[col][row]=matrix[row][col]
    return matrix


def main():
    keyword_path = r'test.xlsx'
    output_path = r'2.txt'
    data = readxls(keyword_path)
    set_key_list = get_set_key(data)
    formated_data = format_data(data, set_key_list)
    matrix = build_matirx(set_key_list)
    matrix = init_matrix(matrix, set_key_list)
    result_matrix = count_matrix(matrix, formated_data)
    np.savetxt(output_path, result_matrix, fmt=('%s,'*len(matrix))[:-1])



if __name__ == '__main__':
    main()

test.xlsx内容如下:

最后,还有一位网友贴出了一个“属性共现”的改进代码,见关键词共现/属性共现矩阵

 

以上是关于Python构建关键词共现矩阵完整版的主要内容,如果未能解决你的问题,请参考以下文章

词共现矩阵

有词篇矩阵和共现矩阵怎么在spss生成聚类树图

在 python pandas 中构造一个共现矩阵

关于高频关键词共现,ACA(作者同被引)等的范式

有没有办法在 python 中为参与者组织者建立一个共现(频率)矩阵?

数据挖掘导论 完整版+PPT+Python R代码