4.3 文本的特征提取_第1页
4.3 文本的特征提取_第2页
4.3 文本的特征提取_第3页
4.3 文本的特征提取_第4页
4.3 文本的特征提取_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

大数据技术在会计与财务中的应用作者:张敏等2026/9/7《大数据技术在会计与财务中的应用》配套课件第4章·4.3文本的特征提取目录4.3.1正则表达式4.3.2文本常见指标的计算4.3文本的特征提取4.3文本的特征提取|02/30想要了解一段文本的具体含义,必须首先读懂一段文本。然而,计算机是无法直接理解人类语言的——计算机只能识别“0”和“1”的区别。因此,我们需要将文本的特征抽象为数学表达,然后将这些数学表达输入到模型中供计算机处理。作为商科学生,我们不需要掌握这些计算机底层知识,本节主要介绍如何使用词典法计算一段文本的词和句子的数量,判断文本的情感和语气,以及分析一段文本的复杂度。这些基础性的工作虽然简单直接,但也是将非结构化文本数据转换为数值化特征的过程,是构建复杂的文本分析变量的基础。4.3文本的特征提取4.3文本的特征提取|03/304.3.1正则表达式正则表达式(RegularExpression或Regex)是一系列定义文本搜索模式的字符序列。正则表达式在各种文本处理任务中非常有用,包括识别特定的单词、短语、实体名称、数字、文本中的URL链接,将文本分割成句子,将句子进行分类等等。具体到学术研究领域,我们可以使用正则表达式在文档中识别正面和负面的词汇,然后计算其语调;将文档中的句子分类为前瞻性或与风险相关的句子;或者根据某些条件将文档区分为不同的类别。4.3文本的特征提取|04/304.3.1正则表达式正则表达式的发明者是斯蒂芬·科尔·克莱尼,他是是一名美国数学家、逻辑学家,主要从事对可计算函数的研究,而他的递归理论研究有助于奠定理论计算机科学的基础而真正将正则表达式引入编辑器和编程领域的是肯·汤普逊。在贝尔实验室工作期间,汤普逊设计和实现了Unix操作系统。他创造了B语言——C语言的前身,而且他是Plan9操作系统的创造者和开发者之一。2006年,汤普逊进入Google公司工作,与他人共同设计了Go语言。他与丹尼斯·里奇同为1983年图灵奖得主。4.3文本的特征提取|05/304.3.1正则表达式正则表达式中有一些特殊字符,它们具有特殊的含义,用于表示一些模式或操作。以下代码是的较为常见的正则表达式字符,读者可以直接查阅:.(点号):匹配除换行符\n外的任何字符。*(星号):匹配前面的元素零次或多次。+(加号):匹配前面的元素一次或多次。?(问号):匹配前面的元素零次或一次。[](字符集):匹配其中任意一个字符,例如[aeiou]匹配任何一个元音字母。|(管道符):表示或,匹配两个模式中的一个。()(括号):用于创建捕获组,也可以用于指定子表达式的范围。\(反斜杠):用于转义特殊字符,使其失去特殊含义,或者表示一些预定义的字符集,如\d表示数字。{}(花括号):用于指定前面元素的重复次数,例如{3}表示重复3次,{1,3}表示重复1到3次。4.3文本的特征提取|06/304.3.1正则表达式上述字符集用于匹配一个字符的集合。如果需要匹配一组字符,则需使用字符集。字符集使用方括号[]表示,可以包含一系列字符,其中任何一个字符都可以参与匹配。需要注意的是,匹配完成后,正则匹配光标就跳转到之后的文本了。例如,表达式[123]在匹配到数字1后,即停止寻找2和3,进入之后的匹配。以下是一些字符集的示例:单个字符集:[aeiou]:匹配任何一个元音字母。[123]:匹配数字1、2或3。

字符范围:[a-z]:匹配任何小写字母。[A-Z]:匹配任何大写字母。[0-9]:匹配任何数字。[a-zA-Z]:匹配任何字母。

