当前位置: 首页 > news >正文

【工程实践】使用EDA(Easy Data Augmentation)做数据增强

        工程项目中,由于数据量不够,经常需要用到数据增强技术,尝试使用EDA进行数据增强。  

1.EDA简介

        EDA是一种简单但是非常有效的文本数据增强方法,是由美国Protago实验室发表于 EMNLP-IJCNLP 2019 会议。EDA来自论文《EDA: Easy Data Augmentation Techniques for Boosting Performance on Text Classification Tasks》

        对于提高文本分类任务性能的简单数据增强技术,文中提出了四种数据增强技术方案,具体包括同义词替换随机插入随机交换随机删除。并在深度学习模型RNN和CNN上用五个数据集做了文本分类实验的对比研究,实验中,作者根据数据集大小将训练集分为3种规模,用于比较EDA技术在训练数据集规模上的影响。实验也表明了,EDA提升了文本分类的效果。

2.增强方法

2-1. 同义词替换(Synonym Replacement, SR)

        1.从文本中随机选取n个不属于停用词集的单词,并随机选择其同义词替换它们。

        2.不考虑 stopwords,在句子中随机抽取n个词,然后从同义词词典中随机抽取同义词,并进行替换。关于同义词可以使用开源同义词表+领域自定义词表来建立。

        注:需要借助synonyms库完成同义词的选择

def synonym_replacement(words, n):new_words = words.copy()random_word_list = list(set([word for word in words if word not in stop_words]))random.shuffle(random_word_list)num_replaced = 0for random_word in random_word_list:synonyms = get_synonyms(random_word)if len(synonyms) >= 1:synonym = random.choice(synonyms)new_words = [synonym if word == random_word else word for word in new_words]num_replaced += 1if num_replaced >= n:breaksentence = ' '.join(new_words)new_words = sentence.split(' ')return new_wordsdef get_synonyms(word):return synonyms.nearby(word)[0]

2-2.随机插入(Random Insertion, RI)

        从文本中随机选择一个不在停用词表中的词,从它的同义词词集中随机选择一个词,插入到句子中的随机位置,并将该步骤重复 n 次。

def random_insertion(words, n):new_words = words.copy()for _ in range(n):add_word(new_words)return new_wordsdef add_word(new_words):synonyms = []counter = 0while len(synonyms) < 1:random_word = new_words[random.randint(0, len(new_words) - 1)]synonyms = get_synonyms(random_word)counter += 1if counter >= 10:returnrandom_synonym = random.choice(synonyms)random_idx = random.randint(0, len(new_words) - 1)new_words.insert(random_idx, random_synonym)

2-3.随机交换(Random Swap, RS)

        句子中,随机选择两个词,位置交换。该过程可以重复n次。 (swap_word 函数中随机产生两个序列下标,如果相同最多重新生成三次。)

def random_swap(words, n):new_words = words.copy()for _ in range(n):new_words = swap_word(new_words)return new_wordsdef swap_word(new_words):random_idx_1 = random.randint(0, len(new_words) - 1)random_idx_2 = random_idx_1counter = 0while random_idx_2 == random_idx_1:random_idx_2 = random.randint(0, len(new_words) - 1)counter += 1if counter > 3:return new_wordsnew_words[random_idx_1], new_words[random_idx_2] = new_words[random_idx_2], new_words[random_idx_1]return new_words

2-4.随机删除(Random Deletion, RD)

        用概率 p 随机删除文本中的单词。如果句子中只有一个单词,则直接返回。如果句子中所有单词都被删掉,则随机返回一个单词。

def random_deletion(words, p):if len(words) == 1:return wordsnew_words = []for word in words:r = random.uniform(0, 1)if r > p:new_words.append(word)if len(new_words) == 0:rand_int = random.randint(0, len(words) - 1)return [words[rand_int]]return new_words

3.问题总结

