Python常用功能函数系列总结(五)
本节目录
常用函数一:向量距离和相似度计算
常用函数二:pagerank
常用函数三:TF-IDF
常用函数四:关键词提取
常用函数一:向量距离和相似度计算
- KL距离、JS距离、余弦距离
# -*- coding: utf-8 -*- """
@Datetime: 2019/3/30
@Author: Zhang Yafei
"""
import numpy as np
import pandas as pd
import scipy.stats
from scipy.stats import norm
from sklearn.metrics.pairwise import cosine_distances p = np.asarray([0.65, 0.25, 0.07, 0.03])
q = np.array([0.6, 0.25, 0.1, 0.05])
q2 = np.array([0.1, 0.2, 0.3, 0.4]) def KL_divergence(p, q):
"""
有时也称为相对熵,KL距离。对于两个概率分布P、Q,二者越相似,KL散度越小。
KL散度满足非负性
KL散度是不对称的,交换P、Q的位置将得到不同结果。
:param p:
:param q:
:return:
"""
return scipy.stats.entropy(p, q) def JS_divergence(p, q):
"""
JS散度基于KL散度,同样是二者越相似,JS散度越小。
JS散度的取值范围在0-1之间,完全相同时为0
JS散度是对称的
:param p:
:param q:
:return:
"""
M = (p + q) / 2
return 0.5 * scipy.stats.entropy(p, M) + 0.5 * scipy.stats.entropy(q, M) # 1000个均值170,标准差10的正态分布身高样本
h_real = norm.rvs(loc=170, scale=10, size=1000)
h_predict1 = norm.rvs(loc=168, scale=9, size=1000)
h_predict2 = norm.rvs(loc=160, scale=20, size=1000) def JS_div(arr1, arr2, num_bins):
max0 = max(np.max(arr1), np.max(arr2))
min0 = min(np.min(arr1), np.min(arr2))
bins = np.linspace(min0 - 1e-4, max0 - 1e-4, num=num_bins)
PDF1 = pd.cut(arr1, bins).value_counts() / len(arr1)
PDF2 = pd.cut(arr2, bins).value_counts() / len(arr2)
return JS_divergence(PDF1.values, PDF2.values) def cos_distance(p, q):
"""
余弦距离
@param p:
@param q:
@return:
"""
res = cosine_distances(np.array([p, q]))
return res[0][1] if __name__ == '__main__':
print(KL_divergence(p, q)) # 0.011735745199107783
print(KL_divergence(q, p)) # 0.013183150978050884
print(KL_divergence(p, q2)) # 1.092879181568733
print(JS_divergence(p, q)) # 0.003093977084273652
print(JS_divergence(p, q2)) # 0.24719159952098618
print(JS_divergence(p, p)) # 0.0
print(JS_div(h_real, h_predict1, num_bins=20)) # 0.011333885999505239
print(JS_div(h_real, h_predict2, num_bins=20)) # 0.14933522936149402
print(cos_distance(p, q))
余弦相似度
# -*- coding: utf-8 -*- """
@Datetime: 2019/3/28
@Author: Zhang Yafei
"""
# 余弦计算相似度度量 http://blog.csdn.net/u012160689/article/details/15341303
import functools
import math
import re
import time
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity text1 = "This game is one of the very best. games ive played. the ;pictures? " \
"cant descripe the real graphics in the game."
text2 = "this game have/ is3 one of the very best. games ive played. the ;pictures? " \
"cant descriPe now the real graphics in the game."
text3 = "So in the picture i saw a nice size detailed metal puzzle. Eager to try since I enjoy 3d wood puzzles, i ordered it. Well to my disappointment I got in the mail a small square about 4 inches around. And to add more disappointment when I built it it was smaller than the palm of my hand. For the price it should of been much much larger. Don't be fooled. It's only worth $5.00.Update 4/15/2013I have bought and completed 13 of these MODELS from A.C. Moore for $5.99 a piece, so i stand by my comment that thiss one is overpriced. It was still fun to build just like all the others from the maker of this brand.Just be warned, They are small."
text4 = "I love it when an author can bring you into their made up world and make you feel like a friend, confidant, or family. Having a special child of my own I could relate to the teacher and her madcap class. I've also spent time in similar classrooms and enjoyed the uniqueness of each and every child. Her story drew me into their world and had me laughing so hard my family thought I had lost my mind, so I shared the passage so they could laugh with me. Read this book if you enjoy a book with strong women, you won't regret it." def timeit(func):
@functools.wraps(func)
def wrap(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
print('运行时间为: {0:.4f}' .format(time.time() - start))
return res return wrap def preprocess(text):
"""
文本预处理,可根据具体情况书写逻辑
:param text:
:return:
"""
return text.split() @timeit
def compute_cosine(words1, words2):
"""
计算两段文本的余弦相似度
:param text_a:
:param text_b:
:return:
"""
# 1. 统计词频
words1_dict = {}
words2_dict = {} for word in words1:
word = re.sub('[^a-zA-Z]', '', word).lower()
if word != '' and word in words1_dict:
words1_dict[word] += 1
elif word != '':
words1_dict[word] = 1
else:
continue
for word in words2:
word = re.sub('[^a-zA-Z]', '', word).lower()
if word != '' and word in words2_dict:
words2_dict[word] += 1
elif word != '':
words2_dict[word] = 1
else:
continue # 2. 按照频率排序
dic1 = sorted(words1_dict.items(), key=lambda x: x[1], reverse=True)
dic2 = sorted(words2_dict.items(), key=lambda x: x[1], reverse=True) # 3. 得到词向量
words_key = []
list(map(lambda x: words_key.append(x[0]), dic1))
list(map(lambda x: words_key.append(x[0]), filter(lambda x: x[0] not in words_key, dic2))) vect1 = []
vect2 = []
for word in words_key:
if word in words1_dict:
vect1.append(words1_dict[word])
else:
vect1.append(0)
if word in words2_dict:
vect2.append(words2_dict[word])
else:
vect2.append(0) # 4. 计算余弦相似度
print(cosin_sim(vect1, vect2))
print(cosin_sim2(vect1, vect2))
result = cosine_sim3(vect1, vect2) return result def cosin_sim(vector1, vector2):
"""
K(X, Y) = <X, Y> / (||X||*||Y||)
:param vector1:
:param vector2:
:return:
"""
dot_product = normA = normB = 0.0
for a, b in zip(vector1, vector2):
dot_product += a * b
normA += a ** 2
normB += b ** 2
if normA == 0.0 or normB == 0.0:
return 0.0
else:
return dot_product / ((normA * normB) ** 0.5) def cosin_sim2(vec1, vec2):
user_tag_matric = np.matrix(np.array([vec1, vec2]))
user_similarity = cosine_similarity(user_tag_matric)
return user_similarity[0][1] def cosine_sim3(vec1, vec2):
"""
@param vec1:
@param vec2:
@return:
"""
sum = sq1 = sq2 = 0
for i in range(len(vec1)):
sum += vec1[i] * vec2[i]
sq1 += pow(vec1[i], 2)
sq2 += pow(vec2[i], 2)
try:
result = float(sum) / (math.sqrt(sq1) * math.sqrt(sq2))
except ZeroDivisionError:
result = 0.0
return result if __name__ == '__main__':
text1 = preprocess(text1)
text2 = preprocess(text2)
print(compute_cosine(text1, text2))
- 余弦相似度(矩阵计算)
# -*- coding: utf-8 -*- """
Datetime: 2020/07/19
author: Zhang Yafei
description: 余弦相似度
"""
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity def matrix_cos_sim_clac(file, columns=None, drop_columns=None, to_file='result.xlsx'):
"""
计算矩阵相似度 数据源格式:文件 多列 每列代表一个向量
:param file 读取文件路径 支持excel格式
:param columns 选取的列
:param drop_columns 排除的列
:param to_file 保存的文件路径
"""
data = pd.read_excel(file)
if columns:
data = data[columns]
elif drop_columns:
data.drop(columns=drop_columns, inplace=True)
columns = data.columns
data_matrix = data.values.T cos_matrix = cosine_similarity(X=data_matrix)
cos_sim_df = pd.DataFrame(data=cos_matrix, columns=columns, index=columns)
cos_sim_df.to_excel(to_file)
print('计算成功') if __name__ == "__main__":
matrix_cos_sim_clac(file='data/entity_2020_01_04.xlsx', drop_columns=['Id', 'Label'], to_file='cis_sim_data.xlsx')
常用函数二:pagerank
# encoding=utf-8 """
@Datetime: 2019/3/27
@Author: Zhang Yafei
@Description: pagerank值计算
""" import traceback
import warnings import numpy as np
from sklearn.metrics.pairwise import cosine_similarity warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim') from gensim.models.doc2vec import Doc2Vec class PageRank(object):
""" 计算pagerank """ def __init__(self, X):
self.X = X # 转移矩阵
self.pr = None
self.move_matrix = np.zeros((X.shape), dtype=np.float) # 转移矩阵初始化
self.pagerank = np.zeros((X.shape[0], 1), dtype=np.float) # pr值的矩阵初始化 def graph_move(self):
"""
构造转移矩阵
0≤ w[i][j] ≤1
np.sum(w[j]) = 1
:param a:
:return:
"""
X = np.where(abs(self.X) >= 0.4, self.X, 0)
X_t = np.transpose(X) # b为a的转置矩阵
bcol = [X_t[j].sum() for j in range(X.shape[1])] #归一化
# bcol = [np.where(X_t[j]>0, 1, 0).sum() for j in range(X.shape[1])] # 存在相似度的度数
for i in range(X.shape[0]):
for j in range(X.shape[1]):
self.move_matrix[i][j] = X[i][j] / bcol[j] # 完成转移矩阵初始化 def first_pr(self):
"""
pr值初始化
:param c:
:return:
"""
for i in range(self.X.shape[0]):
self.pagerank[i] = float(1) / self.X.shape[0] def compute_pagerank(self, p, iter_num=100):
"""
迭代计算pagerank值
:param p:
:param move_matrix: 转移矩阵
:param pr: 初始pr值
:param iter:
:return:
"""
for i in range(iter_num):
self.pagerank = np.dot(self.move_matrix, self.pagerank)
print('iteration {0}'.format(i))
# ===========================================================================
# i=1
# while ((v == dot(m, v)).all() == False): # 判断pr矩阵是否收敛,(v == p*dot(m,v) + (1-p)*v).all()判断前后的pr矩阵是否相等,若相等则停止循环
# # print v
# v = dot(m, v)
# #print((v == p*dot(m,v) + (1-p)*v).all())
# print(i)
# i+=1
# =========================================================================== def train(self, iter_num=100):
""" 训练模型 """
# 1. 计算转义矩阵
self.graph_move()
# print(self.move_matrix.shape) # (1585, 1585) # 2. pr值初始化
self.first_pr()
# print(self.pr.shape) # (1585, 1) # 3. 迭代更新pr值
p = 0.85 # 引入浏览当前网页的概率为p,假设p=0.8
self.compute_pagerank(p=p, iter_num=iter_num)
print(self.pagerank) @staticmethod
def save(fname, X, delimiter=',', fmt='%.18e'):
""" 将计算得到的矩阵保存到文件中 """
try:
np.savetxt(fname=fname, X=X, delimiter=delimiter, fmt=fmt)
print('保存到 {} 成功'.format(fname))
except Exception:
traceback.print_exc() def compute_cosine_similarity(model):
""" 计算doc2vec文档词向量的余弦相似度 """ # 1. 计算文档词矩阵
size_document = len(model.docvecs.vectors_docs)
doc_words_matrix = np.zeros((size_document, 10), dtype=np.float)
for i, vector in enumerate(model.docvecs.vectors_docs):
doc_words_matrix[i] = vector # 2. 计算文档词矩阵的余弦相似度矩阵
cosine_a_matrix = cosine_similarity(doc_words_matrix)
# print(cosine_a_matrix.shape) # (1585, 1585) return cosine_a_matrix if __name__ == '__main__':
# 1. 加载doc2vec文档词向量
doc2vec_model = Doc2Vec.load("results_data/all_model_titles")
# print(len(model.docvecs.vectors_docs)) # 1585 # 2. 计算文档词向量的余弦相似度矩阵
cosine_a_matrix = compute_cosine_similarity(model=doc2vec_model)
# np.savetxt('results_data/cosine_a_matrix.csv', cosine_a_matrix, delimiter=',', fmt='%.2f')
# print(cosine_a_matrix)
# 3. 计算文档的pagerank值
model = PageRank(X=cosine_a_matrix)
model.train()
model.save(fname='results_data/move_matrix.csv', X=model.move_matrix, fmt='%.8f')
model.save(fname='results_data/pagerank_titles.csv', X=model.pagerank, fmt='%.8f')
# import math # with open('results_data/pagerank_titles.csv') as f:
# for line in f:
# print(line.strip())
# print(math.exp(-float(line.strip())))
常用函数三:TF-IDF
# -*- coding: utf-8 -*- """
@Datetime: 2019/3/28
@Author: Zhang Yafei
""" # ################################# nltk计算tfidf ####################################333 def nltk_tfidf():
import nltk
from nltk.text import TextCollection
sents = ['this is sentence one', 'this is sentence two', 'this is sentence three']
sents = [nltk.word_tokenize(sent) for sent in sents]
corpus = TextCollection(sents)
# 直接就能算出tfidf
# (term: ⼀句话中的某个term, text: 这句话)
print(corpus.idf('four'))
print(corpus.tf('four', nltk.word_tokenize('this is a sentence four')))
print(corpus.tf_idf('four', nltk.word_tokenize('this is a sentence four'))) # ################################# sklearn计算tfidf ####################################333
def sklearn_count_tfidf():
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer corpus = ["我 来到 北京 清华大学", # 第一类文本切词后的结果,词之间以空格隔开
"他 来到 了 网易 杭研 大厦", # 第二类文本的切词结果
"小明 硕士 毕业 与 中国 科学院", # 第三类文本的切词结果
"我 爱 北京 天安门"] # 第四类文本的切词结果
vectorizer = CountVectorizer() # 该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
count_corpus = vectorizer.fit_transform(corpus) print(count_corpus) vectorizer2 = TfidfVectorizer() # 该类会统计每个词语的tf-idf权值
tfidf_corpus = vectorizer2.fit_transform(corpus) print(tfidf_corpus) word = vectorizer2.get_feature_names() # 获取词袋模型中的所有词语 weight = tfidf_corpus.toarray() # 将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重 for i in range(len(weight)): # 打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重
print("-------这里输出第", i, "类文本的词语tf-idf权重------")
for j in range(len(word)):
print(word[j], weight[i][j])
print(weight) # ################################# gensim计算tfidf ####################################333
def gensim_tdidf():
import warnings warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim') from gensim import corpora, models, similarities
corpus = ["我 来到 北京 清华大学", # 第一类文本切词后的结果,词之间以空格隔开
"他 来到 了 网易 杭研 大厦", # 第二类文本的切词结果
"小明 硕士 毕业 与 中国 科学院", # 第三类文本的切词结果
"我 爱 北京 天安门"] # 第四类文本的切词结果
texts = [[word for word in text.split()] for text in corpus] dictionary = corpora.Dictionary(texts)
print(dictionary)
# 9、对语料库进一步处理,得到新语料库
corpus = [dictionary.doc2bow(text) for text in texts]
print(corpus)
# 10、将新语料库通过tf-idf model 进行处理,得到tfidf
tfidf = models.TfidfModel(corpus)
for vec in tfidf[corpus]:
print(vec)
# 8、将要对比的文档通过doc2bow转化为稀疏向量
data3 = "基本思路 我 爱 北京 天安门"
new_xs = dictionary.doc2bow(data3.split())
print(new_xs) featurenum = len(dictionary.token2id.keys()) # #12、稀疏矩阵相似度,从而建立索引
index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=featurenum)
# #13、得到最终相似结果
sim = index[tfidf[new_xs]]
print(sim)
常用函数四:关键词提取
# -*- coding: utf-8 -*- """
Datetime: 2020/07/26
Author: Zhang Yafei
Description: 文本关键词抽取
"""
from jieba.analyse import extract_tags, textrank, set_stop_words, set_idf_path
from pandas import read_csv, read_excel, read_table, DataFrame, Series
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np class KeywordsExtract(object):
def __init__(self, file, text_col, new_col, stopwords_file_path=None, idf_path=None):
self.data = self.read_file(file)
self.text_col = text_col
self.new_col = new_col
if stopwords_file_path:
set_stop_words(stop_words_path=stopwords_file_path)
if idf_path:
set_idf_path(idf_path=idf_path) @staticmethod
def read_file(file):
if file.endswith('csv'):
return read_csv(file)
elif file.endswith('xls') or file.endswith('xlsx'):
return read_excel(file)
elif file.endswith('tsv'):
return read_table(file) @staticmethod
def func_tfidf(row):
keywords = extract_tags(row, topK=20, allowPOS=('n', 'nr', 'ns'))
return '; '.join(keywords) @staticmethod
def func_textrank(row):
keywords = textrank(row, topK=20, allowPOS=('n', 'nr', 'ns'))
return '; '.join(keywords) def extract_keywords_with_tfidf(self, path):
""" jieba tfidf关键词抽取 """
self.data[self.text_col].apply(self.func_tfidf)
self.to_file(self.data, path) def extract_keyword_with_textrank(self, path):
""" jieba textrank关键词抽取 """
self.data[self.new_col] = self.data[self.text_col].apply(self.func_textrank)
self.to_file(self.data, path) def tfidf_keywords_extract(self, path):
""" sklearn tfidf关键词抽取 """
documents = self.data[self.text_col]
vectorizer = TfidfVectorizer()
# vectorizer = TfidfVectorizer(token_pattern=r'(?u)\b\w+\b') # 匹配单个字符
corpus = vectorizer.fit_transform(documents).toarray()
vocabs = vectorizer.get_feature_names()
words_list = []
for index, doc in enumerate(corpus):
# words = '; '.join(np.array(vocabs)[np.argsort(-doc)[:15]])
words = '; '.join(np.array(vocabs)[np.where(doc > 0.2)])
words_list.append(words)
self.data[self.new_col] = Series(words_list)
self.to_file(self.data, path) @staticmethod
def to_file(df: DataFrame, path):
if path.endswith('csv'):
return df.to_csv(path, index=False, encoding='utf_8_sig')
elif path.endswith('xls') or file.endswith('xlsx'):
return df.to_excel(path, index=False)
elif path.endswith('tsv'):
return df.to_csv(path, sep='\t', index=False) if __name__ == '__main__':
key_extract = KeywordsExtract(file='data.xlsx', text_col='摘要', new_col='TFID关键词')
# key_extract.extract_keywords_with_tfidf()
# key_extract.extract_keyword_with_textrank()
key_extract.tfidf_keywords_extract()
Python常用功能函数系列总结(五)的更多相关文章
- Python常用功能函数系列总结(一)
本节目录 常用函数一:获取指定文件夹内所有文件 常用函数二:文件合并 常用函数三:将文件按时间划分 常用函数四:数据去重 写在前面 写代码也有很长时间了,总觉得应该做点什么有价值的事情,写代码初始阶段 ...
- Python常用功能函数系列总结(六)
本节目录 常用函数一:词云图 常用函数二:关键词清洗 常用函数三:中英文姓名转换 常用函数四:去除文本中的HTML标签和文本清洗 常用函数一:词云图 wordcloud # -*- coding: ...
- Python常用功能函数系列总结(二)
本节目录 常用函数一:sel文件转换 常用函数二:refwork文件转换 常用函数三:xml文档解析 常用函数四:文本分词 常用函数一:sel文件转换 sel是种特殊的文件格式,具体应用场景的话可以 ...
- Python常用功能函数系列总结(三)
本节目录 常用函数一:词频统计 常用函数二:word2vec 常用函数三:doc2vec 常用函数四:LDA主题分析 常用函数一:词频统计 # -*- coding: utf-8 -*- " ...
- Python常用功能函数系列总结(四)之数据库操作
本节目录 常用函数一:redis操作 常用函数二:mongodb操作 常用函数三:数据库连接池操作 常用函数四:pandas连接数据库 常用函数五:异步连接数据库 常用函数一:redis操作 # -* ...
- Python常用功能函数系列总结(七)
本节目录 常用函数一:批量文件重命名 常用函数一:批量文件重命名 # -*- coding: utf-8 -*- """ DateTime : 2021/02/08 10 ...
- Python常用功能函数总结系列
Python常用功能函数系列总结(一) 常用函数一:获取指定文件夹内所有文件 常用函数二:文件合并 常用函数三:将文件按时间划分 常用函数四:数据去重 Python常用功能函数系列总结(二) 常用函数 ...
- Python常用功能函数
Python常用功能函数汇总 1.按行写字符串到文件中 import sys, os, time, json def saveContext(filename,*name): format = '^' ...
- Python 常用string函数
Python 常用string函数 字符串中字符大小写的变换 1. str.lower() //小写>>> 'SkatE'.lower()'skate' 2. str.upper ...
随机推荐
- Linkerd Service Mesh 授权策略(Server & ServerAuthorization)
简介 Server 和 ServerAuthorization 是 Linkerd 中的两种策略资源, 用于控制对 mesh 应用程序的入站访问. 在 linkerd 安装期间,policyContr ...
- Mysql资料 mysqldump
目录 一.简介 备份过程 优缺点 命令使用 myisam引擎 二.安装 配置 日志 三.日常使用 备份全库 备份单个库(带建立库的语句) 备份单个库(不自动建立库) 备份表合集 从全备中恢复单个库 其 ...
- [BUUCTF]REVERSE——Java逆向解密
Java逆向解密 附件 步骤: 根据题目提示是java语言编写的程序,用jd-gui反编译一下 百度了一些java里的函数后读懂了这段程序的意思,将我们输入的字符串依次+'@',然后跟32异或,得到K ...
- [BUUCTF]PWN——ciscn_2019_ne_5
ciscn_2019_ne_5 题目附件 步骤: 例行检查,32位,开启了nx保护 试运行一下程序,看一下程序的大概执行情况 32位ida载入,shift+f12查看程序里的字符串,发现了flag字符 ...
- 替换错误Table.ReplaceErrorValues(Power Query 之 M 语言)
数据源: 任意数据源,数据中有错误值 目标: 将错误值替换为0 操作过程: [转换]>[替换值]>[替换错误] M公式: = Table.ReplaceErrorValues( 表, {{ ...
- CF688B Lovely Palindromes 题解
Content 输入一个数 \(n\),输出第 \(n\) 个偶数位回文数. 数据范围:\(1\leqslant n\leqslant 10^{10^5}\). Solution 一看这吓人的数据范围 ...
- CF1440A Buy the String 题解
Content 有 \(t\) 组询问,每组询问给出一个长度为 \(n\) 的 \(0/1\) 串,你可以花 \(h\) 的代价把 \(0\) 修改成 \(1\) 或者把 \(1\) 修改成 \(0\ ...
- RabbitMQ 消息队列 实现RPC 远程过程调用交互
#!/usr/bin/env python # Author:Zhangmingda import pika,time import uuid class FibonacciRpcClient(obj ...
- Mysql 主从复制机制
https://blog.csdn.net/girlgolden/article/details/89226528 MySQL异步复制及semi-sync半同步复制,它们都基于MySQL binlog ...
- Sort 多列正排序,倒排序
linux sort 多列正排序,倒排序 转自https://segmentfault.com/a/1190000005713784 发布于 2016-06-14 sort是在Linux里非常常用 ...