字符集取反:[^aeiou]:匹配任何非元音字母。[^0-9]:匹配任何非数字字符。

预定义字符集:\d:匹配任何数字,相当于[0-9]。\D:匹配任何非数字字符,相当于[^0-9]。\w:匹配任何字母数字字符,相当于[a-zA-Z0-9_]。\W:匹配任何非字母数字字符,相当于[^a-zA-Z0-9_]。\s:匹配任何空白字符,包括空格、制表符、换行符等。\S:匹配任何非空白字符。4.3文本的特征提取|07/304.3.1正则表达式

4.3文本的特征提取|08/304.3.1正则表达式正则表达式相关函数在Python中,内置的re模块提供了正则表达式的常用函数,具体如下:pile(pattern):将正则表达式模式编译为一个正则表达式对象,可以用于匹配字符串的其他操作;

re.match(pattern,string):从字符串的起始位置匹配正则表达式模式,如果匹配成功,则返回一个Match对象,否则返回None(注意:即使字符串的起始位置不匹配,re.match()也会返回一个Match对象,但是它只会在字符串的起始位置匹配成功);

re.search(pattern,string):扫描字符串,在正则表达式模式首次匹配的位置停止;如果匹配成功,则输出一个Match对象,否则返回None;

re.findall(pattern,string):查找字符串中所有与正则表达式模式匹配的子字符串,并将它们作为列表返回;

re.finditer(pattern,string):查找字符串中所有与正则表达式模式匹配的子字符串,并将它们作为迭代器返回;

re.split(pattern,string):在正则表达式模式的每个匹配处拆分字符串,并返回一个字符串列表。例如,可以通过在空格处拆分句子来获取句子中的单词;

re.sub(pattern,repl,string):查找字符串中所有匹配正则表达式模式的部分,并用repl进行替换。正则表达式模式可以用单引号''或双引号""指定。4.3文本的特征提取|09/304.3.1正则表达式正则表达式模式可以使用单引号和双引号进行指定,分别是''和""。在Python的re操作中,向正则表达式模式添加字母“r”是一个常见的习惯(例如,re.search(r'pattern',string))。在模式前加上“r”表示反斜杠应该被视为字面字符,而不是在Python中作为转义字符处理。换句话说,前缀“r”表示该字符串是一个“原始字符串”(rawstring)。当反斜杠用于转义字符时,会被python和正则表达式引擎两次处理,因此在正则表达中表示两个“\”时,需要写成“\\\\”。而在带“r”的原始字符串中,只需要写成“\\”即可。4.3文本的特征提取|10/304.3.1正则表达式以下是正则表达式相关函数的简单代码示例:importre

pattern=pile(r'\b\w+\b')#pile(pattern,flags=0):用于编译正则表达式模式,返回一个正则表达式对象。这样可以提高匹配效率,特别是在需要多次匹配时。

4.3文本的特征提取|11/304.3.1正则表达式result1=re.match(r'\b\w+\b','HelloWorld')#re.match(pattern,string,flags=0):尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

result2=re.search(r'\b\w+\b','HelloWorld')#re.search(pattern,string,flags=0):扫描整个字符串并返回第一个成功的匹配,如果匹配失败,则返回none。

result3=re.findall(r'\b\w+\b','HelloWorld')#re.findall(pattern,string,flags=0):在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

result4=re.finditer(r'\b\w+\b','HelloWorld')#re.finditer(pattern,string,flags=0):和findall()函数相似,但返回的不是列表,而是一个迭代器,只能用于for循环中。

result5=re.split(r'\s+','HelloWorld')#re.split(pattern,string,maxsplit=0,flags=0):将一个字符串按照正则表达式匹配结果进行分割,返回列表类型。

result6=re.sub(r'\s+','-','HelloWorld')#re.sub(pattern,repl,string,count=0,flags=0):在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串。

print(result1)

print(result2)

print(result3)

print(result4)

print(result5)