3-1.若句子中有多个单词被改变了,那么句子的原始标签类别是否还会有效?​​​​​​​

        为了验证通过EDA方法产生的数据是否原数据特征一致,作者在Pro-Con数据集上进行数据的对比分析。

        具体方法:首先,使用RNN在一未使用EDA过的数据集上进行训练;然后,对测试集进行EDA扩增,每个原始句子扩增出9个增强的句子,将这些句子作为测试集输入到RNN中;最后,从最后一个全连接层取出输出向量。应用t-SNE技术,将这些向量以二维的形式表示出来。如下图所示。下图中大三角和大圆圈都是原来的句子,小三角和小圆圈表示使用EDA技术进行数据增强的句子,可以看出来绝大多数原数据和EDA增强数据保持一致,即没有发生语义偏移,故而文中提出的4种数据增强技术不会影响文本的原始标签。

3-2.对于EDA中的每个方法,单独提升的效果如何?

        为了确定性能的提升到底是由四种数据增强方式中哪一种,或哪几种方式起到的作用,以及哪种方式起到的作用比较大,作者做了消融研究——分别单独使用其中一种数据增强方式进行实验研究。并得到如下实验结果。

        上图中,参数α表示四种数据增强方式里被改变的单词数量占原文本长度的比例,实验中取α={0.05,0.1,0.2,0.3,0.4,0.5}。

        对于同义词替换(SR),当α较小时,实验性能提升明显,但是α变大时性能有所下降,可能是因为替换过多单词时改变了原文本的含义;

        对于随机插入(RI),α在上述范围内的取值使得实验性能保持相对稳定,可能是因为随机插入的方法使得原文本中的单词顺序保持相对稳定;

        对于随机交换(RS),当α≤0.2时实验性能提升明显,当α≥0.3时性能有所下降,因为过多的单词位置交换打乱了原文本的整体顺序,改变了文本含义;

        对于随机删除(RD),当α较小时能够使得实验性能达到最高,但是α变大时能严重降低实验性能,因为删除过多单词时,句子难以理解,是的文本丢失语义信息。

消融实验得出的结论是,对于每个方法在小数据集上取得的效果更明显。 α如果太大的话,甚至会降低模型表现效果, α=0.1似乎是最佳值。

3-3.如何选取合适的增强语句个数?

        在较小的数据集上,模型容易过拟合,因此生成多一点的语料能取得较好的效果。对于较大的数据集,每句话生成超过4个句子对于模型的效果提升就没有太大帮助。因此,作者推荐实际使用中的一些参数选取如下表所示。

 naug :每个原始语句的增强语句个数;Ntrain :训练集大小

3-4.EDA提高文本分类的效果的原理是什么?

        1.生成类似于原始数据的增强数据会引入一定程度的噪声,有助于防止过拟合;

        2.使用EDA可以通过同义词替换和随机插入操作引入新的词汇,允许模型泛化到那些在测试集中但不在训练集中的单词;

4. EDA数据增强代码实现

4-1 说明

       代码实现中是需要jieba分词,停用词表(默认使用哈工大停用词表),以及一个提供同义词的包(Synonyms)。

4-2 代码实现

