Coder Social home page Coder Social logo

time-nlp's Introduction

Time-NLP

#中文语句中的时间语义识别

author:shinyke

本工具是由复旦NLP中的时间分析功能修改而来,做了很多细节和功能的优化,具体如下:

  1. 泛指时间的支持,如:早上、晚上、中午、傍晚等。
  2. 时间未来倾向。 如:在周五输入“周一早上开会”,则识别到下周一早上的时间;在下午17点输入:“9点送牛奶给隔壁的汉子”则识别到第二天上午9点。
  3. 多个时间的识别,及多个时间之间上下文关系处理。如:"下月1号下午3点至5点到图书馆还书",识别到开始时间为下月1号下午三点。同时,结束时间也继承上文时间,识别到下月1号下午5点。
  4. 自定义基准时间:指定基准时间为“2016-05-20-09-00-00-00”,则一切分析以此时间为基准。
  5. 修复了各种各样的BUG

简而言之,这是一个输入一句话,能识别出话里的时间的工具。╮(╯▽╰)╭

使用方法详见测试类:

/**
 * <p>
 * 测试类
 * <p>
 * @author <a href="mailto:[email protected]">kexm</a>
 * @version 1.0
 * @since 2016年5月4日
 * 
 */
public class TimeAnalyseTest {
	
	@Test
	public void test(){
		String path = TimeNormalizer.class.getResource("").getPath();
		String classPath = path.substring(0, path.indexOf("/com/time"));
		System.out.println(classPath+"/TimeExp.m");
		TimeNormalizer normalizer = new TimeNormalizer(classPath+"/TimeExp.m");

		
		normalizer.parse("Hi,all.下周一下午三点开会");// 抽取时间
		TimeUnit[] unit = normalizer.getTimeUnit();
		System.out.println("Hi,all.下周一下午三点开会");
		System.out.println(DateUtil.formatDateDefault(unit[0].getTime()) + "-" + unit[0].getIsAllDayTime()); 
		
		normalizer.parse("早上六点起床");// 注意此处识别到6天在今天已经过去,自动识别为明早六点(未来倾向,可通过开关关闭:new TimeNormalizer(classPath+"/TimeExp.m", false))
		unit = normalizer.getTimeUnit();
		System.out.println("早上六点起床");
		System.out.println(DateUtil.formatDateDefault(unit[0].getTime()) + "-" + unit[0].getIsAllDayTime());
		
		normalizer.parse("周一开会");// 如果本周已经是周二,识别为下周周一。同理处理各级时间。(未来倾向)
		unit = normalizer.getTimeUnit();
		System.out.println("周一开会");
		System.out.println(DateUtil.formatDateDefault(unit[0].getTime()) + "-" + unit[0].getIsAllDayTime());
		
		normalizer.parse("下下周一开会");//对于上/下的识别
		unit = normalizer.getTimeUnit();
		System.out.println("下下周一开会");
		System.out.println(DateUtil.formatDateDefault(unit[0].getTime()) + "-" + unit[0].getIsAllDayTime());
		
		normalizer.parse("6:30 起床");// 严格时间格式的识别
		unit = normalizer.getTimeUnit();
		System.out.println("6:30 起床");
		System.out.println(DateUtil.formatDateDefault(unit[0].getTime()) + "-" + unit[0].getIsAllDayTime());
		
		normalizer.parse("6-3 春游");// 严格时间格式的识别
		unit = normalizer.getTimeUnit();
		System.out.println("6-3 春游");
		System.out.println(DateUtil.formatDateDefault(unit[0].getTime()) + "-" + unit[0].getIsAllDayTime());
		
		normalizer.parse("6月3  春游");// 残缺时间的识别 (打字输入时可便捷用户)
		unit = normalizer.getTimeUnit();
		System.out.println("6月3  春游");
		System.out.println(DateUtil.formatDateDefault(unit[0].getTime()) + "-" + unit[0].getIsAllDayTime());
		
		normalizer.parse("明天早上跑步");// 模糊时间范围识别(可在RangeTimeEnum中修改
		unit = normalizer.getTimeUnit();
		System.out.println("明天早上跑步");
		System.out.println(DateUtil.formatDateDefault(unit[0].getTime()) + "-" + unit[0].getIsAllDayTime());
		
		normalizer.parse("本周日到下周日出差");// 多时间识别
		unit = normalizer.getTimeUnit();
		System.out.println("本周日到下周日出差");
		System.out.println(DateUtil.formatDateDefault(unit[0].getTime()) + "-" + unit[0].getIsAllDayTime());
		System.out.println(DateUtil.formatDateDefault(unit[1].getTime()) + "-" + unit[1].getIsAllDayTime());
		
		normalizer.parse("周四下午三点到五点开会");// 多时间识别,注意第二个时间点用了第一个时间的上文
		unit = normalizer.getTimeUnit();
		System.out.println("周四下午三点到五点开会");
		System.out.println(DateUtil.formatDateDefault(unit[0].getTime()) + "-" + unit[0].getIsAllDayTime());
		System.out.println(DateUtil.formatDateDefault(unit[1].getTime()) + "-" + unit[1].getIsAllDayTime());
		
		//新闻随机抽取长句识别(2016年6月7日新闻,均以当日0点为基准时间计算)
		//例1
		normalizer.parse("昨天上午,第八轮中美战略与经济对话气候变化问题特别联合会议召开。**气候变化事务特别代表解振华表示,今年中美两国在应对气候变化多边进程中政策对话的重点任务,是推动《巴黎协定》尽早生效。", "2016-06-07-00-00-00");
		unit = normalizer.getTimeUnit();
		System.out.println("昨天上午,第八轮中美战略与经济对话气候变化问题特别联合会议召开。**气候变化事务特别代表解振华表示,今年中美两国在应对气候变化多边进程中政策对话的重点任务,是推动《巴黎协定》尽早生效。");
		for(int i = 0; i < unit.length; i++){
		    System.out.println("时间文本:"+unit[i].Time_Expression +",对应时间:"+ DateUtil.formatDateDefault(unit[i].getTime()));
		}
		 
		//例2
		normalizer.parse("《辽宁日报》今日报道,6月3日辽宁召开省委常委扩大会,会议从下午两点半开到六点半,主要议题为:落实**巡视整改要求。", "2016-06-07-00-00-00");
		unit = normalizer.getTimeUnit();
		System.out.println("《辽宁日报》今日报道,6月3日辽宁召开省委常委扩大会,会议从下午两点半开到六点半,主要议题为:落实**巡视整改要求。");
		for(int i = 0; i < unit.length; i++){
		    System.out.println("时间文本:"+unit[i].Time_Expression +",对应时间:"+ DateUtil.formatDateDefault(unit[i].getTime()));
		}
		 
		//例3
		normalizer.parse("去年11月起正式实施的刑法修正案(九)中明确,在法律规定的国家考试中,组织作弊的将入刑定罪,最高可处七年有期徒刑。另外,本月刚刚开始实施的新版《教育法》中也明确...", "2016-06-07-00-00-00");
		unit = normalizer.getTimeUnit();
		System.out.println("去年11月起正式实施的刑法修正案(九)中明确,在法律规定的国家考试中,组织作弊的将入刑定罪,最高可处七年有期徒刑。另外,本月刚刚开始实施的新版《教育法》中也明确...");
		for(int i = 0; i < unit.length; i++){
		    System.out.println("时间文本:"+unit[i].Time_Expression +",对应时间:"+ DateUtil.formatDateDefault(unit[i].getTime()));
		}
	}
	
