File size: 6,542 Bytes
fdffdf0
 
 
8ba144e
fdffdf0
8ba144e
 
 
 
 
 
 
 
 
 
 
fdffdf0
 
8ba144e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1c529f8
8ba144e
 
 
 
 
 
 
 
 
 
fdffdf0
8ba144e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fdffdf0
8ba144e
 
 
 
 
 
 
 
 
 
 
fdffdf0
8ba144e
 
 
 
 
 
fdffdf0
 
 
8ba144e
 
fdffdf0
 
 
 
1c529f8
8ba144e
 
 
 
 
 
1c529f8
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import numpy as np
from scipy.cluster.hierarchy import linkage, fcluster, dendrogram
import matplotlib.pyplot as plt
import numpy as np

def find_parent(matrix, node):
    # 获取该节点的所有可能的父节点及其概率
    parents = matrix[:, node]
    # 找出其中概率最大的父节点
    max_parent = np.argmax(parents)
    # 如果该父节点的概率不为零,那么返回该父节点
    if parents[max_parent] > 0:
        return max_parent
    # 否则,返回None,表示该节点没有父节点
    else:
        return None


def find_tree(matrix, node, depth=1, children=[], max_depth=1, visited=set()):
    # 定义一个空列表,用来存储结果
    result = []
    # 调用find_parent函数,找出该节点的最可能的父节点
    parent = find_parent(matrix, node)
    # 如果该父节点存在,且不在visited中
    if parent is not None and parent not in visited:
        # 将该父子关系添加到结果列表中
        result.append([parent, node])
        # 遍历当前节点的所有子节点
        for child in children:
            # 将该子节点和当前节点的关系也添加到结果列表中
            result.append([node, child])
        # 如果当前深度小于最大深度,那么递归地调用find_tree函数,传入概率矩阵和该父节点作为参数,并将深度加一
        if depth < max_depth:
            # 将当前节点添加到visited中
            visited.add(node)
            # 递归调用find_tree函数,并将visited传入
            result.extend(find_tree(matrix, parent, depth + 1, visited=visited))
    # 返回结果列表
    return result

# 定义一个函数,它接受一个树形结构作为参数,然后返回该树形结构的概率
def find_prob(tree, matrix):
    # 定义一个变量,用来存储概率,初始值为1
    prob = 1
    # 遍历树形结构中的每个父子关系
    for parent, child in tree:
        # 将该父子关系对应的概率乘到变量上
        prob *= matrix[parent][child]
    # 返回最终的概率
    return prob

# 定义一个函数,它接受一个概率矩阵和一个k值作为参数,然后返回前k个最可能的森林及其概率
def find_forests(matrix, k):
    # 定义一个空字典,用来存储每个森林及其概率
    forests = {}
    # 遍历所有的节点
    for i in range(len(matrix)):
        # 获取该节点的所有可能的子节点及其概率
        children = matrix[i]
        # 定义一个空列表,用来存储该节点的所有子节点
        child_list = []
        # 遍历所有的子节点
        for j in range(len(children)):
            # 如果子节点的概率不为零
            if children[j] > 0:
                # 将该子节点添加到列表中
                child_list.append(j)
        # 调用find_tree函数,传入概率矩阵、当前节点和子节点列表作为参数,并将返回的结果赋值给tree
        tree = find_tree(matrix, i, children=child_list)
        tree = tuple([tuple(x) for x in tree]) # 将列表中的每个元素转换为元组,然后再将整个列表转换为元组
        if tree:
            # 调用find_prob函数,传入tree作为参数,并将返回的结果赋值给prob
            prob = find_prob(tree, matrix)
            # 如果tree已经在字典的键中,即该树形结构已经被添加过
            if tuple(tree) in forests:  # 将tree转换为元组
                # 那么将prob加到字典的值上,表示该树形结构出现了多次
                forests[tuple(tree)] += prob  # 将tree转换为元组
            # 否则,即该树形结构是第一次被添加
            else:
                # 那么将tree和prob作为键值对添加到字典中
                forests[tuple(tree)] = prob  # 将tree转换为元组
    # 将字典按照值降序排序,得到一个列表,每个元素是一个键值对的元组
    sorted_forests = sorted(forests.items(), key=lambda x: x[1], reverse=True)
    # 返回列表的第一个元素,即最可能的森林及其概率
    forest, prob = sorted_forests[0]
    # 定义一个空字典,用来存储带有层级结构的森林
    result = {}
    # 遍历森林中的每个树形结构
    for parent, child in forest:
        # 如果父节点已经在字典的键中,即该父节点已经有其他子节点
        if parent in result:
            # 那么将当前子节点添加到父节点对应的值中,即该父节点的子节点列表中
            result[parent].append(child)
        # 否则,即该父节点是第一次出现
        else:
            # 那么将父节点和当前子节点作为键值对添加到字典中,即创建一个新的子节点列表
            result[parent] = [child]
    # 返回带有层级结构的字典和概率
    return result, prob
def passage_outline(matrix,sentences):

    # Z = linkage(matrix, method="average")
    # median = np.median(matrix)
    # print(median)
    # print('yes')
    # labels = fcluster(Z, t=median, criterion="distance")
    # print(labels)
    # 调用函数,传入概率矩阵作为参数,并且指定最大深度为1
    result, prob = find_forests(matrix, 1)
    # 打印结果字典和概率
    print(result, prob)
        # 根据簇标签和主题句子生成文章结构
    structure = {}
    for each in result.keys():
        structure[each] =[sentences[i] for i in result[each]]
    # for label, sentence in zip(result.keys(), sentences):
    #     if label not in structure:
    #         structure[label] = []
    #     structure[label].append(sentence)
    outline = ""
    outline_list = []
    for key in sorted(structure.keys()):
        outline_list.append(f"主题:")
        outline = outline+f"主题:\n"
        for sentence in structure[key]:
            outline_list.append(sentence)
            outline = outline+f"- {sentence}\n"
    return outline,outline_list
if __name__ == "__main__":
    matrix = np.array([[0.0 ,0.02124888, 0.10647043 ,0.09494194 ,0.0689209 ],
                        [0.01600688 ,0.0 ,0.05879448 ,0.0331325 , 0.0155093 ],
                        [0.01491911 ,0.01652437, 0.0, 0.04714563, 0.04577385],
                        [0.01699071 ,0.0313585 , 0.040299   ,0.0 ,0.014933  ],
                        [0.02308992 ,0.02791895 ,0.06547201, 0.08517842 ,0.0]])
    sentences = ["主题句子1", "主题句子2", "主题句子3", "主题句子4", "主题句子5"]
    print(passage_outline(matrix,sentences)[0])