import pandas as pd
import json
from tqdm import tqdm# !/usr/bin/env python
# -*- coding: utf-8 -*-
import jieba
import re
import random
from random import shuffle
random.seed(2019)
import synonyms 
# 停用词列表,默认使用哈工大停用词表
f = open('/home/zhenhengdong/WORk/Classfier/Dates/stopWord.json', encoding='utf-8')
stop_words = list()
for stop_word in f.readlines():stop_words.append(stop_word[:-1])
# 文本清理
import re
def get_only_chars(line):#1.清除所有的数字########################################################################
# 同义词替换
# 替换一个语句中的n个单词为其同义词
########################################################################def synonym_replacement(words, n):new_words = words.copy()random_word_list = list(set([word for word in words if word not in stop_words]))random.shuffle(random_word_list)num_replaced = 0for random_word in random_word_list:synonyms = get_synonyms(random_word)if len(synonyms) >= 1:synonym = random.choice(synonyms)new_words = [synonym if word == random_word else word for word in new_words]num_replaced += 1if num_replaced >= n:breaksentence = ' '.join(new_words)new_words = sentence.split(' ')return new_wordsdef get_synonyms(word):return synonyms.nearby(word)[0]########################################################################
# 随机插入
# 随机在语句中插入n个词
########################################################################
def random_insertion(words, n):new_words = words.copy()for _ in range(n):add_word(new_words)return new_wordsdef add_word(new_words):synonyms = []counter = 0while len(synonyms) < 1:random_word = new_words[random.randint(0, len(new_words) - 1)]synonyms = get_synonyms(random_word)counter += 1if counter >= 10:returnrandom_synonym = random.choice(synonyms)random_idx = random.randint(0, len(new_words) - 1)new_words.insert(random_idx, random_synonym)########################################################################
# Random swap
# Randomly swap two words in the sentence n times
########################################################################def random_swap(words, n):new_words = words.copy()for _ in range(n):new_words = swap_word(new_words)return new_wordsdef swap_word(new_words):random_idx_1 = random.randint(0, len(new_words) - 1)random_idx_2 = random_idx_1counter = 0while random_idx_2 == random_idx_1:random_idx_2 = random.randint(0, len(new_words) - 1)counter += 1if counter > 3:return new_wordsnew_words[random_idx_1], new_words[random_idx_2] = new_words[random_idx_2], new_words[random_idx_1]return new_words########################################################################
# 随机删除
# 以概率p删除语句中的词
########################################################################
def random_deletion(words, p):if len(words) == 1:return wordsnew_words = []for word in words:r = random.uniform(0, 1)if r > p:new_words.append(word)if len(new_words) == 0:rand_int = random.randint(0, len(words) - 1)return [words[rand_int]]return new_words########################################################################
# EDA函数
def eda_func(sentence, alpha_sr = 0.35, alpha_ri = 0.35, alpha_rs = 0.35, p_rd = 0.35, num_aug = 12):seg_list = jieba.cut(sentence)seg_list = " ".join(seg_list)words = list(seg_list.split())num_words = len(words)augmented_sentences = []num_new_per_technique = int(num_aug / 4)n_sr = max(1, int(alpha_sr * num_words))n_ri = max(1, int(alpha_ri * num_words))n_rs = max(1, int(alpha_rs * num_words))# print(words, "\n")# 同义词替换srfor _ in range(num_new_per_technique):a_words = synonym_replacement(words, n_sr)augmented_sentences.append(''.join(a_words))# 随机插入rifor _ in range(num_new_per_technique):a_words = random_insertion(words, n_ri)augmented_sentences.append(''.join(a_words))## 随机交换rsfor _ in range(num_new_per_technique):a_words = random_swap(words, n_rs)augmented_sentences.append(''.join(a_words))### 随机删除rdfor _ in range(num_new_per_technique):a_words = random_deletion(words, p_rd)augmented_sentences.append(''.join(a_words))# print(augmented_sentences)shuffle(augmented_sentences)if num_aug >= 1:augmented_sentences = augmented_sentences[:num_aug]else:keep_prob = num_aug / len(augmented_sentences)augmented_sentences = [s for s in augmented_sentences if random.uniform(0, 1) < keep_prob]# augmented_sentences.append(seg_list)def Data_Augmentation(item,num):augmented_sentence_dataframe = pd.DataFrame()for join_class in tqdm(stations_dict[item]):for index in range(len(new_data)):if new_data.loc[index].联合分类 == join_class:augmented_sentences = eda_func(sentence = new_data.loc[index]['内容'])[:num]for augmented_sentence in augmented_sentences:creat_new_data = pd.DataFrame()creat_new_data['内容'] = [augmented_sentence]creat_new_data['反馈类型'] = [new_data.loc[index]['反馈类型']]creat_new_data['一级分类'] = [new_data.loc[index]['一级分类']]creat_new_data['二级分类'] = [new_data.loc[index]['二级分类']]creat_new_data['联合分类'] = [new_data.loc[index]['联合分类']]augmented_sentence_dataframe = pd.concat([augmented_sentence_dataframe, creat_new_data], ignore_index=True)print(len(augmented_sentence_dataframe))          return augmented_sentence_dataframeif __name__ == '__main__':new_data = pd.read_csv('./Temp_data.csv')stations_dict = {}for index,key_values in enumerate(new_data.联合分类.value_counts().items()):if 1500 > key_values[1] > 1000:stations_dict.setdefault('1000', []).append(key_values[0])if 1000 > key_values[1] > 800:stations_dict.setdefault('800', []).append(key_values[0])if 800 > key_values[1] > 600:stations_dict.setdefault('600', []).append(key_values[0])if 600 > key_values[1] > 500:stations_dict.setdefault('500', []).append(key_values[0])if 500 > key_values[1] > 400:stations_dict.setdefault('400', []).append(key_values[0])if 400 > key_values[1] > 300:stations_dict.setdefault('300', []).append(key_values[0])if 300 > key_values[1] > 0:stations_dict.setdefault('0', []).append(key_values[0])Temp_data = pd.DataFrame()for item in stations_dict:if item == '1000':#13642augmented_sentence_dataframe = Data_Augmentation(item,num = 2)Temp_data = pd.concat([Temp_data, augmented_sentence_dataframe], ignore_index=True)if item == '800':#16503augmented_sentence_dataframe = Data_Augmentation(item,num = 3)Temp_data = pd.concat([Temp_data, augmented_sentence_dataframe], ignore_index=True)if item == '600':#23684augmented_sentence_dataframe = Data_Augmentation(item,num = 4)Temp_data = pd.concat([Temp_data, augmented_sentence_dataframe], ignore_index=True)if item == '500':#15186augmented_sentence_dataframe = Data_Augmentation(item,num = 6)Temp_data = pd.concat([Temp_data, augmented_sentence_dataframe], ignore_index=True)if item == '400':#20400augmented_sentence_dataframe = Data_Augmentation(item,num = 8)Temp_data = pd.concat([Temp_data, augmented_sentence_dataframe], ignore_index=True)if item == '300':#7137augmented_sentence_dataframe = Data_Augmentation(item,num = 9)Temp_data = pd.concat([Temp_data, augmented_sentence_dataframe], ignore_index=True)if item == '0':#3897augmented_sentence_dataframe = Data_Augmentation(item,num = 9)Temp_data = pd.concat([Temp_data, augmented_sentence_dataframe], ignore_index=True)#将合并的data存储Temp_data.to_csv('./Temp_data_single_sample.csv',index = False,encoding='utf8')