print(result6)4.3文本的特征提取|12/304.3.1正则表达式输出结果如下:<re.Matchobject;span=(0,5),match='Hello'>

<re.Matchobject;span=(0,5),match='Hello'>

['Hello','World']

<callable_iteratorobjectat0x0000029B9A49B340>

['Hello','World']

Hello-World4.3文本的特征提取|13/304.3.1正则表达式在正则表达式中,使用分组可以将多个模式组合在一起,并对其进行操作。可以使用圆括号()来定义分组,其中包含的模式将作为一个整体进行匹配。分组提供了以下几个主要的功能:(1)限定范围:分组允许将模式组织在一起,并应用限定符(如*、+、?、{})来指定匹配次数。(2)捕获:可以使用分组将匹配的部分捕获到一个单独的组中,以后可以通过引用组来获取匹配的内容。(3)非捕获分组:在分组中添加?:可以创建非捕获分组,即匹配但不捕获结果。下面来看几个简单的例子:正则表达式r"TotalAssets=($[\d,.]+)\b"应用于字符串“TotalAssets=$10,000,000”将产生两个匹配:(1)完全匹配:‘TotalAssets=$10,000,000’(2)组匹配:‘$10,000,000’正则表达式r"Email:([\w.-]+@[\w.-]+.edu)"应用于字符串“Email:abc@ABC.edu”将产生两个匹配:(1)完全匹配:‘Email:abc@ABC.edu’(2)组匹配:‘abc@ABC.edu’我们还可以在同一正则表达式中引用先前的组匹配,这被称为反向引用(backreferencing)。我们需要在正则表达式中使用\n以引用第n组匹配的文本。例如,正则表达式r"\b(\w+)\s\1\b"将捕获文本中重复的单词(例如,“wewe”,“inin”,“aboveabove”等);这其中,\b(\w+)\s捕获一个单词后跟一个空格\s。\1后跟边界\b捕获第一个(且唯一的)组的结果。为方便寻找匹配到的组及提高可读性,我们可以使用语法(?P<name>pattern)给正则表达式组命名。4.3文本的特征提取|14/304.3.1正则表达式正则表达式的综合应用importre

#下述代码匹配一个数字后面跟着两个字母

pattern1=pile(r'\d{1,3}([a-zA-Z]{2})')

result1=pattern1.match('123ab')#调用match方法进行匹配

print(result1.group(1))#输出:ab

#在上述的例子中,元素\d{1,3}匹配一个包含1到3个数字的序列,元素([a-zA-Z]{2})匹配两个字母的序列,并使用括号将其分组,以便可以通过group(1)获取匹配的内容。

4.3文本的特征提取|15/304.3.1正则表达式

#下述代码匹配日期格式,捕获年、月、日

pattern2=pile(r'(\d{4})-(\d{2})-(\d{2})')

result2=pattern2.match('2026/9/7')#调用match方法进行匹配

print(result2.group(1))#输出:2023

print(result2.group(2))#输出:12

print(result2.group(3))#输出:10

#在上述的例子中,使用了三个分组,每个分组用于匹配年、月、日,并可以通过相应的group方法获取捕获的内容。

#下述代码匹配一个以"Mr."或"Ms."开头的名字

pattern3=pile(r'(?:Mr\.|Ms\.)(\w+)')

result3=pattern3.match('Mr.Smith')#调用match方法进行匹配

print(result3.group(1))#输出:Smith

#在上述的例子中,使用了非捕获分组(?:...)来匹配以"Mr."或"Ms."开头的名字,但只捕获名字部分,不捕获"Mr."或"Ms."。

#将小组命名为group1和group2,并取出group2

regex=r"\b(?P<word1>\w+)\s(?P<word2>to)\b"

#这是我们的测试文本

text="weweexpectthisthistrendtocontinue"

