【BI学习心得11-资金流入流出预测】


1.正则表达式

对字符串(包括普通字符和特殊字符)操作的一种逻辑公式

  • 好处:可以迅速地用极简单的方式达到字符串的复杂操作
  • 坏处:要记住很多符号

应用:python中的re模块

import re

1.1re.match(pattern, string, flags=0)

尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none

pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等

import re
# 在起始位置匹配
print(re.match('www', 'www.baidu.com').span())
print(re.match('com', 'www.baidu.com'))

输出结果:
(0, 3)
None

1.2re.search(pattern, string, flags=0)

扫描整个字符串并返回第一个成功的匹配

pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等

search与match区别

  • re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,返回None
  • re.search匹配整个字符串,直到找到一个匹配
import re
#扫描整个字符串并返回第一个成功的匹配
print(re.search('www', 'www.baidu.com').span())
print(re.search('com', 'www.baidu.com').span())

输出结果:
(0, 3)
(10, 13)

1.3re.compile(pattern, flags=0)

将正则表达式模式编译为正则表达式对象,可使用match(),search()方法将其用于匹配

1.3.1匹配两个数字
prog = re.compile('\d{2}') 

下面两个作用是相同的

print(prog.search('12abc'))
print(re.search('\d{2}', '12abc'))

通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None

print(prog.search('12abc').group())
<re.Match object; span=(0, 2), match='12'>
12
<re.Match object; span=(0, 2), match='12'>

1.4re.sub(pattern, repl, string, count=0, flags=0)

用于替换字符串中的匹配项

pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。

1.5re.findall(pattern, string, flags=0)

返回string中所有与pattern相匹配的全部字串,返回形式为数组

phone = "001-609-7267 # ETS的TOEFL查询电话" 
# 删除字符串中的注释 
num = re.sub(r'#.*$', "", phone)
print("电话号码是: ", num)
# 删除非数字(-)的字符串 
num = re.sub(r'\D', "", phone)
print("电话号码是 : ", num)
电话号码是:  001-609-7267 
电话号码是 :  0016097267

2.常用正则符号

元字符匹配内容元字符匹配内容
.匹配除换行符以外的任意字符$匹配字符串的结尾
\w匹配字母或数字或下划线\W匹配非字母或数字或下划线
\s匹配任意的空白符\D匹配非数字
\d匹配数字\S匹配非空白符
\n匹配一个换行符a竖杆b匹配字符a或字符b
\t匹配一个制表符()匹配括号内的表达式,也表示一个组
\b匹配一个单词的结尾[…]匹配字符组中的字符
^匹配字符串的开始[^…]匹配除了字符组中字符的所有字符
量词用法说明符号匹配内容
*重复零次或更多次[\u4e00-\u9fa5]中文字符
+重复一次或更多次[^\x00-\xff]双字节字符(包括汉字在内)
重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

2.1 电话号码验证

  • 规则11位,首位为1,第二位不为0,1,2,4,9
  • 比如158 1234 5678
def is_phone(phone):
	# 电话号码正则对象
	prog = re.compile('^1[35678]\d{9}$') 
	result = prog.match(phone)
	if result:
		return True
	else:
		return False
print(is_phone('15801234567'))

2.2邮箱验证

  • @之前必须有内容且只能是字母、数字、下划线(_)、减号(-)、点(.)

  • @和最后一个点(.)之间必须有内容,可以是字母、数字、点(.)、减号(-),不能是下划线(_),且两个点不能挨着

  • 最后一个点(.)之后必须有内容,而且内容只能是字母(大小写)、数字且长度为大于等于2个字节,小于等于4个字节

比如 1580123@qq.com => True
1580123@qq => False

def is_email(email):
	# 邮箱正则对象
	prog = re.compile('^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,4}$') 
	result = prog.match(email)
	if result:
		return True
	else:
		return False
print(is_email("1580123@qq.com"))  #True
print(is_email("1580123@qq"))   #False
2.2.1邮箱验证实战

(希拉里邮件丑闻)数据集:https://github.com/cystanford/PageRank

数据集包括了9306封邮件和513个人名

Emails.csv:记录了所有公开邮件的内容,发送者和接受者的信息。 Persons.csv:统计了邮件中所有人物的姓名及对应的ID。
Aliases.csv:因为姓名存在别名的情况,为了将邮件中的人物进行统一,我们还需要用Aliases文件来查询别名和人物的对应关系。