Reference:

1.https://www.zhihu.com/question/341361292/answer/2916784123

2.NLP中的数据增强:UDA、EDA_eda数据增强_快乐小码农的博客-CSDN博客

相关文章:

【工程实践】使用EDA(Easy Data Augmentation)做数据增强

工程项目中&#xff0c;由于数据量不够&#xff0c;经常需要用到数据增强技术&#xff0c;尝试使用EDA进行数据增强。 1.EDA简介 EDA是一种简单但是非常有效的文本数据增强方法&#xff0c;是由美国Protago实验室发表于 EMNLP-IJCNLP 2019 会议。EDA来自论文《EDA: Easy Data…...

ClickHouse(十三):Clickhouse MergeTree系列表引擎 - ReplicingMergeTree

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术&#xff0c;IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 &…...

机器学习笔记之优化算法(十)梯度下降法铺垫:总体介绍

机器学习笔记之优化算法——梯度下降法铺垫&#xff1a;总体介绍 引言回顾&#xff1a;线搜索方法线搜索方法的方向 P k \mathcal P_k Pk​线搜索方法的步长 α k \alpha_k αk​ 梯度下降方法整体介绍 引言 从本节开始&#xff0c;将介绍梯度下降法 ( Gradient Descent,GD ) …...

Selenium 根据元素文本内容定位

使用xpath定位元素时&#xff0c;有时候担心元素位置会变&#xff0c;可以考虑使用文本内容来定位的方式。 例如图中的【股市】按钮&#xff0c;只有按钮文本没变&#xff0c;即使位置变化也可以定位到该元素。 xpath内容样例&#xff1a; # 文本内容完全匹配 //button[text(…...

第17章-Spring AOP经典应用场景

文章目录 一、日志处理二、事务控制三、参数校验四、自定义注解五、AOP 方法失效问题1. ApplicationContext2. AopContext3. 注入自身 六、附录1. 示例代码 AOP 提供了一种面向切面操作的扩展机制&#xff0c;通常这些操作是与业务无关的&#xff0c;在实际应用中&#xff0c;可…...