#调取group2,即tore.search(regex,text).group('word2')4.3文本的特征提取|16/304.3.1正则表达式零宽断言用于在匹配字符串的过程中,对字符串进行一些限定,例如规定匹配的字符串后面需要跟什么特定字符,以及匹配的字符串前面需要出现什么特定字符,但是不会将这些限定的字符串作为匹配结果的一部分。(1)(?=pattern)零宽正向先行断言(zero-widthpositivelookaheadassertion)(2)(?!pattern)零宽负向先行断言(zero-widthnegativelookaheadassertion)(3)(?<=pattern)零宽正向后行断言(zero-widthpositivelookbehindassertion)(4)(?<!pattern)零宽负向后行断言(zero-widthnegativelookbehindassertion)4.3文本的特征提取|17/304.3.1正则表达式下面我们用几个具体的例子来说明其用法,请参阅代码和注释:importre

str1="microsoft'searningsthisyearis12.4billion,upmorethaneightpercentfromlastyear'searningsof11.4billion."

#这里的?=是正向肯定预查,即ea后面跟着rning

regex=r"ea(?=rning)"

#这里的?!是正向否定预查,即ea后面不跟着rningregex2=r"ea(?!rning)"

#这里的?<=是反向肯定预查,即ea前面跟着\w

regex3=r"(?<=\w)ea"4.3文本的特征提取|18/304.3.1正则表达式

#这里的?<!是反向否定预查,即ea前面不跟着\w

regex4=r"(?<!\w)ea"

#我们使用了start()方法,返回匹配开始的位置索引,这里是第一个ea的位置

print(re.search(regex,str1).start())

#这是第二个ea的位置print(re.search(regex2,str1).start())

#这是第三个ea的位置

print(re.search(regex3,str1).start())

#这是第四个ea的位置

print(re.search(regex4,str1).start())4.3文本的特征提取|19/304.3.2文本中常见指标的计算1.计算句子和单词的数量单词和句子数量的计算是文本分析中最简单的任务之一。这是计算文本其他指标的基础。诸多文本分析方法都需要计算文本句子或者单词的数量。例如,在判断一段文字的正负面情绪时,需要对正负向词汇进行计数,有时我们还会利用文本中的单词和句子数量进行比例化,以计算正负语义的单词所占的比例。4.3文本的特征提取|20/304.3.2文本中常见指标的计算(1)计算单词数量。定义并调用相关函数以计算单词数量。#采用nltk的word_tokenize函数,可以将文本分割成单词,然后再统计单词的个数

importnltk

fromnltk.tokenizeimportword_tokenize

defcount_words_nltk(input_text:str):#把长文本分割成单词

words=word_tokenize(input_text)#这里是为了去掉标点符号

words=[wordforwordinwordsifword.isalpha()]#统计单词个数

word_count=len(words)

returnword_count

text="""Weacquireothercompaniesandintangibleassetsandmaynotrealizealltheeconomicbenefitfromthoseacquisitions,whichcouldcauseanimpairmentofgoodwillorintangibles.Wereviewouramortizableintangibleassetsforimpairmentwheneventsorchangesincircumstancesindicatethecarryingvaluemaynotberecoverable.Wetestgoodwillforimpairmentatleastannually.Factorsthatmaybeachangeincircumstances,indicatingthatthecarryingvalueofourgoodwilloramortizableintangibleassetsmaynotberecoverable,includeadeclineinourstockpriceandmarketcapitalization,reducedfuturecashflowestimates,andslowergrowthratesinindustrysegmentsinwhichweparticipate.Wemayberequiredtorecordasignificantchargeonourconsolidatedfinancialstatementsduringtheperiodinwhichanyimpairmentofourgoodwilloramortizableintangibleassetsisdetermined,negativelyaffectingourresultsofoperations."""

#调用我们自定义的函数

text_length=count_words_nltk(text)

#输出结果print(f"Numberofwordsintext:{text_length}")print(word_tokenize(text))4.3文本的特征提取|21/304.3.2文本中常见指标的计算(2)计算句子数量。我们可以调用自定义函数并计算该段文本的句子数量#直接调用nltk的sent_tokenize函数,则可以将文本分割成句子,然后再统计句子的个数