目标:提取往来邮件中的内容,即针对Emails.csv中的ExtractedBodyText字段进行清洗(使用正则表达式)

# 希拉里邮件内容清洗
import numpy as np
import pandas as pd
import re
from gensim import corpora, models, similarities
import gensim
from nltk.corpus import stopwords
 
 
# 对邮件正文进行清洗
def clean_email_text(text):
    # 换行,可以删除
    text = text.replace('\n'," ") 
    # 把 "-" 的两个单词,分开。(比如:meet-the-right ==> meet the right)
    text = re.sub(r"-", " ", text) 
    # 日期,对主题模型没什么意义
    text = re.sub(r"\d+/\d+/\d+", "", text) 
    # 时间,没意义
    text = re.sub(r"[0-2]?[0-9]:[0-6][0-9]", "", text) 
    # 邮件地址,没意义
    text = re.sub(r"[\w]+@[\.\w]+", "", text) 
    # 网址,没意义
    text = re.sub(r"/[a-zA-Z]*[:\//\]*[A-Za-z0-9\-_]+\.+[A-Za-z0-9\.\/%&=\?\-_]+/i", "", text) 
    
    pure_text = ''
    # 检查每个字母,去掉其他特殊字符等
    for letter in text:
        # 只留下字母和空格
        if letter.isalpha() or letter==' ':
            pure_text += letter
    # 最终得到的都是有意义的单词
    text = ' '.join(word for word in pure_text.split() if len(word)>1)
    return text
 
# 数据加载
df = pd.read_csv("./Emails.csv")
# 原邮件数据中有很多Nan的值,直接扔了。
df = df[['Id', 'ExtractedBodyText']].dropna()

docs = df['ExtractedBodyText']
docs = docs.apply(lambda s: clean_email_text(s))
#print(docs)

# 转化为列表List
doclist = docs.values
print(doclist)
print(len(doclist))

3.分词与词性

3.1分词

NLTK库,对英文文本预处理
jieba库,对中文文本预处理

停用词(Stop Words):
需要自动过滤掉某些字或词

语料(Corpus):
一组原始文本的集合,用于无监督地训练文本

import jieba

text = '张飞和关羽'
words = jieba.cut(text)
words = list(words)
print(words)

输出结果:
['张飞', '和', '关羽']

在这里插入图片描述

3.2jieba库的使用

jieba分词的三种模式:

  1. 精确模式:把文本精确的切分开,不存在冗余单词
  2. 全模式:把文本中所有可能的词语都扫描出来,有冗余
  3. 搜索引擎模式:在精确模式基础上,对长词再次切分
函数描述
jieba.cut(s)精确模式,返回一个可迭代的数据类型
jieba.cut(s, cut_all=True)全模式,输出文本s中所有可能单词
jieba.cut_for_search(s)搜索引擎模式,适合搜索引擎建立索引的分词结果
jieba.lcut(s)精确模式,返回一个列表类型,建议使用
jieba.lcut(s, cut_all=True)全模式,返回一个列表类型,建议使用
jieba.lcut_for_search(s, cut_all=True)搜索引擎模式,返回一个列表类型,建议使用
jieba.add_word(w)向分词字典中增加新词
3.2.1jieba库使用

美国新冠肺炎确诊超57万,纽约州死亡人数过万。当地时间4月13日,世卫组织发布最新一期新冠肺炎每日疫情报告。截至欧洲中部时间4月13日10时(北京时间4月13日16时),全球确诊新冠肺炎1773084例(新增76498例),死亡111652例(新增5702例)。其中,疫情最为严重的欧洲区域已确诊913349例(新增33243例),死亡77419例(新增3183例)。

拿到文本以后,对句子进行分词需要进行以下步骤:
1)分词
2)获取每个单词的词性

add_word(word, freq=None, tag=None)
  • 添加word,后续不被切分
  • add_word只是一次性的添加分词字典,不是直接将内容添加到结巴库中了
del_word(word) # 删除word

完整代码

import jieba