Leetcode周赛 | 2023-8-6

2023-8-6 题1体会我的代码 题2我的超时代码题目体会我的代码 题3体会我的代码 题1 体会 这道题完全就是唬人&#xff0c;只要想明白了&#xff0c;只要有两个连续的数的和&#xff0c;大于target&#xff0c;那么一定可以&#xff0c;两边一次切一个就好了。 我的代码 题2 我…...

ts中interface自定义结构约束和对类的约束

一、interface自定义结构约束对后端接口返回数据 // interface自定义结构 一般用于较复杂的结构数据类型限制 如后端返回的接口数据// 首字母大写;用分割号隔开 interface Iobj{a:number;b:string } let obj:Iobj {a:1,b:2 }// 复杂类型 模拟后端返回的接口数据 interface Il…...

Oracle单实例升级补丁

目录 1.当前DB环境2.下载补丁包和opatch的升级包3.检查OPatch的版本4.检查补丁是否冲突5.关闭数据库实例&#xff0c;关闭监听6.应用patch7.加载变化的SQL到数据库8.ORACLE升级补丁查询 oracle19.3升级补丁到19.18 1.当前DB环境 [oraclelocalhost ~]$ cat /etc/redhat-releas…...

力扣初级算法(二分查找)

力扣初级算法(二分法)&#xff1a; 每日一算法&#xff1a;二分法查找 学习内容&#xff1a; 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 2.二分查找流程&…...

探索未来:直播实时美颜SDK在增强现实(AR)直播中的前景

在AR直播中&#xff0c;观众可以与虚拟元素实时互动&#xff0c;为用户带来更加丰富、沉浸式的体验。那么&#xff0c;直播美颜SDK在AR中有哪些应用呢&#xff1f;下文小编将于大家一同探讨美颜SDK与AR有哪些关联。 一、AR直播与直播实时美颜SDK的结合 增强现实技术在直播中…...

SQL 单行子查询 、多行子查询、单行函数、聚合函数 IN 、ANY 、SOME 、ALL

单行子查询 子查询结果是 一个列一行记录 select a&#xff0c;b&#xff0c;c from table where a >(select avg(xx) from table ) 还支持这种写法,这种比较少见 select a&#xff0c;b&#xff0c;c from table where (a ,b)(select xx,xxx from table where col‘000’ )…...

【第一阶段】kotlin的range表达式

range:范围&#xff1a;从哪里到哪里的意思 in:表示在 !in&#xff1a;表示不在 … :表示range表达式 代码示例&#xff1a; fun main() {var num:Int20if(num in 0..9){println("差劲")}else if(num in 10..59){println("不及格")}else if(num in 60..89…...

网络防御(5)

一、结合以下问题对当天内容进行总结 1. 什么是恶意软件&#xff1f; 2. 恶意软件有哪些特征&#xff1f; 3. 恶意软件的可分为那几类&#xff1f; 4. 恶意软件的免杀技术有哪些&#xff1f; 5. 反病毒技术有哪些&#xff1f; 6. 反病毒网关的工作原理是什么&#xff1f; 7. 反…...

gradle 命令行单元测试执行问题

文章目录 问题&#xff1a;命令行 执行失败最终解决方案&#xff08;1&#xff09;ADB命令&#xff08;2&#xff09;Java 环境配置 问题&#xff1a;命令行 执行失败 命令行 执行测试命令 无法使用&#xff08;之前还能用的。没有任何改动&#xff0c;又不能用了&#xff09; …...

剑指Offer12.矩阵中的路径 C++

1、题目描述 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平…...

金鸣识别将无表格线的图片转为excel的几个常用方案

我们知道&#xff0c;金鸣识别要将横竖线齐全的表格图片转为excel非常简单&#xff0c;但要是表格线不齐全甚至没有表格线的图片呢&#xff1f;这就没那么容易了&#xff0c;在识别这类图片时&#xff0c;我们一般会使用以下的一种或多种方法进行处理&#xff1a; 1. 基于布局…...

