def phrase_extract(text):
text = text.lower()
custom_kw_extractor = yake.KeywordExtractor(top=2, lan="en")
keywords = custom_kw_extractor.extract_keywords(text)
phrase_list = []
for keyword, score in keywords:
if len(keyword.split(' ')) > 1:
phrase_list.append(keyword.lower())
phrases_list = []
for phrase in phrase_list:
for i in range(0, len(text.split(phrase)) - 1):
phrases_list.append(phrase)
return phrases_list
这段代码是一个用于提取短语的函数。它使用了一个名为yake
的关键词提取器,该提取器可以从文本中提取出关键词及其得分。
函数首先将输入的文本转换为小写字母,并创建了一个yake.KeywordExtractor
对象custom_kw_extractor
,设置了提取的关键词数量为2,指定语言为英文。
然后,通过调用custom_kw_extractor.extract_keywords(text)
方法,提取出文本中的关键词及其得分,保存在keywords
列表中。
接下来,函数遍历keywords
列表中的每个关键词及其得分,如果关键词包含多个单词(通过判断关键词中是否存在空格来判断),则将其转换为小写字母,并添加到phrase_list
列表中。
最后,函数通过循环遍历phrase_list
列表中的每个短语,并根据短语在文本中的出现次数,将该短语重复添加到phrases_list
列表中,以便后续处理。
最终,函数返回一个包含重复出现的短语的列表phrases_list
。
def segment(text):
phrases_list = phrase_extract(text)
word_list = []
for i in text.split(' '):
word_list.append(i)
table = str.maketrans('', '', string.punctuation)
tokens = [w.translate(table) for w in word_list]
tokens = [word for word in tokens if word.isalpha()]
tokens = [word.lower() for word in tokens if word.lower() not in stop_words] # 过滤停用词
tokens = [word for word in tokens if len(word) > 1]
tokens = list(set(tokens+phrases_list))
return tokens
这段代码是一个用于文本分词的函数。它调用了之前提到的phrase_extract
函数来获取短语列表,并对输入的文本进行一系列处理。
函数首先通过调用phrase_extract(text)
方法获取短语列表,并将其保存在phrases_list
变量中。
然后,函数将输入的文本按空格分割成一个个单词,并保存在word_list
列表中。
接下来,函数使用string.punctuation
模块中的标点符号字符串来创建一个转换表table
,该表用于去除单词中的标点符号。然后,通过遍历word_list
列表,使用str.translate(table)
方法去除每个单词中的标点符号,并将处理后的单词保存在tokens
列表中。
继而,函数通过一系列步骤过滤和处理tokens
列表中的单词。首先,通过判断单词是否只包含字母来保留只含字母的单词,即过滤掉包含数字或其他字符的单词。然后,将单词转换为小写字母形式,并通过判断单词是否在停用词列表stop_words
中来过滤停用词。接着,过滤掉长度小于等于1的单词。
最后,函数将tokens
列表与phrases_list
列表合并,并去除重复的元素,得到最终的分词结果,并将其作为函数的返回值。
def get_set_key(data, threshold=2):
'''选取频数大于等于Threshold的关键词构建一个集合,用于作为共现矩阵的首行和首列'''
print(data)
if data is None:
return []
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
函数内部的逻辑如下:
- 首先,函数打印输入的
data
。 - 接着,对输入的
data
进行判空操作,如果data
为空,则返回一个空列表[]
。 - 将
data
中的所有元素连接成字符串并以斜杠分隔,然后用split('/')
方法分割成列表,并去除每个元素两端的空格,得到key_list
。 - 将
key_list
转换为集合keys
,并统计每个关键词的出现频数,保存在字典dic
中。 - 通过遍历
dic
字典,筛选出出现频数大于等于阈值且非空的关键词,保存在字典wf
中。 - 将字典
wf
按值进行排序,并将排序后的关键词添加到列表set_key_list
中。 - 最终,返回经过排序后的关键词列表
set_key_list
作为函数的输出结果。
def format_data(data, set_key_list):
'''格式化需要计算的数据,将原始数据格式转换成二维数组'''
formated_data = []
for ech in data:
ech_line = str(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
这段代码定义了一个名为format_data
的函数,该函数用于格式化需要计算的数据,将原始数据格式转换成二维数组。函数的逻辑如下:
- 函数打印输入的
data
和set_key_list
。 - 对于
data
中的每个元素ech
,将其转换为字符串并使用斜杠进行分割,得到ech_line
。 - 创建空列表
temp
,用于存储ech_line
中属于关键词集合set_key_list
的词。 - 遍历
ech_line
,将属于关键词集合的词添加到temp
中。 - 将
temp
转换为集合,过滤掉空字符串,并转换为列表,得到ech_line
。 - 将处理后的
ech_line
添加到formated_data
中。 - 返回经过格式化处理后的
formated_data
作为函数的输出结果。
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
coocur_count = [] # 存储关键词共现次数的列表
num_keywords = len(keywordlist)
sparse_matrix = dok_matrix((num_keywords, num_keywords), dtype=int) # 使用稀疏矩阵存储共现次数
def calculate_coocur_count(row, col):
if col >= row:
# 仅计算上半个矩阵
if matrix[0][row] == matrix[col][0]:
# 如果取出的行关键词和取出的列关键词相同,则其对应的共现次数为0,即矩阵对角线为0
sparse_matrix[col, row] = 0
else:
counter = len(set(appeardict[matrix[0][row]]) & set(appeardict[matrix[col][0]]))
sparse_matrix[col, row] = counter
coocur_count.append((matrix[0][row], matrix[col][0], counter))
else:
sparse_matrix[col, row] = sparse_matrix[row, col]
# 使用多线程计算共现次数
with ThreadPoolExecutor() as executor:
for row in range(1, num_keywords):
for col in range(1, num_keywords):
executor.submit(calculate_coocur_count, row, col)
# 根据共现次数进行降序排序
coocur_count.sort(key=lambda x: x[2], reverse=True)
top_50 = coocur_count[:5000] # 只保留排名前50的共现次数
# 构建新的关键词集合
new_set_key_list = set()
for item in top_50:
new_set_key_list.add(item[0])
new_set_key_list.add(item[1])
# 构建缩减后的矩阵
reduced_matrix = build_matrix(list(new_set_key_list))
reduced_matrix = init_matrix(reduced_matrix, list(new_set_key_list))
for item in top_50:
row_index = reduced_matrix[0].index(item[0])
col_index = reduced_matrix[0].index(item[1])
reduced_matrix[row_index][col_index] = item[2]
return reduced_matrix
这段代码定义了一个名为count_matrix
的函数,用于计算关键词的共现次数和构建缩减后的矩阵。
函数的逻辑如下:
- 从
matrix
中提取出所有的关键词,存储在keywordlist
列表中。 - 创建一个空字典
appeardict
,用于存储每个关键词在formated_data
中出现的行号列表。 - 遍历
keywordlist
,对于每个关键词w
,遍历formated_data
中的每行each_line
,如果关键词w
存在于该行,则将当前行号i
添加到appearlist
中。 - 将关键词
w
与appearlist
组成的键值对添加到appeardict
字典中。 - 创建一个空列表
coocur_count
,用于存储关键词的共现次数。 - 获取关键词的数量,创建一个空的稀疏矩阵
sparse_matrix
,其大小为(num_keywords, num_keywords)
,数据类型为整型。 - 定义了一个局部函数
calculate_coocur_count
,用于计算关键词的共现次数。该函数接受两个参数:row
和col
,表示矩阵中的行号和列号。 - 在
calculate_coocur_count
函数内部,如果col
大于等于row
,则仅计算上半个矩阵。如果取出的行关键词和列关键词相同,则对应的共现次数为0,即矩阵对角线为0;否则,计算两个关键词在appeardict
中对应的出现行号列表的交集,并统计交集的元素个数作为它们的共现次数。 - 如果
col
小于row
,则将矩阵中对称位置的共现次数设置为与其对应的行列位置的共现次数相同。 - 使用多线程计算共现次数,遍历行号
row
和列号col
的范围,并使用ThreadPoolExecutor
创建线程池,分配每个任务给一个线程进行计算。 - 根据共现次数对
coocur_count
进行降序排序。 - 获取前5000个共现次数最高的关键词组合,存储在
top_50
列表中。 - 创建一个新的关键词集合
new_set_key_list
,遍历top_50
中的每个元组,将关键词添加到集合中。 - 使用
build_matrix
函数构建一个由new_set_key_list
中关键词组成的缩减后的矩阵reduced_matrix
。 - 使用
init_matrix
函数初始化reduced_matrix
,将矩阵的第一行和第一列设置为关键词列表。 - 遍历
top_50
,获取每个关键词组合在reduced_matrix
中对应的行号和列号,将对应位置的元素设置为共现次数。 - 返回缩减后的矩阵
reduced_matrix
作为函数的输出结果。
# 定义一个空字典用于存储词组搭配及其出现次数
co_occurrence_dict = {}
# 遍历共现矩阵中每个单元格,并将词组搭配及其出现次数存储到字典中
for i in range(df.shape[0]):
for j in range(df.shape[1]):
# 获取当前单元格的值
count = df.iloc[i, j]
# 只处理 count 列不等于 0 的单元格
if count != 0:
# 获取当前单元格所对应的行和列的单词
word1 = df.index[i]
word2 = df.columns[j]
# 构造词组搭配
collocation = (word1, word2)
# 更新字典中的词组搭配及其出现次数
if collocation in co_occurrence_dict:
co_occurrence_dict[collocation] += count
else:
co_occurrence_dict[collocation] = count
# 将词组搭配及其出现次数转换为 DataFrame 类型
result = pd.DataFrame([(collocation[0], collocation[1], count) for collocation, count in co_occurrence_dict.items()], columns=["Word1", "Word2", "Count"])
- 创建一个空字典
co_occurrence_dict
,用于存储词组搭配及其出现次数。 - 使用两个嵌套的循环遍历共现矩阵中的每个单元格。外层循环遍历行,内层循环遍历列。
- 获取当前单元格的值,即共现次数。
- 如果共现次数不等于0,说明存在共现关系。
- 获取当前单元格所对应的行和列的单词。
- 组合行和列的单词,构造词组搭配。
- 更新字典
co_occurrence_dict
中的词组搭配及其出现次数。如果词组搭配已经在字典中存在,则将共现次数累加上去;否则,在字典中新增该词组搭配及其出现次数。 - 将字典
co_occurrence_dict
中的词组搭配及其出现次数转换为DataFrame类型,存储在result
变量中。DataFrame的列名分别为"Word1"、"Word2"和"Count",对应词组搭配的第一个单词、第二个单词和共现次数。