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 ...
随机推荐
- python初探——pandas使用
一.简介 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的.Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具.pandas提供了大量 ...
- Salesforce LWC学习(三十七) Promise解决progress-indicator的小问题
本篇参考:https://developer.salesforce.com/docs/component-library/bundle/lightning-progress-indicator/exa ...
- IOS 真机调试和发布相关证书
一.成员介绍1. Certification(证书)证书是对电脑开发资格的认证,每个开发者帐号有一套,分为两种:1) Developer Certification(开发证书)安装在电脑上 ...
- 小迪安全 Web安全 基础入门 - 第八天 - 信息打点-系统篇&端口扫描&CDN服务&负载均衡&WAF防火墙
一.获取网络信息-服务厂商&网络架构 1.通过whois查询获取. 2.nmap.goby等扫描工具扫描获取. 3.https://www.netcraft.com/等网站查询获取. 二.服务 ...
- response 返回js的alert()语句,中文乱码如何解决
response 返回js的alert()语句,中文乱码如何解决, 步骤1:在后台加上如下代码: response.setCharacterEncoding("utf-8"); r ...
- Windows系统CMD命令bat脚本编写
复制文件(/y 表示不提示确认框,/-y 表示提示是否覆盖确认) echo "复制文件" copy /y D:\apache-zookeeper-3.6.3.tar.gz E:\l ...
- JAVA调用WebService接口(以调用第三方天气接口为例)
天气接口地址:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl 1.打开项目文件目录路径文件夹,在当前文件夹打开cmd, ...
- cmake之引入外部项目(引用其他项目)、FetchContent管理子模块(fetchcontent用法)
本文CMAKE版本为3.18 演示环境: Windows+CMake+VS2017 源码下载说明 演示代码是后来传上去的,而且做了些修改,将spdlog_demo由exe改为了lib,但是,spdlo ...
- 【LeetCode】136. Single Number 解题报告(Java & Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 异或 字典 日期 [LeetCode] 题目地址:h ...
- 【LeetCode】122.Best Time to Buy and Sell Stock II 解题报告(Java & Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...