刚刚更新win11,记事本消失怎么处理?你需要注意些什么?

记录window11的bug hello&#xff0c;我是小索奇 昨天索奇从window10更新到了window11&#xff0c;由于版本不兼容卸载了虚拟机&#xff0c;这是第一个令脑壳大的&#xff0c;算了&#xff0c;还是更新吧&#xff0c;了解了解win11的生态&#xff0c;后期重新装虚拟机 第一个可…...

【QT】 QTabWidgetQTabBar控件样式设计(QSS)

很高兴在雪易的CSDN遇见你 &#xff0c;给你糖糖 欢迎大家加入雪易社区-CSDN社区云 前言 本文分享QT控件QTabWidget&QTabBar的样式设计&#xff0c;介绍两者可以自定义的内容&#xff0c;以及如何定义&#xff0c;希望对各位小伙伴有所帮助&#xff01; 感谢各位小伙伴…...

【个人记录】CentOS7 编译安装最新版本Git

说明 使用yum install git安装的git版本是1.8&#xff0c;并不是最新版本&#xff0c;使用gitlab-runner托管时候会拉项目失败&#xff0c;这里使用编译源码方式安装最新版本的git。 基础环境安装 echo "nameserver 8.8.8.8" >> /etc/resolv.conf curl -o /…...

【Linux】计算机网络的背景和协议分层

文章目录 网络发展协议何为协议网络协议协议分层OSI七层模型TCP/IP五层模型&#xff08;四层&#xff09; 基本通信流程mac地址和ip地址网络通信本质 网络发展 从一开始计算机作为一台台单机使用&#xff0c;到现在网络飞速发展&#xff0c;从局域网Lan建立起局域网&#xff0…...

代理模式:静态代理+JDK/CGLIB 动态代理

文章目录 1. 代理模式2. 静态代理3. 动态代理3.1. JDK 动态代理机制3.1.1. 介绍 3.1.2. JDK 动态代理类使用步骤3.1.3. 代码示例3.2. CGLIB 动态代理机制3.2.1. 介绍3.2.2. CGLIB 动态代理类使用步骤3.2.3. 代码示例 3.3. JDK 动态代理和 CGLIB 动态代理对比 4. 静态代理和动态…...

gps虚拟定位 AnyGo for Mac 中文

要在AnyGo中进行Gps位置模拟&#xff0c;您只需连接您的设备并选择“位置模拟”选项&#xff0c;然后输入您想要模拟的位置信息即可。通过使用AnyGo&#xff0c;您可以轻松地模拟任何地方的位置&#xff0c;而无需实际去到那个地方。 借助AnyGo&#xff0c;您可以通过在地图上…...

LLM reasoners 入门实验 24点游戏

LLM reasoners Ber666/llm-reasoners 实验过程 实验样例24games&#xff0c;examples/tot_game24&#xff0c;在inference.py中配置使用代理和open ai的api key。 首先安装依赖 git clone https://github.com/Ber666/llm-reasoners cd llm-reasoners pip install -e .然后…...

【LeetCode 算法】Maximum Absolute Sum of Any Subarray 任意子数组和的绝对值的最大值-前缀和

文章目录 Maximum Absolute Sum of Any Subarray 任意子数组和的绝对值的最大值问题描述&#xff1a;分析代码前缀和前缀和 Tag Maximum Absolute Sum of Any Subarray 任意子数组和的绝对值的最大值 问题描述&#xff1a; 给你一个整数数组 nums 。一个子数组 [ n u m s l ,…...

怎么建立大型语言模型

建立大型语言模型通常涉及以下主要步骤&#xff1a; 数据收集&#xff1a;收集大规模的文本数据作为模型的训练数据。可以从各种来源获取数据&#xff0c;如互联网、书籍、新闻文章等。数据的质量和多样性对于模型的性能至关重要。 数据预处理&#xff1a;对收集到的数据进行预…...

docker简介和安装

什么是docker&#xff1f; docker是基于Go语言编写的开源容器引擎&#xff0c;是操作系统级别的轻量级虚拟技术。主要用于应用打包、分发、部署。 打包&#xff1a;软件开发过程中&#xff0c;打包是将程序打包成软件包或者镜像的过程&#xff1b;在容器化程序中&#xff0c;打…...