text = '美国新冠肺炎确诊超57万,纽约州死亡人数过万。当地时间4月13日,世卫组织发布最新一期新冠肺炎每日疫情报告。截至欧洲中部时间4月13日10时(北京时间4月13日16时),全球确诊新冠肺炎1773084例(新增76498例),死亡111652例(新增5702例)。其中,疫情最为严重的欧洲区域已确诊913349例(新增33243例),死亡77419例(新增3183例)。'
jieba.add_word('新冠肺炎')
words = jieba.cut(text)
#words = jieba.cut(text)
words = list(words)
print(words)

4.TF-IDF计算

4.1TF-IDF是什么

TF:Term Frequency,词频

一个单词的重要性和它在文档中出现的次数呈正比

IDF:Inverse Document Frequency,逆向文档频率

一个单词在文档中的区分度。这个单词出现的文档数越少,区分度越大,IDF越大

TF-IDF作用:获得文档向量和提取文档关键词

4.2TF-IDF的使用

from sklearn.feature_extraction.text import CountVectorizer,
TfidfVectorizer, TfidfTransformer

  • CountVectorizer,只考虑词汇在文本中出现的频率

  • TfidfTransformer,统计CountVectorizer中每个词语的tf-idf权值。除了考量某词汇在文本出现的频率,还关注包含这个词汇的所有文本的数量

  • TfidfVectorizer,把CountVectorizer, TfidfTransformer合并起来,直接生成tfidf值

常用函数:

  • get_feature_names(), 得到所有文本的关键字
  • fit_transform(), 训练并且转换

4.3Gensim工具

一款开源的第三方Python工具包,用于从原始的非结构化的文本中,无监督地学习到文本隐层的主题向量表达

corpora

  • gensim中的一个基本概念,是文档集的表现形式。
  • corpora本质上是个二维矩阵,但在实际运行中,因为单词数量极多(上万甚至更多),而一篇文档的单词数是有限的,所以gensim内部是用稀疏矩阵的形式来表示的

TF-IDF生成步骤:
Step1, 生成字典

dictionary = corpora.Dictionary(train)

Step2, 生成语料

corpus = [dictionary.doc2bow(text) for text in train]

Step3, 定义TFIDF模型

tfidf_model = models.TfidfModel(corpus, dictionary=dictionary)

Step4, 生成TFIDF矩阵

corpus_tfidf = tfidf_model[corpus]

5.TextRank算法

线性约束系统在自然数集上的兼容性。 考虑了线性丢番图方程组,严格不等式和非严格不等式的相容性准则。 给出了针对所有类型系统的最小解集的组成部分的上限以及构造最小解集的构建算法。 这些标准和用于构造解决方案的最小支持集的相应算法可用于求解所有考虑的类型系统和混合类型的系统。
在这里插入图片描述

5.1TextRank流程

Step1,进行分词和词性标注,将单词添加到图中

Step2,出现在一个窗口中的词形成一条边

Step3,基于PageRank原理进行迭代(20-30次)

Step4,顶点(词)按照分数进行排序,可以筛选指定的词性

5.2jieba中使用TextRank提取关键词

jieba.analyse.textrank(string, topK=20, withWeight=True, allowPOS=())

  • string:待处理语句

  • topK:输出topK个词,默认20

-withWeight:是否返回权重值,默认false

  • allowPOS:是否仅返回指定类型,默认为空

5.3jieba中使用TF-IDF提取关键词

jieba.analyse.extract_tags(sentence, topK=20, withWeight=True,
allowPOS=())

  • 效果好于TextRank,考虑了IDF的情况,而TextRank倾向使用频繁词

  • 效率高于TextRank,TextRank基于图的计算和迭代较慢

5.4textrank4zh工具

TextRank除了可以找到关键词,还可以生成摘要(关键句子)

依赖分词,分词提取结果及TextRank结果与jieba存在差异

#-*- encoding:utf-8 -*-
from textrank4zh import TextRank4Keyword, TextRank4Sentence
import jieba

text = '王者荣耀典韦连招是使用一技能+大招+晕眩+二技能+普攻。这套连招主要用于先手强开团,当发现对面走位失误或撤退不及时,我们就可以利用一技能的加速。此外配合大招减速留住对手,协同队友完成击杀。\
当对方站位较集中时,我们同样可以利用“一技能+大招+晕眩”进行团控和吸收伤害。\
在吸收伤害的同时我们还可以利二技能打出不错的输出。这套连招重要的是把握时机,要有一夫当关,万夫莫开之势。\
缺点是一技能的强化普攻和解除控制的效果会被浪费。\
连招二:大招+晕眩+二技能+普攻+一技能+普攻。\
这套连招用于偷袭对手后排很是好用,利用草丛埋伏。\
大招跳到对面身上。迅速晕眩对手,接着二技能继续减速对手,二技能命中后会提升典韦到极限攻速,这时不断普攻,接下来一般会遇到两种情况,当对手继续逃跑时,我们利用一技能加速追击对手,强化普攻击杀对手。\
当对手用技能控住我们我们可以利用一技能解除控制,追击并完成击杀。'