	/**
	 * 修改TimeExp.m文件的内容
	 */
	@Test
	public void editTimeExp(){
		String path = TimeNormalizer.class.getResource("").getPath();
		String classPath = path.substring(0, path.indexOf("/com/time"));
		System.out.println(classPath+"/TimeExp.m");
		/**写TimeExp*/
		Pattern p = Pattern.compile("your-regex");
		try {
			TimeNormalizer.writeModel(p, classPath+"/TimeExp.m");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

2016年6月7日9:44执行測試,结果如下:

Hi,all。下周一下午三点开会

2016-06-13 15:00:00-false

周一开会

2016-06-13 00:00:00-true

下下周一开会

2016-06-20 00:00:00-true

6:30 起床

2016-06-08 06:30:00-false

6-3 春游

2016-06-03 00:00:00-true

6月3日 春游

2016-06-03 00:00:00-true

明天早上跑步

2016-06-08 08:00:00-false

本周日到下周日出差

2016-06-12 00:00:00-true

2016-06-19 00:00:00-true

周四下午三点到五点开会

2016-06-16 15:00:00-false

2016-06-16 17:00:00-false

昨天上午,第八轮中美战略与经济对话气候变化问题特别联合会议召开。**气候变化事务特别代表解振华表示,今年中美两国在应对气候变化多边进程中政策对话的重点任务,是推动《巴黎协定》尽早生效。

时间文本:昨天上午, 对应时间:2016-06-06 10:00:00

时间文本:今年, 对应时间:2016-01-01 00:00:00

《辽宁日报》今日报道,6月3日辽宁召开省委常委扩大会,会议从下午两点半开到六点半,主要议题为:落实**巡视整改要求。

时间文本:今日, 对应时间:2016-06-07 00:00:00

时间文本:6月3日, 对应时间:2016-06-03 00:00:00

时间文本:下午2点半, 对应时间:2016-06-03 14:30:00

时间文本:6点半, 对应时间:2016-06-03 18:30:00

去年11月起正式实施的刑法修正案(九)中明确,在法律规定的国家考试中,组织作弊的将入刑定罪,最高可处七年有期徒刑。另外,本月刚刚开始实施的新版《教育法》中也明确...

时间文本:去年11月, 对应时间:2015-11-01 00:00:00

时间文本:本月, 对应时间:2016-06-01 00:00:00



如果您使用并有意见和建议,欢迎在Issue和我交流。若觉得好用,你的star是对作者最好的支持。

Enjoy ** - shinyke**

time-nlp's People

Contributors

shinyke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

time-nlp's Issues

TimeExp读取问题

String path = TimeNormalizer.class.getResource("").getPath();
String classPath = path.substring(0, path.indexOf("/com/time"));
System.out.println(classPath+"/TimeExp.m");
TimeNormalizer normalizer = new TimeNormalizer(classPath+"/TimeExp.m");

如果将项目打成jar包加入到工程中,这种加载方式无法工作,因为jar中的资源是无法用FileInputStream读取的

标准时间如何解决

normalizer.parse("收录时间:2016-05-24TimeNLP 详细介绍");// 抽取时间
TimeUnit[] unit = normalizer.getTimeUnit();
System.out.println("收录时间:2016-05-24TimeNLP 详细介绍");
System.out.println(DateUtil.formatDateDefault(unit[0].getTime()) + "-" + unit[0].getIsAllDayTime());

运行结果是:
2017-05-03 10:17:15
收录时间:2016-05-24TimeNLP 详细介绍
2017-06-05 00:00:00-true

TimeEx正则匹配出现死循环

数据:依大端序,第1202538828478502551459097860527993021号,是“白日依山尽”
有问题的正则部分:((一|二|两|三|四|五|六|七|八|九|十|百|千|万|几|多|上|\d+)+个?(天|日|周|月|年)(后|前|半))
\d+后面还有一个+
可以把\d后面的+去掉,只用括号后的那个+号

希望能修正一下TimeExp.m文件,谢谢!

能否将一些时间识别为时间段而不是具体的时间点

能否将例如上午,下午、明天、下周一、下月1号等时间识别为一个时间段,而不是一个单独的时间点。
例如,今天上午可以识别为[2018-05-30 08:00:00, 2018-05-30 12:00:00],明天识别为[2018-05-31 00:00:00, 2018-05-31 23:59:59]

星期结合日期的会识别错误

例如 星期三(11月29日)8点半 会识别为星期三 丢失对日期的识别 而且以星期三之后的星期四 星期五等识别还是之前的星期三 是不是可以修改timeunit中的 norm_setCurRelated方法 进行下判断 如果是有精确地时间了 就不在进行这个规范化

解析的时候出现正则中文乱码

Exception in thread "main" java.util.regex.PatternSyntaxException: Unclosed character class near index 3
[鐨刔+
^
at java.util.regex.Pattern.error(Pattern.java:1955)
at java.util.regex.Pattern.clazz(Pattern.java:2548)
at java.util.regex.Pattern.sequence(Pattern.java:2063)
at java.util.regex.Pattern.expr(Pattern.java:1996)
at java.util.regex.Pattern.compile(Pattern.java:1696)
at java.util.regex.Pattern.(Pattern.java:1351)
at java.util.regex.Pattern.compile(Pattern.java:1028)
at com.time.nlp.stringPreHandlingModule.delKeyword(stringPreHandlingModule.java:23)

【如果发现时间解析有bug,那就来这里试一下另一个工具JIONLP吧】

如果发现时间解析有bug,那就来这里试一下另一个工具吧
JioNLP

import time
import jionlp as jio
res = jio.parse_time('今年9月', time_base={'year': 2021})
res = jio.parse_time('零三年元宵节晚上8点半', time_base=time.time())
res = jio.parse_time('一万个小时')
res = jio.parse_time('100天之后', time.time())
res = jio.parse_time('每周五下午4点', time.time())
print(res)

# {'type': 'time_span', 'definition': 'accurate', 'time': ['2021-09-01 00:00:00', '2021-09-30 23:59:59']}
# {'type': 'time_point', 'definition': 'accurate', 'time': ['2003-02-15 20:30:00', '2003-02-15 20:30:59']}
# {'type': 'time_delta', 'definition': 'accurate', 'time': {'hour': 10000.0}}
# {'type': 'time_span', 'definition': 'blur', 'time': ['2021-10-22 00:00:00', 'inf']}
# {'type': 'time_period', 'definition': 'accurate', 'time': {'delta': {'day': 7}, 
#  'point': {'time': ['2021-07-16 16:00:00', '2021-07-16 16:59:59'], 'string': '周五下午4点'}}}

解释错误的问题

作者的这个包还不错,
不过用的过程中还是发现一些问题
1.如 “晚上10点开会”,当前时间为下午4点,会解出 第二天的晚上10点。按我理解应该解出当天的10点。因为还没有到嘛
2.“帮我看一下星期五的天气”,这种场景会匹配“下星期五”而不是“星期五”,导至不精确。

时间识别错误

——3个BUG,
第一个
时间识别,isPreferFuture=ture时
下午7点到8点,识别到第二天的7点到8点

问题在于TimeUnit.java中的下面语句:
if(curTime < _tp.tunit[checkTimeIndex]){
return;
}
curTime =16点, _tp.tunit[checkTimeIndex] =7
这个7不对,应该是12+7 =19

这是一个bug

第二个
今天下午7到8点
由于【7】后面没加【点】所以识别为今天下午的默认时间【15:00】

第三个
今天6月28日,周三,
【周五下午7点到8点】,识别为【7月7日】

TimeExp.m文件中文乱码

下载下来用编辑器打开TimeExp.m发现中文乱码,修改编辑器的编码也还是乱码,请问这个文件原来的内容是什么?

在android studio中使用

我是新手,在开发一个有提醒功能的app,想问这个如何放到android studio中运行?TimeExp.m是怎么放到project里面去呢?

无法使用

项目打成jar包,执行test报错,无法使用

读取TimeExp.m失败: Not in GZIP format

将TimeExp.m放到本地项目的resources目录下,加载时发生如下异常:
java.util.zip.ZipException: Not in GZIP format
at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:165)
at java.util.zip.GZIPInputStream.(GZIPInputStream.java:79)
at java.util.zip.GZIPInputStream.(GZIPInputStream.java:91)
at com.time.nlp.TimeNormalizer.readModel(TimeNormalizer.java:265)
at com.time.nlp.TimeNormalizer.(TimeNormalizer.java:52)

rpointer--; rpointer++;这用法的奥秘在哪?

博主您好,我在学习您的代码,TimeNormalizer类的TimeEx方法中,有两段代码都用到了rpointer--; rpointer++;这种写法。
我自己写了测试类,发现这样做了之后rpointer的值似乎是没有任何变化的,那么这种用法的奥秘在哪儿呢?
若博主看到了消息,很期待能被老师您指点一下,万分感激!!!

发现一个bug

"下星期提醒我吃饭"
居然识别的时间是1970-1-1 0:0:0

添加识别节假日和农历的需求

hi 你好

我希望可以添加识别节假日和农历的识别。如果可以的话,我希望可以将这个功能添加到您的github工程中来。这里我简单说一下我的需求,然后希望可以得到您的指点和建议

比如说 “端午回家过节” 可以识别出来2017-05-30 00:00:00
比如说 “农历五月初三放假” 可以识别出来 2017-05-27 00:00:00

要完成上面的需求,我觉得需要做以下几个事情

  1. 识别是否有农历。这个可以作为一个单独的函数,传入文本,返回true、false
  2. 实现农历和阳历之间的转换(该功能我已经完成)
  3. 添加节假日的识别。我想请教一下,如果要添加这个功能,应该将方法在什么时候调用比较合适呢?我过了一遍代码,感觉应该在Time_Normalization方法中,再添加一个norm_festival的方法。不知道您对这个功能的实现有没有什么好的建议。

期待您的回复
Thanks
Ting

rpointer问题

你好,请问代码中的rpointer为什么会有自增然后自减的操作?TimeNormalizer类的第220+行
java初学者求回复

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.