记录问题: servlet获取项目包绝对路径

【2023-8-8 23:46:27 星期二】 如何获取在webapp下的路径?而不是target包下的webapp目录 比如这里应该获取到 F:\Tiam\Desktop\freemarker\freemarker-demo01\src\main\webapp 而readPath总是获取到 F:\Tiam\Desktop\freemarker\freemarker-demo01\target\freemarker-demo0…...

C语言文件操作基本方法

1、文件的分类 ANSI C 的缓冲文件系统 缓冲文件系统 缓冲文件系统是指&#xff0c;系统自动地在内存区为每个正在使用的文件开辟一个缓冲区。 从内存向磁盘输出数据时&#xff0c;必须首先输出到缓冲区中。待缓冲区装满后&#xff0c;再一起输出到磁盘文件中。 从磁盘文件向内…...

SQL 相关子查询 和 不相关子查询、Exists 、Not Exists、 多表连接(包含自连接)

不相关子查询 子查询的查询条件不依赖于父查询&#xff0c;称不相关子查询。子查询可以单独运行的 select stu_id,sex,age from student t where sex(select sexfrom studentwhere stu_id10023 )相关子查询 关联子查询 子查询的查询条件依赖于父查询&#xff0c;称为 相关子…...

项目规范 编写规范(范例)

项目目录 目录接口参考 项目目录结构设计&#xff0c;增加部分领域模型后缀强制定义&#xff0c;方便统一编码风格。 controller&#xff1a;请求处理 RestController module&#xff1a;按大业务区分&#xff0c;对多个业务对象数据聚合处理 Component manager&#xff1a;…...

专门网站建设/电子商务网站建设

nameZed A.Shaw age7 print("my name is%s" %name) print("my name is%r" %name) print("my name is%d" %age)...

wordpress好还是织梦好/营销课程培训视频

本文涉及的主要程序有 Python 3.6&#xff0c; VS Code 1.33.1 。Python 扩展为在 VS Code 中编辑 Python 代码提供了许多功能&#xff0c;代码补全、智能提示、格式化代码、代码重构等。这些基础功能一般自己摸索下就都会用&#xff0c;所以就不浪费文字在一些概念上了&#x…...

如何对上传的网站做代码修改/自动收录网

第一章 成局在胸一一用工具对 SQL 整体优化 第二章 风驰电掣一一有效缩短SQL 优化过程 第三章规蹈矩一一如何读懂SQL 执行计划 第四章 运筹幢幢一一左右 SQL执行计划妙招 第五章感受体系结构让SQL飞 第六章 且慢&#xff0c;体验逻辑结构让SQL飞 第七章探寻表的设计让SQL飞 第…...

衢州哪里有做网站的公司4000-262-/宁波seo优化公司排名

秒字符设备 秒字符设备也是字符驱动&#xff0c;所以与之前的字符设备驱动程序的框架类似&#xff0c;模块编译&#xff0c;模块加载与卸载也与内核模块的编译&#xff0c;加载卸载一致。秒字符设备驱&#xff08;second&#xff09;的实现&#xff0c;创建目录&#xff08;sec…...

北京市朝阳区住房建设网站/青岛关键词推广seo

本系列博客是对斯坦福大学Jure Leskovec副教授所讲《CS224W图机器学习》所做的听课笔记。由于课程为英语授课&#xff0c;本人的英文理解不是很好&#xff0c;笔记中难免很有许多错误&#xff0c;欢迎大家一起纠错&#xff0c;一起学习。 课程网址&#xff08;源自于哔哩哔哩视…...

东莞市建设质量监督网站/重庆网站seo多少钱

前言 覆盖jar里面的方法 bean 方式一 目标&#xff1a;bean 方式&#xff1a;新建一个接口实现类&#xff0c;实现目标方法所对应的接口&#xff0c;然后重写需要改动的方法&#xff0c;最后拿着这个新的实现类去执行逻辑 普通的类 方式一 目标&#xff1a;普通的类 方式…...