importnltk

fromnltk.tokenizeimportsent_tokenize

defcount_sentences_nltk(input_text:str):#把长文本分割成句子

sentences=sent_tokenize(input_text)#统计句子个数

sentence_count=len(sentences)#返回结果

returnsentence_count

#调用刚才自定义的函数

num_sentences=count_sentences_nltk(text)print(f"Numberofsentencesintext:{num_sentences}")4.3文本的特征提取|22/304.3.2文本中常见指标的计算2.情感分析文本的情感分析通常是指对文本的情感极性进行分析,即判断文本是正向情感还是负向情感。情感分析在商业领域有着广泛的应用,比如对用户评论的情感进行分析等。例如,Campbell和Shang(2022)通过基于词典法的模型,分析公司员工在Glassdoor上对雇主的评论的语气特征,来度量公司的违规风险。Jiang等(2019)构建了一个基于词典法的模型,利用10-K、10-Q以及电话会议的语料,度量公司管理层的情感基调,进而预测股票收益。4.3文本的特征提取|23/304.3.2文本中常见指标的计算让我们来看一个简单的例子:判断一段话是正向情感(positive)还是负向情感(negative)。(1)准备正则表达式。定义正则表达式便于后面的分析,这是此类分析的基础。importre

#这是一个txt文件,里面是积极的词语

positive_words_dict=r".\positive.txt"#这是一个txt文件,里面是消极的词语negative_words_dict=r".\negative.txt"

defcreate_dict_regex_list(dict_file:str):

withopen(dict_file,'r')asf:#每一个文件中的词语都是以换行符分隔的(打开演示),所以我们用splitlines()来把每一行分开

dict_terms=f.read().splitlines()

#为每个词语加上\b,然后用列表推导式生成一个正则表达式列表

dict_terms_regex=[pile(r'\b'+term+r'\b')fortermindict_terms]

#返回的是一个列表,列表中的每一个元素都是一个正则表达式s

returndict_terms_regex

4.3文本的特征提取|24/304.3.2文本中常见指标的计算#调用函数,得到正向词语的正则表达式列表

positive_words_regex=create_dict_regex_list(positive_words_dict)

#调用函数,得到负向词语的正则表达式列表

negative_words_regex=create_dict_regex_list(negative_words_dict)

#把这些正则表达式打印出来检查一下

print(positive_words_regex[0:5])print(negative_words_regex[0:5])4.3文本的特征提取|25/304.3.2文本中常见指标的计算(2)定义并调用函数。我们要定义一个情感分析函数,并用这个函数计算一段特定文本的正负向情感词汇的数量。defget_tone(str):

#以下代码用来找到str中的正向词语和负向词语,然后计算正向词语和负向词语的数量,最后计算tone

#找到str中所有正向词语的列表

positive_match=[re.findall(regex,str)forregexinpositive_words_regex]

#计算正向词语的数量

positive_match_count=sum([len(match)formatchinpositive_match])

#找到str中所有负向词语的列表

negative_match=[re.findall(regex,str)forregexinnegative_words_regex]

#计算负向词语的数量

negative_match_count=sum([len(match)formatchinnegative_match])

#计算str中所有单词的数量

total_words=len(re.findall(r'\b[a-zA-Z\'\-]+\b',str))

#计算tone

tone=100*(positive_match_count-negative_match_count)/total_words

#返回结果

return(total_words,positive_match_count,negative_match_count,tone)

4.3文本的特征提取|26/304.3.2文本中常见指标的计算

text='''AtFedExGround,wehavethemarketleadinge-commerceportfolio.Wecontinuetoseestrongdemandacrossallcustomersegmentswithournewseven-dayservice.WewillincreaseourspeedadvantageduringtheNewYear.OurSundayroll-outwillspeedupsomelanesbyoneandtwofulltransit

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论