JavaFX和可视化信息抽取
1、阅读说明
本篇博客是非介绍类的,即,不含有关于JavaFX的基础介绍。博客主要描述实现可视化信息抽取时,如何利用JavaFX的WebView组件。仅介绍涉及到的JavaFX的内容,至于可视化信息抽取的算法是哪个,博客不进行介绍,提供的源码中有一个可视化信息抽取的演示Demo,Demo不涉及到核心算法,是基于定制规则进行抽取的。
博客内容是我毕业设计(基于反馈学习的半结构化信息抽取研究及应用)可能涉及到的基础技术的准备和总结,技术准备的时间较短,同时心里着急找工作(真心着急。。。),里面可能有不正确的,如有发现,请指正,同时提醒,本博客内容只是作为技术实现的可行tips,千万不要作为标准样板,关于某些问题,如果您有发现新的解决方案,请您一定要告诉我一下,非常感谢!
2、主要解决的问题
- 如何获取WebView渲染后网页中元素的基本信息,比如x,y坐标、字体大小、字体颜色、背景色等等;
- 如果用TreeView绑定DOM树,同时实现右键TreeView时,查看元素的基本信息或者高亮指定元素;
- 如果直接通过右键浏览器界面来高亮点击的元素;
- 如何获取WebView的滚动条对象、滚动条的宽度和判断滚动条的方向;
- 如何在拖拽窗体、最大化窗体等改变窗口大小时,获取WebView中的元素坐标位置;
- 对于已生成的Document文档对象,如何在Java中监听网页中对应DOM树的结构的变化;
- 如何对JavaFX生成的DOM对象,进行XPath操作;
- Java如何执行WebView渲染网页中的按钮自动点击操作,比如“下一页”自动点击下一页,“百度一下”自动进行搜索。
3、尚未完全解决的问题
- 网页随着滚动条滚动加载时,如何快速让网页滚动至网页底部,使其加载完全(因为滚动条不止滚动一次,即到底部以后,有可能还需要继续滚动)
- WebView对象怎么具体识别水平滚动条和垂直滚动条(因为编程过程中,发现WebView有多个ScrollBar对象,有时候多达10多个,如何区分哪两个是有效的,暂时不会)
- WebView.onScrollProperty().addListener((ChangeListener<? super EventHandler<? super ScrollEvent>>),这个addListener函数如何添加参数,因为<? super EventHandler<? super ScrollEvent>>是嵌套类型的,实现时,总是提示错误,当时解决了,撤销以后,隔天又忘了。
本文涉及到的JavaFX对应的JDK版本是JDK1.7
4、关于JavaFX的基本概念
关于JavaFX的基本概念,比如,JavaFX UI组件的使用、布局相关、Web组件相关等等,可参考JAVAFX中文资料。这个网页相当于Oracle官方文档的翻译,里面有基础知识介绍,以及相关实现代码,非常推荐。对应英文版入口JavaFX: Getting Started with JavaFX 和 Java Platform, Standard Edition (Java SE) 8相关资料(含JavaFX),JavaFX 2.0的API文档。
JavaFX是和DOM模型以及CSS紧密相结合的。尤其是WebView,获取渲染后的网页内容,一般都是通过执行JavaScript获取的。所以,学习或者利用JavaFX解决相关问题时,一定不要局限于窗体程序思维,一定要记住JavaFX和JavaScript的交互性。我刚开始接触JavaFX,就因为这个,想很多问题时就太死板,浪费很多时间。
JavaFX事件模型是DOM2事件模型,DOM2事件模型有一个典型的特性,就是事件从“顶层开始捕获,直至目标元素,然后事件相应处理从目标元素冒泡到顶层”(推荐文档:JAVAFX-事件),如下图:
图片引用来自:http://www.csdn123.com/html/topnews201408/5/11405.htm
treeItemParent.addEventHandler(TreeItem.<DOMBox> branchCollapsedEvent(),new EventHandler<TreeItem.TreeModificationEvent<DOMBox>>() {@Overridepublic void handle(TreeItem.TreeModificationEvent<DOMBox> event) {TreeItem<DOMBox> tCurrent = event.getTreeItem();DOMBox domBox = (DOMBox) tCurrent.getValue();if (!ElementTools.isSelfClose(domBox.getTagName())) {String strHtml = domBox.getSelfHtml() + "...</" + domBox.getTagName() + ">";domBox.setSelfHtml(strHtml);TreeItem<DOMBox> tNext = tCurrent.nextSibling();tNext.getParent().getChildren().remove(tNext);}}});
/*** Returns the vertical scrollbar of the webview.** @param webView webview* @return vertical scrollbar of the webview or {@code null} if no vertical* scrollbar exists*/private ScrollBar getVScrollBar(WebView webView) {Set<Node> scrolls = webView.lookupAll(".scroll-bar");for (Node scrollNode : scrolls) {if (ScrollBar.class.isInstance(scrollNode)) {ScrollBar scroll = (ScrollBar) scrollNode;if (scroll.getOrientation() == Orientation.VERTICAL) {return scroll;}}}return null;}
通过WebView的lookup或者lookupAll函数来进行查找相关元素。
以下是遍历元素结点样式表的代码片段,以ScrollBar为例。
List<CssMetaData<? extends Styleable, ?>> css = scroll.getCssMetaData();
for (int i = 0; i < css.size(); i++) {CssMetaData<? extends Styleable, ?> oneAttr = css.get(i);System.out.print(oneAttr.getProperty() + ":" + ((CssMetaData<ScrollBar, ScrollBar>) oneAttr).getStyleableProperty(scroll).getValue() + "\t");
}
System.out.println();
5、问题具体解决方案
强烈推荐Stack OverFlow,我的解决方案好像都是在其中看的代码片段知道的。
5.1 如何获取WebView渲染后网页中元素的基本信息,比如x,y坐标、字体大小、字体颜色、背景色等等
- 浏览器默认样式,就是浏览器自身所带的样式表,因为添加样式时,你不可能将所有样式都添加进去,比如h1默认展示的样式,就是浏览器自身的。这个概念之前还真没有注意。
- .css文件中的样式
- 网页中style结点中定义的样式
- 标签内嵌的样式,就是元素中style属性中定义的样式
// 计算对应元素的属性public DOMBox getDOMBoxByNode(WebEngine wEngine, Element e){JSObject obj_defaultView = (JSObject)webEngine.executeScript("document.defaultView");JSObject obj_ComputedStyle = (JSObject)obj_defaultView.call("getComputedStyle", e,null);JSObject obj = (JSObject)e;String tag_name = e.getTagName().toLowerCase();String strTemp = obj_ComputedStyle.getMember("font-size").toString();float font_size = Float.parseFloat(strTemp.substring(0, strTemp.length()-2));// 这个方法获取x,y坐标时,有问题
// float width = (int)obj.getMember("offsetWidth");
// float height = (int)obj.getMember("offsetHeight");
// float x = (int)obj.getMember("offsetLeft");
// float y = (int)obj.getMember("offsetTop");JSObject bounds = (JSObject) obj.call("getBoundingClientRect");float right = Float.parseFloat(bounds.getMember("right").toString());float top = Float.parseFloat(bounds.getMember("top").toString());float bottom = Float.parseFloat(bounds.getMember("bottom").toString());float left = Float.parseFloat(bounds.getMember("left").toString());float width = right - left;float height = bottom - top;float x = left;float y = top;String font_color = obj_ComputedStyle.getMember("color").toString();String background_color = obj_ComputedStyle.getMember("background-color").toString();boolean is_link = tag_name.compareToIgnoreCase("a") == 0;String strSelfHtml = ElementTools.getElementHtml(e);return new DOMBox(e, tag_name, font_size, width, height, x, y, font_color, background_color, is_link, strSelfHtml);}
5.2 如果用TreeView绑定DOM树,同时实现右键TreeView时,查看元素的基本信息或者高亮指定元素
rightTreeView.setCellFactory(new Callback<TreeView<DOMBox>, TreeCell<DOMBox>>(){@Overridepublic TreeCell<DOMBox> call(TreeView<DOMBox> para){return new DOMTreeCellImpl();}});
private final class DOMTreeCellImpl extends TreeCell<DOMBox>{private final ContextMenu addMenu = new ContextMenu();public DOMTreeCellImpl(){MenuItem addMenuItem1 = new MenuItem("查看信息");MenuItem addMenuItem2 = new MenuItem("高亮元素");addMenu.getItems().add(addMenuItem1);addMenu.getItems().add(addMenuItem2);addMenuItem1.setOnAction(new EventHandler<ActionEvent>(){public void handle(ActionEvent t) {// 以对话框的形式,弹出结点的基本信息TreeItem<DOMBox> treeItem = getTreeItem();Label lblInfo = new Label(treeItem.getValue().getDetailInfo());BorderPane pane = new BorderPane();pane.setCenter(lblInfo);pane.setPadding(new Insets(30, 0, 0, 0));BorderPane.setAlignment(lblInfo, Pos.TOP_CENTER);Stage secondWindow=new Stage();Scene scene=new Scene(pane,300,275);secondWindow.setTitle("DOM结点详细信息");secondWindow.setScene(scene);secondWindow.show();}});addMenuItem2.setOnAction(new EventHandler<ActionEvent>(){public void handle(ActionEvent t) {MenuItem itemTemp = (MenuItem)t.getTarget();// 根据被点击的节点信息,对浏览器中对应的元素进行高亮显示Node nd = getTreeItem().getValue().getBindNode();if(nd != null && nd instanceof Element){Object obj = itemTemp.getUserData();if(obj == null){if (lstRectNode.indexOf(nd) == -1) {lstRectNode.add(nd);drawRectangle();}itemTemp.setUserData(true);itemTemp.setText("取消高亮");}else if((Boolean)obj && lstRectNode.indexOf(nd) != -1){itemTemp.setUserData(null);lstRectNode.remove(nd);drawRectangle();itemTemp.setText("高亮元素");}}else{Alert alert = new Alert(AlertType.WARNING, "");alert.initModality(Modality.APPLICATION_MODAL);alert.initOwner(null);alert.getDialogPane().setContentText("该结点不可进行高亮!");alert.getDialogPane().setHeaderText(null);alert.showAndWait();}}});}@Overridepublic void startEdit() {super.startEdit();}@Overridepublic void cancelEdit() {super.cancelEdit();}@Overridepublic void updateItem(DOMBox item, boolean empty) {super.updateItem(item, empty);if (empty) {setText(null);setGraphic(null);} else {setText(item.toString());setGraphic(getTreeItem().getGraphic());Node nd = getTreeItem().getValue().getBindNode();// 必须是元素才可以有菜单if (nd != null && nd instanceof Element) {if(lstRectNode.indexOf(nd) != -1){addMenu.getItems().get(1).setText("取消高亮");addMenu.getItems().get(1).setUserData(true);}else{addMenu.getItems().get(1).setText("高亮元素");addMenu.getItems().get(1).setUserData(null);}setContextMenu(addMenu);}else{setContextMenu(null);}}}}
5.3 如果直接通过右键浏览器界面来高亮点击的元素
JSObject jsNd = (JSObject) nd;
JSObject bounds = (JSObject) jsNd.call("getBoundingClientRect");
Double right = Double.parseDouble(bounds.getMember("right").toString());
Double top = Double.parseDouble(bounds.getMember("top").toString());
Double bottom = Double.parseDouble(bounds.getMember("bottom").toString());
Double left = Double.parseDouble(bounds.getMember("left").toString());
nd表示org.w3c.dom中的Node类型的变量,一般来说都是Element类型的。
5.4 如何获取WebView的滚动条对象、滚动条的宽度和判断滚动条的方向
// 添加样式表,使WebView始终有滚动条
String strCss = "body {"+ " overflow-x: scroll;"+ " overflow-y: scroll;"+ "}";
Document doc = webEngine.getDocument() ;
Element styleNode = doc.createElement("style");
Text styleContent = doc.createTextNode(strCss);
styleNode.appendChild(styleContent); doc.getDocumentElement().getElementsByTagName("head").item(0).appendChild(styleNode);
// 获取水平、垂直滚动条的宽度
ObservableList<javafx.scene.Node> lst = webView.getChildrenUnmodifiable();
for(javafx.scene.Node n : lst){if (ScrollBar.class.isInstance(n)) {ScrollBar scroll = (ScrollBar) n;if(scroll.getParent() == webView){ scroll.valueProperty().addListener(scrollChangeListener);if(dScrollBarHHeight == -1 && scroll.getOrientation() == Orientation.HORIZONTAL){dScrollBarHHeight = scroll.getLayoutBounds().getHeight();}if(dScrollBarVWidth == -1 && scroll.getOrientation() == Orientation.VERTICAL){dScrollBarVWidth = scroll.getLayoutBounds().getWidth();}}}
}
注意:JavaFX元素的OnScroll事件和传统的窗体的事件不同,因为其兼容考虑移动设备的手势滑动,所以,对WebView直接绑定Scroll事件是无效的。
5.5 如何在拖拽窗体、最大化窗体等改变窗口大小时,获取WebView中的元素坐标位置
// 监听webView的大小是否发生变化,变化时,重绘所有的矩形
webView.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {@Overridepublic void changed(ObservableValue<? extends Bounds> observableValue, Bounds oldValue, Bounds newValue) {// 采用延迟一点时间,获取坐标进行绘制,是因为窗口变化时,WebView对控件进行排版,这个事件暂时不知道怎么控制animationRect.play();}
});
// 获取水平、垂直滚动条的宽度
ObservableList<javafx.scene.Node> lst = webView.getChildrenUnmodifiable();for(javafx.scene.Node n : lst){if (ScrollBar.class.isInstance(n)) {ScrollBar scroll = (ScrollBar) n;if(scroll.getParent() == webView){scroll.valueProperty().addListener(scrollChangeListener);if(dScrollBarHHeight == -1 && scroll.getOrientation() == Orientation.HORIZONTAL){dScrollBarHHeight = scroll.getLayoutBounds().getHeight();}if(dScrollBarVWidth == -1 && scroll.getOrientation() == Orientation.VERTICAL){dScrollBarVWidth = scroll.getLayoutBounds().getWidth();}}}}
// 监听是否有新的控制条产生
webView.getChildrenUnmodifiable().addListener(new ListChangeListener<javafx.scene.Node>() {public void onChanged(Change<? extends javafx.scene.Node> c) {while (c.next()) {// 如果是增加元素if (c.wasAdded()) {for (javafx.scene.Node ndTemp : c.getAddedSubList()) {if (ScrollBar.class.isInstance(ndTemp)) {ScrollBar scroll = (ScrollBar) ndTemp;if (scroll.getParent() == webView) {scroll.valueProperty().addListener(scrollChangeListener);if(dScrollBarHHeight == -1 && scroll.getOrientation() == Orientation.HORIZONTAL){dScrollBarHHeight = scroll.getLayoutBounds().getHeight();}if(dScrollBarVWidth == -1 && scroll.getOrientation() == Orientation.VERTICAL){dScrollBarVWidth = scroll.getLayoutBounds().getWidth();}}}}}}}
});
// WebView中的滚动条,滚动时对应的事件final ChangeListener<Number> scrollChangeListener = new ChangeListener<Number>() {@Override public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue) {drawRectangle();}};
// 窗体大小改变时,重绘所有矩形的动画Timeline animationRect = new Timeline(new KeyFrame(Duration.seconds(0.05), // 动画操作被调用后的延时时间new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent actionEvent) {drawRectangle();}}));
定义动画操作,用于延迟50ms后,进行所有Rectangle重绘,同时设置循环执行次数是1次。
// 设置动画动作的循环次数
animationRect.setCycleCount(1);
5.6 对于已生成的Document文档对象,如何在Java中监听网页中对应DOM树的结构的变化
JSObject jsWin = (JSObject)webEngine.executeScript("window");
jsWin.setMember("cn_edu_hitsz_ices_automaticExtractor", cn_edu_hitsz_ices_automaticExtractor);
// 设置DOM树发生结构时,回调修改TreeView的脚本
String strScript = "var MutationObserver = window.MutationObserver ||" // 获取MutationObserver对象+" window.WebKitMutationObserver || "+" window.MozMutationObserver;"+" var mutationObserverSupport = !!MutationObserver;"// DOM被修改时,具体被调用的文本+" var callback = function(records){"+" cn_edu_hitsz_ices_automaticExtractor.callDomChanged(records);"+" console.log('MutationObserver callback');"+" records.map(function(record){"+" console.log('Mutation type: '+ record);"+" });"+" };"+" var option = {"
// +" 'attributes': true," // 对属性的变化不进行监听+" 'childList': true, "
// +" 'characterData':true," // 文本内容变化不进行监听+" 'subtree': true"+" };"+" var mo = new MutationObserver(callback);"+" mo.observe(document.body, option);";
// 执行脚本,注册回调
webEngine.executeScript(strScript);
webEngine是WebEngine的具体对象。这个函数是注册MutationObserver对DOM结构变化的监听回调。
public class Cn_Edu_Hitsz_Ices_AutomaticExtractor{// 这个地方还需要优化,因为Mutation事件记录了哪些Node发生变化(包括,被删除,被添加,属性被修改),可以通过判断,动态修改树,而不是直接全部重构右侧树public void callDomChanged(JSObject obj){buildRightTreeView();}}
5.7 如何对JavaFX生成的DOM对象,进行XPath操作
// 将org.w3c.dom中的Document转换成dom4j中的Document
public org.dom4j.Element convert( Document doc) throws ParserConfigurationException
{// Convert w3c document to dom4j documentorg.dom4j.io.DOMReader reader = new org.dom4j.io.DOMReader();org.dom4j.Document docNew = reader.read(doc);return docNew.getRootElement();
}
// 下面是利用java标准的api执行xpath获取操作,不过这个对于JavaFX产生的DOM是不可行的,因为JavaFX的tag是大写的,而XPath是小写的,好像是因为这个原因。
public List<String[]> TestInformationExtraction_Old(Document doc){XPathFactory xpfactory = XPathFactory.newInstance();XPath path = xpfactory.newXPath();try{System.out.println(doc.getNodeName());NodeList nodes = (NodeList)path.evaluate("//div", doc, XPathConstants.NODESET);System.out.println("结果:"+nodes.getLength());}catch(Exception ex){ex.printStackTrace();}return null;
}
这个是标准的使用XPath对org.w3c.dom进行搜索定位。因为对于WebEngine产生的Document没有用,所以工程中给注释掉了。
// 获取下一页的按钮
JSObject eTarget = null;
Element page = doc.getElementById("AspNetPager1");
if(page != null){JSObject express = (JSObject)webEngine.executeScript("document.createExpression(\"//a[@class='mypaper']\")");JSObject jsNodeList = (JSObject)express.call("evaluate", page, "XPathResult.ANY_TYPE");Element eTemp = null;while((eTemp = (Element)jsNodeList.call("iterateNext")) != null){if(eTemp.getTextContent().compareTo("[下一页]") == 0){eTarget = (JSObject)eTemp;break;}}
}
if(eTarget != null){eTarget.call("click");
}
5.8 Java如何执行WebView渲染网页中的按钮自动点击操作,比如“下一页”自动点击下一页,“百度一下”自动进行搜索
JSObject btn = (JSObject)dom.getElementById("su");
JSObject text = (JSObject)dom.getElementById("kw");
text.setMember("value", "哈工大深研院");
btn.call("click");
dom是从WenEngine中获取的Document文档,上述是模拟在百度首页搜索框中输入“哈工大深研院”后自动点击搜索的功能。
((EventTarget)btn).addEventListener("click", new EventListener() {public void handleEvent(Event ev) {System.out.println("Hello World!");}
}, false);
6、附件
- 基于JavaFX的可视化信息抽取Demo,说明:工程默认是采用GBK编码格式的,导入时请注意,否则相应注释会出现乱码。
我的eclipse下载的是直接集成JavaFX开发环境的版本,下载链接是:http://downloads.efxclipse.bestsolution.at/downloads/released/2.3.0/sdk/eclipse-SDK-4.5.2-win32-x86_64-distro-2.3.0.zip因为这个工程不涉及到FXML的布局,只是简单的Java代码,所以如果你不想用定制版,想用原先的eclipse,简单设置一下JDK规则也可以,默认eclipse不开放对JavaFX的访问,设置方法如下:
- Build Path -》 Configure Build Path… -》 Libraries,如下图:
- 添加允许的规则,如下图:
- 然后点击OK即可。代码便可在eclipse正常运行了。注意,工程不涉及任何第三方包,都是利用JDK自带的JavaFX包进行编写的。
- Build Path -》 Configure Build Path… -》 Libraries,如下图:
- Oracle提供的一些JavaFX的demo代码,这里面包括了所有的关于JavaFX的基础使用样例,不是仅局限于WebView的使用。下载网址:javafx_samples-8u102-ea-b04-windows-25_apr_2016
参考文献汇总
- JAVAFX中文资料:http://www.javafxchina.net/blog/docs/tutorial1/
- JavaFX: Getting Started with JavaFX:http://docs.oracle.com/javase/8/javafx/get-started-tutorial/index.html
- Java Platform, Standard Edition (Java SE) 8相关资料(含JavaFX:http://docs.oracle.com/javase/8/index.html
- JavaFX 2.0的API文档:http://docs.oracle.com/javafx/2/api/
- JavaFX CSS Reference Guide:https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html
- JavaFX 2.0 Resizing of UI Controls:http://blog.e-zest.net/javafx-20-resizing-of-ui-controls/
- 【CSS进阶】原生JS getComputedStyle等方法解析:http://www.tuicool.com/articles/M7fyQv6
- vips_java:https://github.com/tpopela/vips_java
- XPath expressions are evaluated incorrectly:https://bugs.openjdk.java.net/browse/JDK-8090173
- Converting org.w3c.dom.Document into org.dom4j.Document:https://community.oracle.com/thread/2051697?start=0&tstart=0
- JAVAFX-事件:http://blog.csdn.net/ice00mouse/article/details/25491565
- How to make an overlay on top of JavaFX 2 webview?:http://stackoverflow.com/questions/10894903/how-to-make-an-overlay-on-top-of-javafx-2-webview
- 使用JavaFX UI组件 -> 列表视图(LIST VIEW):http://www.javafxchina.net/blog/2015/04/doc03_list-view/
- How to listen for resize events in JavaFX:http://stackoverflow.com/questions/10773000/how-to-listen-for-resize-events-in-javafx/25812859#25812859
- 使用JavaFX UI组件 -> 树视图(TREE VIEW):http://www.javafxchina.net/blog/2015/04/doc03_treeview/
- HTML5新特性之Mutation Observer:http://www.cnblogs.com/jscode/p/3600060.html
- Is there a JavaScript/jQuery DOM change listener?:http://stackoverflow.com/questions/2844565/is-there-a-javascript-jquery-dom-change-listener/11546242#11546242
- XML DOM - XPathExpression 对象:http://www.w3school.com.cn/xmldom/dom_xpathexpression.asp
- js-dom2高级事件列表:http://www.cnblogs.com/lianzi/archive/2011/09/17/2179735.html
- Is it possible to retrieve HTML element in web engine without using Javascript?:http://stackoverflow.com/questions/31957218/is-it-possible-to-retrieve-html-element-in-web-engine-without-using-javascript
- Detect DOM changes with Mutation Observers:https://developers.google.com/web/updates/2012/02/Detect-DOM-changes-with-Mutation-Observers?hl=en
JavaFX和可视化信息抽取相关推荐
- 关于NLP相关技术全部在这里:预训练模型、图神经网络、模型压缩、知识图谱、信息抽取、序列模型、深度学习、语法分析、文本处理...
NLP近几年非常火,且发展特别快.像BERT.GPT-3.图神经网络.知识图谱等技术应运而生. 我们正处在信息爆炸的时代.面对每天铺天盖地的网络资源和论文.很多时候我们面临的问题并不是缺资源,而是找准 ...
- 【ACL2020】这8份Tutorial不可错过!包括:常识推理、多模态信息抽取、对话、解释性等...
点击上方,选择星标或置顶,不定期资源大放送! 阅读大概需要7分钟 Follow小博主,每天更新前沿干货 自然语言处理领域顶级会议 ACL 2020 将于 7 月 5 日至 10 日在线上举行.本届 A ...
- 详解预训练模型、图神经网络、模型压缩、知识图谱、信息抽取、序列模型、深度学习、语法分析、文本处理...
NLP近几年非常火,且发展特别快.像BERT.GPT-3.图神经网络.知识图谱等技术应运而生.我们正处在信息爆炸的时代.面对每天铺天盖地的网络资源和论文.很多时候我们面临的问题并不是缺资源,而是找准资 ...
- 面向知识图谱的信息抽取
面向知识图谱的信息抽取 人工智能技术与咨询 点击蓝字 · 关注我们 来源:< 数据挖掘,> ,作者赵海霞等 关键词: 知识图谱:信息抽取:实体抽取:关系抽取:开放域 摘要: 摘要: 随着大 ...
- 百分点认知智能实验室:基于不完全标注样本集的信息抽取实践
编者按 信息抽取是从文本数据中抽取特定信息的一种技术,命名实体识别(Named Entity Recognition, NER)是信息抽取的基础任务之一,其目标是抽取文本中具有基本语义的实体单元,在知 ...
- NLP专栏简介:数据增强、智能标注、意图识别算法|多分类算法、文本信息抽取、多模态信息抽取、可解释性分析、性能调优、模型压缩算法等
NLP专栏简介:数据增强.智能标注.意图识别算法|多分类算法.文本信息抽取.多模态信息抽取.可解释性分析.性能调优.模型压缩算法等 专栏链接:NLP领域知识+项目+码源+方案设计 订阅本专栏你能获得什 ...
- 深度学习应用篇-自然语言处理[10]:N-Gram、SimCSE介绍,更多技术:数据增强、智能标注、多分类算法、文本信息抽取、多模态信息抽取、模型压缩算法等
[深度学习入门到进阶]必看系列,含激活函数.优化策略.损失函数.模型调优.归一化算法.卷积模型.序列模型.预训练模型.对抗神经网络等 专栏详细介绍:[深度学习入门到进阶]必看系列,含激活函数.优化策略 ...
- 【PaddleOCR-kie】关键信息抽取1:使用VI-LayoutXLM模型推理预测(SER+RE)
背景:在训练自己数据集进行kie之前,想跑一下md里面的例程,但md教程内容混乱,而且同一个内容有多个手册,毕竟是多人合作的项目,可能是为了工程解耦,方便更新考虑--需要运行的模型和运行步骤散落在不用 ...
- 第三届“达观杯”文本智能信息抽取挑战赛丰厚奖金,群英集结,等你来战!...
近日,第三届"达观杯"文本智能信息抽取挑战赛正式上线启动(点击阅读原文,跳转报名页面),6月28日至8月31日,面向所有参赛选手开放竞赛结果提交.本届"达观杯" ...
最新文章
- 学习web前端你必须要了解的主流框架!
- BFS之三(单向bfs和康托压缩)
- java io 网络编程_[笔面] Java IO和网络编程相关面试
- Java黑皮书课后题第8章:*8.23(游戏:找到翻转的单元格)假定给定一个填满0和1的6*6矩阵,所有的行和列都有偶数个1。让用户翻转一个单元,编写一个程序找到哪个单元格被翻转了
- oracle主从表分离怎么实时更新数据_高可用数据库UDB主从复制延时的解决
- Fixed Function Shader
- Undefined control sequence.l.113 \LinesNumbered
- App开发流程之图像处理工具类
- php led显示屏控制软件下载,中航led控制软件
- opengl 知识点2
- 解放生产力!20 个必知必会 VSCode 小技巧
- html5动漫动态背景图片,简单动画-让你的背景图动起来!!!
- 分享一个简易的AT变速箱(TCU)换挡逻辑控制模型
- 新玺配资:股票波段操作中的操作法则
- 自动化控制面试问题整理
- 6-27 实验9_7_设计函数int getVowel(char str[],char vowel[]); (100 分)
- 使用Optional类来消除代码中的null检查
- 330. 按要求补齐数组
- Dynamics 365 for Phones Android APK(v4.3.22042.2)下载
- 选股策略之MACD指标选股
热门文章
- 我开发过程中遇到的Echarts地图立体描边问题解决方式
- 工作了4年的JAVA程序员应该具备什么技能?
- 农业病虫害数据集与算法——调研整理
- react黑马前端学习笔记
- 第一周《人月神话》读书笔记-------黄志鹏
- uniapp附件上传及预览
- Cannot download sources Sources not found for:xxx解决方法汇总
- Python 编码错误UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xac in position 131: illegal multibyte
- 【PTA题目】7-5 阶梯电价 (15 分)
- 评论:“哭不起”的王君为何还流泪