# 输出关键词,设置文本小写,窗口为2
tr4w = TextRank4Keyword()
tr4w.analyze(text=text, lower=True, window=3)
print('关键词:')
for item in tr4w.get_keywords(20, word_min_len=2):
    print(item.word, item.weight)


# 输出重要的句子
tr4s = TextRank4Sentence()
tr4s.analyze(text=text, lower=True, source = 'all_filters')
print('摘要:')
# 重要性较高的三个句子
for item in tr4s.get_key_sentences(num=3):
	# index是语句在文本中位置,weight表示权重
    print(item.index, item.weight, item.sentence)

5.5使用snownlp库分词

from snownlp import SnowNLP

text = '王者荣耀典韦连招是使用一技能+大招+晕眩+二技能+普攻,这套连招主要用于先手强开团,当发现对面走位失误或撤退不及时,我们就可以利用一技能的加速,配合大招减速留住对手,协同队友完成击杀。\
当对方站位较集中时,我们同样可以利用“一技能+大招+晕眩”进行团控和吸收伤害。\
在吸收伤害的同时我们还可以利二技能打出不错的输出。这套连招重要的是把握时机,要有一夫当关,万夫莫开之势。\
缺点是一技能的强化普攻和解除控制的效果会被浪费。\
连招二:大招+晕眩+二技能+普攻+一技能+普攻。\
这套连招用于偷袭对手后排很是好用,利用草丛埋伏。\
大招跳到对面身上。迅速晕眩对手,接着二技能继续减速对手,二技能命中后会提升典韦到极限攻速,这时不断普攻,接下来一般会遇到两种情况,当对手继续逃跑时,我们利用一技能加速追击对手,强化普攻击杀对手。\
当对手用技能控住我们我们可以利用一技能解除控制,追击并完成击杀。'
snow = SnowNLP(text)
# 打印关键词
print(snow.keywords(20))

# TextRank算法
print(snow.summary(3))
print(snow.sentiments)

5.6使用jieba库分词

# -*- coding: utf-8 -*-
import jieba
import jieba.analyse
import jieba.posseg as pseg

sentence = '王者荣耀典韦连招是使用一技能+大招+晕眩+二技能+普攻,这套连招主要用于先手强开团,当发现对面走位失误或撤退不及时,我们就可以利用一技能的加速,配合大招减速留住对手,协同队友完成击杀。当对方站位较集中时,我们同样可以利用“一技能+大招+晕眩”进行团控和吸收伤害。在吸收伤害的同时我们还可以利二技能打出不错的输出。这套连招重要的是把握时机,要有一夫当关,万夫莫开之势。缺点是一技能的强化普攻和解除控制的效果会被浪费。'
# 获取分词
seg_list = jieba.cut(sentence, cut_all=False)
print(' '.join(seg_list))
# 获取分词和词性
words = pseg.cut(sentence)
for word, flag in words:
	print('%s, %s' % (word, flag))


# 通过TF-IDF获取关键词
keywords = jieba.analyse.extract_tags(sentence, topK=20, withWeight=True, allowPOS=('n','nr','ns'))
for item in keywords:
    print(item[0],item[1])
print('-'*100)

# 基于TextRank算法的关键词抽取
#keywords = jieba.analyse.extract_tags(sentence, topK=20, withWeight=True, allowPOS=('n','nr','ns'))
#keywords = jieba.analyse.textrank(sentence, topK=20, withWeight=True, allowPOS=('ns', 'n', 'vn', 'v')) 
#keywords = jieba.analyse.textrank(sentence, topK=20, withWeight=True, allowPOS=('n', 'ns')) 
keywords = jieba.analyse.textrank(sentence, topK=20, withWeight=True) 
print(keywords)
for item in keywords:
    print(item[0],item[1])
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水花

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值