精华内容
下载资源
问答
  • 自然语言处理实战 TextCNN文本分类

    千人学习 2020-06-26 17:47:20
    (4)通过项目案例实战,掌握TextCNN短文本分类在工业界应用,可以直接应用在如下领域 例如:对话系统意图识别,智能客服问答意图识别,资讯短文本分类等文本分类场景。 适用人群 (1)想要从事NLP的在校学生、NLP研发...
  • 自然语言处理动手学Bert文本分类

    千人学习 2020-05-30 09:41:43
    Bert作为目前自然语言处理领域最流行的技术之一,文本分类作为自然语言处理领域最常见的任务之一,Pytorch作为目前最流程的深度学习框架之一,三者结合在一起将会产生什么样的花火,本套课程基于Pytorch最新1.4版本...
  • Tensorflow项目实战-文本分类

    千人学习 2017-05-03 21:58:31
    csdn500)回复【唐宇迪】 进入学习群,获取唐宇迪老师社群答疑 Tensorflow项目实战视频培训教程,该课程使用Tensorflow从零开始完成垃圾邮件分类任务,首先讲解如何使用卷积神经网络来处理文本数据,讲解整理网络...
  • 这个链接是测试集,训练集请见我的资源 本语料库由复旦大学李荣陆提供。test_corpus.rar为测试语料,共9833篇文档;train_corpus.rar为训练语料,共9804篇文档,两个预料各分为20个相同类别。训练语料和测试语料...
  • [python] Kmeans文本聚类算法+PAC降维+Matplotlib显示聚类图像 http://blog.csdn.net/eastmount/article/details/50545937 包括输入文档txt,共1000行数据,每行都是分词完的文本。 本文主要讲述以下几点: 1.通过...
  • 基于svm的中文文本分类

    热门讨论 2014-01-01 10:34:42
    基于内容的文本分类系统 (这是一个完整的分类系统,用java写的,分词是中科院64位的分词) 详情:http://blog.csdn.net/yinchuandong2/article/details/17717449 使用libsvm 进行分类 使用中科院的分词器ICTLAS对...
  • LTFViewr打开大文本文件工具(大于1G以上的文本文件) 解决了大文件notepad、rtf、word等工具打开超级慢甚至都不能打开的问题 本软件是分页显示,比notepad、rtf、word等工具效率高,显示效果好,大家不妨试着用用
  • 若该文为原创文章,未经允许不得转载 原博主博客地址:...本文章博客地址: 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 目录 前话 文本光标接口 概述 基于光标的编辑 ...

    若该文为原创文章,未经允许不得转载
    原博主博客地址:https://blog.csdn.net/qq21497936
    原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
    本文章博客地址:https://blog.csdn.net/qq21497936/article/details/105595018
    各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

    红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)

    Qt开发专栏:开发技术(点击传送门)

    Qt开发技术:Qt富文本(一)富文本介绍、文档结构

    Qt开发技术:Qt富文本(二)Qt文本光标操作、文档布局、富文本编辑、处理和Demo

    Qt开发技术:Qt富文本(三)Qt支持的HTML子集(查询手册)以及涉及的类

     

    前话

          红胖子,来也!

          Qt的富文本技术介绍,文本光标操作、文档布局、富文本常用操作和处理大文件富文本。

     

    文本光标接口

    概述

    文档可以通过QTextCursor类提供的接口进行编辑。

    光标可以使用构造函数创建,也可以从编辑器小部件获取。光标用于执行编辑操作,这些操作与用户能够在编辑器中创建的操作完全对应。因此,有关文档结构的信息也可以通过光标获得,这允许修改结构。使用面向光标的界面进行编辑使编写自定义编辑器的过程对开发人员来说更加简单,因为编辑操作可以很容易地可视化。

    QTextCursor类还维护它在文档中选择的任何文本的信息,同样遵循一个模型,该模型在概念上类似于用户在编辑器中选择文本的操作。

    富文本文档可以有多个与之关联的光标,每个光标都包含有关它们在文档中的位置以及它们可能保存的任何选择的信息。这种基于光标的范例使常见的操作(如剪切和粘贴文本)易于编程实现,但也允许对文档执行更复杂的编辑操作。

    基于光标的编辑

    在最简单的级别上,文本文档是由一个字符串组成的,这些字符串以某种方式标记以表示文档中文本的块结构。QTextCursor提供了一个基于光标的接口,允许在字符级别操作QTextDocument的内容。由于元素(块、文本框架、表等)也被编码在字符流中,文档结构本身可以被光标更改。

    光标跟踪其父文档中的位置,并可以报告有关周围结构的信息,例如封闭文本块、框架、表或列表。封闭结构的格式也可以通过光标直接获得。

    使用光标

    光标的主要用途是在块中插入或修改文本。我们可以使用文本编辑器的光标执行以下操作:

    QTextEdit *editor = new QTextEdit();
    QTextCursor cursor(editor->textCursor());
    

    或者,直接从文档获取光标:

    QTextDocument *document = new QTextDocument(editor);
    QTextCursor cursor(document);
    

    光标位于文档的开头,以便我们可以写入文档中的第一个(空)块。

    分组光标操作

    一系列编辑操作可以打包在一起,以便在单个操作中可以将它们一起重放或撤消。这是通过以下方式使用beginEditBlock()和endEditBlock()函数实现的,如下例中,我们选择包含光标的单词:

    cursor.beginEditBlock();
    cursor.movePosition(QTextCursor::StartOfWord);
    cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
    cursor.endEditBlock();
    

    如果编辑操作未分组,则文档会自动记录各个操作,以便以后可以撤消这些操作。将操作分组到更大的包中可以提高用户和应用程序的编辑效率,但必须注意不要将太多操作分组在一起,因为用户可能希望找到对撤消过程的粒度控制。

    多个光标

    可以使用多个光标同时编辑同一文档,尽管用户在QTextEdit小部件中只能看到一个光标。QTextDocument确保每个光标正确地写入文本,并且不会干扰任何其他光标。

    插入文档元素

    QTextCursor提供了几个函数,可用于更改富文本文档的结构。通常,这些函数允许使用相关的格式信息创建文档元素,并将这些元素插入到光标所在位置的文档中。

    第一组函数插入块级元素并更新光标位置,但不返回插入的元素:

    • insertBlock()将新的文本块(段落)插入到文档中光标所在的位置,并将光标移动到新块的开头。
    • insertFragment()将现有文本片段插入光标所在位置的文档中。
    • insertImage()将图像插入光标所在位置的文档中。
    • insertText()在文档的光标位置插入文本。

    可以检查通过光标接口插入的元素的内容。

    第二组函数插入为文档提供结构的元素,并返回插入的结构:

    • insertFrame()将文本框架插入到文档中光标当前块之后,并将光标移动到新框架中空块的开始处。
    • insertList()在文档的光标位置插入一个列表,并将光标移动到列表中第一个项的开头。
    • insertTable()光标的当前块之后将表插入到文档中,并将光标移动到表之后的块的开头。

    包含或组合文档中的其他元素。

    文本和文本片段

          文本可以以当前字符格式或用文本指定的自定义格式插入到当前块中:

    cursor.insertText(tr("Character formats"), headingFormat);
    cursor.insertBlock();
    cursor.insertText(tr("Text can be displayed in a variety of "
                    "different character formats. "), plainFormat);
    cursor.insertText(tr("We can emphasize text by "));
    cursor.insertText(tr("making it italic"), emphasisFormat);
    

    一旦字符格式与光标一起使用,该格式将成为随光标插入的任何文本的默认格式,直到指定了其他字符格式。

    如果使用光标插入文本而不指定字符格式,则将为文本提供文档中该位置使用的字符格式。

    文本块:QTextBlock

          文本块使用insertBlock()函数插入到文档中。

    QTextBlockFormat backgroundFormat = blockFormat;
    backgroundFormat.setBackground(QColor("lightGray"));
    cursor.setBlockFormat(backgroundFormat);
    

    文本文本框架:QTextFrame

          使用光标插入到文档中,并将放置在当前块之后光标的当前框架内。下面的代码演示如何在文档根框架中的两个文本块之间插入框架。我们首先找到光标的当前文本框架:

    QTextFrame *mainFrame = cursor.currentFrame();
    cursor.insertText(...);
    

          在此文本框架中插入一些文本,然后为子文本框架设置框架格式:

    QTextFrameFormat frameFormat;
    frameFormat.setMargin(32);
    frameFormat.setPadding(8);
    frameFormat.setBorder(4);
    

    文本框架格式将为文本框架提供32像素的外部边距、8像素的内部填充和4像素宽的边框。有关文本框架格式的详细信息,请查看QTextFrameFormat。

    文本框架将在前面的文本之后插入到文档中:

    cursor.insertFrame(frameFormat);
    cursor.insertText(...);
    

    在插入框架后立即向文档中添加一些文本。由于文本光标插入文档时位于文本框架内,因此此文本也将插入文本框架内。

    最后,将光标放置在文本框架外,方法是在前面记录的文本框架内获取最后一个可用的光标位置:

    cursor = mainFrame->lastCursorPosition();
    cursor.insertText(...);
    

    最后添加的文本将插入文档的子框架之后。由于每个文本框架都用文本块填充,这确保了可以始终用光标插入更多的元素。

    表格:QTextTable

    表格使用光标插入到文档中,并将放置在当前块之后光标的当前文本框架中:

    QTextCursor cursor(editor->textCursor());
    QTextTable *table = cursor.insertTable(rows, columns, tableFormat);

    可以使用特定格式创建表,该格式定义表的总体属性,例如其对齐方式、背景颜色和使用的单元格间距。它还可以确定每列上的约束,允许每列具有固定的宽度,或者根据可用空间调整大小。

    QTextTableFormat tableFormat;
    tableFormat.setBackground(QColor("#e0e0e0"));
    QVector<QTextLength> constraints;
    constraints << QTextLength(QTextLength::PercentageLength, 16);
    constraints << QTextLength(QTextLength::PercentageLength, 28);
    constraints << QTextLength(QTextLength::PercentageLength, 28);
    constraints << QTextLength(QTextLength::PercentageLength, 28);
    tableFormat.setColumnWidthConstraints(constraints);
    QTextTable *table = cursor.insertTable(rows, columns, tableFormat);

    上面创建的表中的列各占可用宽度的一定百分比。请注意,表格式是可选的;如果插入的表没有格式,则表的属性将使用一些合理的默认值。

    由于单元格可以包含其他文档元素,因此也可以根据需要对其进行格式化和样式设置。

    通过使用光标导航到每个单元格并插入文本,可以将文本添加到表中。

    cell = table->cellAt(0, 0);
    cellCursor = cell.firstCursorPosition();
    cellCursor.insertText(tr("Week"), charFormat);
    

    可以通过以下方法创建一个简单的时间表:

    for (column = 1; column < columns; ++column)
    {
        cell = table->cellAt(0, column);
        cellCursor = cell.firstCursorPosition();
        cellCursor.insertText(tr("Team %1").arg(column), charFormat);
    }
    for (row = 1; row < rows; ++row)
    {
        cell = table->cellAt(row, 0);
        cellCursor = cell.firstCursorPosition();
        cellCursor.insertText(tr("%1").arg(row), charFormat);
        for (column = 1; column < columns; ++column)
        {
            if ((row-1) % 3 == column-1)
            {
                cell = table->cellAt(row, column);
                QTextCursor cellCursor = cell.firstCursorPosition();
                cellCursor.insertText(tr("On duty"), charFormat);
            }
        }
    }
    

    上面的代码首先检查光标是否在现有列表中,如果是,则为新列表的列表格式提供适当的缩进级别。这允许创建嵌套列表,并增加缩进级别。一个更复杂的实现还将使用不同类型的符号来表示列表中每个级别的要点。

    图像:QTextImageFormat

    内联图像以通常的方式通过光标添加到文档中。与许多其他元素不同,所有图像属性都由图像的格式指定。这意味着必须先创建QTextImageFormat对象,然后才能插入图像:

    QTextImageFormat imageFormat;
    imageFormat.setName(":/images/advert.png");
    cursor.insertImage(imageFormat);
    

    图片名称指的是应用程序资源文件中的一个条目(:/xxxx)。Qt资源系统中描述了用于派生此名称的方法。

    示例:createCalendarDemo

    效果

    关键代码

    修改富文本

    void CalendarWidget::modifyRichText()
    {
        ui->textEdit_dst->setText(ui->textEdit_src->toHtml());
        QTextDocument *pDocument = ui->textEdit_dst->document();
        // 获取光标
        QTextCursor cursor(pDocument);
        // 光标移动到最开始
        cursor.movePosition(QTextCursor::Start);
        // 光标移动到本行末尾,保持光标原来的位置,这样等于选中了本行
        cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
        // 设置字体加速
        QTextCharFormat format;
        format.setFontWeight(QFont::Bold);
        cursor.mergeCharFormat(format);
    
        // 再移动到网页链接的(0、1、2,第三行),斜体,加粗,红色,24号字体
        // 光标移动到最开始
        cursor.movePosition(QTextCursor::Start);
        // 光标移动2次,第3行,下标为2(0,1,2)
        cursor.movePosition(QTextCursor::NextBlock);
        cursor.movePosition(QTextCursor::NextBlock);
        // 光标移动到本行末尾,保持光标原来的位置,这样等于选中了本行
        cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
        // 设置字体斜体、加粗、红色
        QTextCharFormat format2;
        QFont font = format2.font();
        // 斜体
        font.setStyle(QFont::StyleItalic);
        // 粗体
        font.setBold(true);
        // 字体大小:24号
        font.setPixelSize(24);
        // 前景色:黑色
        format2.setForeground(QBrush(Qt::red));
        format2.setFont(font);
        cursor.mergeCharFormat(format2);
    
        // 光标移动到最开始
        cursor.movePosition(QTextCursor::Start);
        // 光标移动4次,第5行,下标为2(0,1,2,3,4)
        cursor.movePosition(QTextCursor::NextBlock);
        cursor.movePosition(QTextCursor::NextBlock);
        cursor.movePosition(QTextCursor::NextBlock);
        cursor.movePosition(QTextCursor::EndOfBlock);
        cursor.insertBlock();
        // 插入图片
        QTextImageFormat textImageFormat;
        textImageFormat.setName(":/images/images/1.jpg");
        textImageFormat.setHeight(200);
        textImageFormat.setWidth(200);
        cursor.insertImage(textImageFormat);
        // 插入gif,显示时,没有动画
        textImageFormat.setName(":/images/images/1.gif");
        cursor.insertImage(textImageFormat);
    }
    

    生成日历

    void CalendarWidget::createCalendar()
    {
        QTextEdit *pEditor = ui->textEdit_canlendar;
    
        // 获取光标
        QTextCursor cursor(pEditor->textCursor());
        cursor.movePosition(QTextCursor::Start);
    
        // 获取光标的字符属性1,设置了字体
        QTextCharFormat format(cursor.charFormat());
        format.setFontFamily("Courier");
    
        // 获取光标的字符属性2,设置了字体,加粗了字体
        QTextCharFormat boldFormat = format;
        boldFormat.setFontWeight(QFont::Bold);
    
        // 插入空文本块(可理解为插入一个空行),从第0行开始,光标插入空文本块后,第0行为空行,光标到达第1行
        cursor.insertBlock();
        // 插入空格(带不带字体没什么关系)
        cursor.insertText(" ");
        cursor.insertText(" ", boldFormat);
    
        // 计算日期
        QDate date = QDate::currentDate();
        int year = date.year(), month = date.month();
    
        // 插入 星期几
        for (int weekDay = 1; weekDay <= 7; ++weekDay)
        {
            cursor.insertText(QString("%1").arg(QDate::shortDayName(weekDay), 3),
                              boldFormat);
        }
    
        // 插入空行
        cursor.insertBlock();
        cursor.insertText(" ", format);
    
        // 插入缺少的日子,空格占位
        for (int column = 1; column < QDate(year, month, 1).dayOfWeek(); ++column)
        {
            cursor.insertText("   ", format);
        }
    
        // 插入本月的日期
        for (int day = 1; day <= date.daysInMonth(); ++day)
        {
            int weekDay = QDate(year, month, day).dayOfWeek();
    
            if (QDate(year, month, day) == date)
            {
                // 今天的日期,就加粗
                cursor.insertText(QString("%1 ").arg(day, 3), boldFormat);
            }else
            {
                cursor.insertText(QString("%1 ").arg(day, 3), format);
            }
    
            // 第七天,则另起一行
            if (weekDay == 7)
            {
                cursor.insertBlock();
                cursor.insertText("   ", format);
            }
        }
    }
    

     

    文档布局

    概述

    文档的布局仅在要在设备上显示时才相关,或者在请求某些需要文档可视化表示的信息时才相关。在此之前,不需要为设备格式化和准备文档。

    每个文档的布局都由QAbstractTextDocumentLayout类的一个子类管理。这个类为布局和呈现引擎提供了一个公共接口。默认呈现行为当前在私有类中实现。

    这种方法使创建自定义布局成为可能,并提供了在准备打印页面或导出为可移植文档格式(PDF)文件时使用的机制。

    示例:LayoutDemo

    关键代码

    (在paintEvent中调用该函数)

    void LayoutWidget::paintLayout()
    {
        QString text = "Hello world!!!";
        for(int index = 0; index < 200; index++)
        {
            text += "Hello world!!!";
        }
        QFont font = this->font();
        QTextLayout textLayout(text, font);
        qreal margin = 10;
        qreal radius = qMin(width()/2.0, height()/2.0) - margin;
        QFontMetrics fm(font);
    
        qreal lineHeight = fm.height();
        qreal y = 0;
    
        textLayout.beginLayout();
    
        while(true)
        {
            // 创建一根直线
            QTextLine line = textLayout.createLine();
            if (!line.isValid())
            {
                break;
            }
            // 计算椭圆有边界x的值
            qreal x1 = qMax(0.0, pow(pow(radius,2)-pow(radius-y,2), 0.5));
            qreal x2 = qMax(0.0, pow(pow(radius,2)-pow(radius-(y+lineHeight),2), 0.5));
            qreal x = qMax(x1, x2) + margin;
            qreal lineWidth = (width() - margin) - x;
    
            // 设置每一行textLine的右边的开始坐标
            line.setLineWidth(lineWidth);
            line.setPosition(QPointF(x, margin+y));
            y += line.height();
        }
    
        textLayout.endLayout();
    
        QPainter painter;
        painter.begin(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.fillRect(rect(), Qt::white);
        painter.setBrush(QBrush(Qt::black));
        painter.setPen(QPen(Qt::black));
        textLayout.draw(&painter, QPoint(0,0));
    
        painter.setBrush(QBrush(QColor("#a6ce39")));
        painter.setPen(QPen(Qt::black));
        painter.drawEllipse(QRectF(-radius, margin, 2*radius, 2*radius));
        painter.end();
    }
    

     

    常见的富文本编辑任务

    概述

    在使用Qt编辑和处理文本文档时,开发人员经常执行许多任务。其中包括使用显示小部件,如QTextBrowser和QTextEdit,使用QTextDocument创建文档,使用QTextCursor编辑,以及导出文档结构

    常见编辑任务

    使用QTextEdit

    可以构造文本编辑器小部件,并使用它以以下方式显示HTML:

    QTextEdit *editor = new QTextEdit(parent);
    editor->setHtml(aStringContainingHTMLtext);
    editor->show();
    

    默认情况下,文本编辑器包含一个带有根框架的文档,其中包含一个空文本块。本文件可通过以下方式获取,以便直接由应用程序修改:

    QTextDocument *document = editor->document();

    文本编辑器的光标也可用于编辑文档:

    QTextCursor cursor = editor->textCursor();

    虽然可以同时使用多个光标编辑文档,但QTextEdit一次只显示一个光标(闪光标)。因此,如果要更新编辑器以显示特定光标或其选择,则需要在修改文档后设置编辑器光标:

    editor->setTextCursor(cursor);

    选择文本

    通过使用类似于用户在文本编辑器中执行的操作移动光标来选择文本。要在文档中的两点之间选择文本,需要将光标定位在第一点,然后使用带有移动操作(QTextCursor::MoveOperation)的特殊模式(QTextCursor::MoveMode)移动它。

    当我们选择文本时,我们将选择锚定保留在旧的光标位置,就像用户在选择文本时按住Shift键一样:

    cursor.movePosition(QTextCursor::StartOfWord);
    cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
    

    在上面的代码中,使用此方法选择整个单词。QTextCursor提供了许多常用的移动操作,用于选择单个字符、单词、行和整个块。

    查找文本

    QTextDocument提供了一个基于光标的搜索界面,使得在文本编辑器的样式中很容易找到和修改文本。以下代码查找文档中特定单词的所有实例,并更改每个实例的颜色:

    QTextCursor newCursor(document);
    while (!newCursor.isNull() && !newCursor.atEnd())
    {
        newCursor = document->find(searchString, newCursor);
        if (!newCursor.isNull())
        {
            newCursor.movePosition(QTextCursor::WordRight,
                                 QTextCursor::KeepAnchor);
            newCursor.mergeCharFormat(colorFormat);
        }
    }
    

    请注意,在每次搜索和替换操作之后,不必移动光标;它始终位于刚刚替换的单词的末尾。

    打印文档

    QTextEdit是为显示在屏幕上读取的大型富文本文档而设计的,其呈现方式与web浏览器相同。因此,它不会自动将文档内容分成适合打印的页面大小的部分。

    QTextDocument提供了print()函数,允许使用QPrinter类打印文档。下面的代码演示如何在QTextEdit中准备文档以便使用QPrinter打印:

    QTextDocument *document = editor->document();
    QPrinter printer;
    QPrintDialog *dlg = new QPrintDialog(&printer, this);
    if (dlg->exec() != QDialog::Accepted)
    {
       return;
    }
    document->print(&printer);
    

    从文本编辑器获取文档,然后使用QPrintDialog构造QPrinter并进行配置。如果用户接受打印机的配置,则使用print()函数格式化并打印文档。

     

    高级富文本

    处理大文件

    Qt不限制用于文本处理的文件的大小。在大多数情况下,这不会造成问题。但是,对于特别大的文件,可能会遇到应用程序将变得无响应或内存不足的情况。可以加载的文件大小取决于硬件、Qt和应用程序的实现。

    面临此问题,建议采取以下解决方案:

    • 考虑将大段落分解成小段落,因为Qt更好地处理小段落。可以按固定的间隔插入换行符,这看起来与QTextEdit中的一个大段落相同。
    • 可以使用maximumBlockCount()减少QTextDocument中的块数量。就QTextEdit而言,文档只与块的数量一样大。
    • 将文本添加到文本编辑时,将其添加到编辑块中是一种优势(请参见下面的示例)。结果是文本编辑不需要一次构建整个文档结构。

    给出了以上最后一种技术的示例代码,假设文本编辑是可见的:

    textEdit.show();
    textCursor.beginEditBlock();
    for (int i = 0; i < 1000; ++i)
    {
        textCursor.insertBlock();
        textCursor.insertText(paragraphText.at(i));
    }
    textCursor.endEditBlock();
    

     

    工程模板v1.0.0

    富文本工程模板v1.0.0:附带2个子Demo。

     

    下载工程模板

    CSDN:https://download.csdn.net/download/qq21497936/12336683

    QQ群:1047134658(点击“文件”搜索“qtRichTextDemo”,群内与博文同步更新所有可开源的源码模板)

     

    原博主博客地址:https://blog.csdn.net/qq21497936
    原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
    本文章博客地址:https://blog.csdn.net/qq21497936/article/details/105595018

    展开全文
  • 该资源主要参考我的博客:word2vec词向量训练及中文文本相似度计算 http://blog.csdn.net/eastmount/article/details/50637476 其中包括C语言的Word2vec源代码(从官网下载),自定义爬取的三大百科(百度百科、互动...
  • 若该文为原创文章,未经允许不得转载 原博主博客地址:...本文章博客地址: 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 目录 前话 富文本处理 概述 富文本文档结构 ...

    若该文为原创文章,未经允许不得转载
    原博主博客地址:https://blog.csdn.net/qq21497936
    原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
    本文章博客地址:https://blog.csdn.net/qq21497936/article/details/105594953
    各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

    红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)

    Qt开发专栏:开发技术(点击传送门)

    Qt开发技术:Qt富文本(一)富文本介绍、文档结构

    Qt开发技术:Qt富文本(二)Qt文本光标操作、文档布局、富文本编辑、处理和Demo

    Qt开发技术:Qt富文本(三)Qt支持的HTML子集(查询手册)以及涉及的类

     

    前话

          红胖子,来也!

          Qt的富文本技术介绍,富文本的文档结构。

     

    富文本处理

    概述

    Scribe框架提供了一组用于读取和操作结构化富文本文档的类。与Qt中以前的富文本支持不同,新类以QTextDocument类为中心,而不是以原始文本信息为中心。这使开发人员能够创建和修改结构化富文本文档,而无需准备中间标记格式的内容。

    文档中的信息可以通过两个相互补充的接口访问:

    • 基于光标的接口用于编辑:可以使用模拟用户与编辑器交互的操作编辑文本,而不会丢失文档的底层结构。
    • 只读层次接口提供文档结构的高级描述:在执行搜索和文档导出等操作时,只读分层界面最有用。

    富文本文档结构

    概述了QTextDocument中的各种元素,并描述了它们在文档结构中的排列方式。

    文本光标接口

    QTextCursor接口解释了如何使用基于光标(光标)的接口编辑富文本文档。

    文档布局

    简要说明文档布局的作用。

    常见的富文本编辑任务

    检查一些涉及阅读或操作富文本文档的常见任务。

    高级富文本

    高级富文本处理检查高级富文本编辑任务。

    支持的HTML子集

    列出QTextDocument支持的HTML标记。

     

    富文本文档结构

    概述

    文本文档由QTextDocument类表示,该类包含有关文档的内部表示、其结构的信息,并跟踪修改以提供撤消/重做功能。

    文本文档的结构化表示将其内容表示为文本块、框架、表和其他对象的层次结构。它们为文档提供了逻辑结构,并描述了它们的内容将如何显示。通常,框架和表用于将其他结构分组,而文本块包含实际的文本信息。

    使用QTextCursor或使用编辑器小部件(如QTextEdit)以编程方式创建新元素并将其插入到文档中。创建元素时,可以为其指定特定格式;否则,它们将采用元素的光标当前格式。

    基本结构

    文档的“顶层”可能按所示的方式填充。每个文档总是包含一个根框架,并且它总是至少包含一个文本块。

    对于具有某些文本内容的文档,根框架通常包含一系列块和其他元素

    即使文本块不包含任何信息,文档中的框架和表序列始终由文本块分隔。这样可以确保新元素始终可以插入现有结构之间。

    富文本文档

    QTextDocument对象包含构造富文本文档所需的所有信息。文本文档可以通过两种互补的方式访问:作为编辑器使用的线性缓冲区,以及作为对布局引擎有用的对象层次结构。在分层文档模型中,对象通常对应于可视元素,如框架、表和列表。在较低的级别上,这些元素描述文本样式和对齐方式等属性。文档的线性表示用于编辑和操作文档内容。

    尽管QTextEdit使显示和编辑富文本变得容易,但文档也可以独立于任何编辑器小部件使用,例如:

    QTextDocument *pTextDocument = new QTextDocument;

    或者,可以从现有编辑器中提取它们:

    QTextEdit *pTextEdit = new QTextEdit;
    QTextDocument *pTextDocument = pTextEdit->document();

    这种灵活性使应用程序能够处理多个富文本文档,而无需多个编辑器小部件的开销,或要求文档以某种中间格式存储。

    空文档包含根框架,根框架本身包含单个空文本块。框架提供了文档各部分之间的逻辑分隔,但也具有确定它们在呈现时的显示方式的属性。表格是一种特殊的框架类型,它由多个单元格组成,按行和列排列,每个单元格都可以包含进一步的结构和文本。表提供了管理和布局功能,允许创建灵活的单元格配置。

    文本块包含文本片段,每个片段指定文本和字符格式信息。文本属性是在字符级和块级定义的。在字符级别,可以指定字体系列、文本颜色和字体粗细等属性。块级特性控制文本的高级外观和行为,例如文本流的方向、对齐方式和背景颜色。

    文档结构不是直接操作的。通过基于光标的界面执行编辑。文本光标界面自动将新的文档元素插入到根框架中,并确保在必要时用空块填充。

    通过以下方式获得根框架:

    QTextDocument *textDocument;
    QTextFrame *root = textDocument->rootFrame();
    

    在导航文档结构时,从根框架开始很有用,因为它提供了对整个文档结构的访问。

    文档元素

    富文本文档通常由常见元素组成,如段落、框架、表和列表。这些在QTextDocument中由QTextBlock、QTextFrame、QTextTable和QTextList类表示。与文档中的其他元素不同,图像由特殊格式的文本片段表示。这使它们能够与周围的文本以内联格式放置。

    文档中的基本构造块是QTextBlock和QTextFrame。块本身包含富文本片段(QTextFragment),但这些片段不会直接影响文档的高级结构。

    可以将其他文档元素组合在一起的元素通常是QTextObject的子类,分为两类:

    • 将文本块组合在一起的元素是QTextBlockGroup的子类;
    • 将框架和其他元素组合在一起的元素是QTextFrame的子类。

    文本块:QTextBlock

          文本块由QTextBlock类提供。

    文本块将不同字符格式的文本片段组合在一起,用于表示文档中的段落。每个块通常包含许多具有不同样式的文本片段。在将文本插入文档时创建片段,而在编辑文档时添加更多片段。

    文档将拆分、合并和移除片段,以便有效地表示块中不同样式的文本。

    通过使用QTextBlock::iterator迭代器遍历块的内部结构,可以检查给定块中的片段:

    QTextBlock::iterator it;
    for (it = currentBlock.begin(); !(it.atEnd()); ++it) 
    {
        QTextFragment currentFragment = it.fragment();
        if (currentFragment.isValid()) 
        {
            processFragment(currentFragment);  // processFragment处理片段
        }
    }
    

    文本块还用于表示列表项。因此,块可以定义自己的字符格式,其中包含有关块级描述的信息,例如用于列表项的项目符号类型。

    文本块本身的格式由QTextBlockFormat类描述,并描述文本对齐、缩进和背景色等属性。

    尽管给定的文档可能包含复杂的结构,但一旦我们引用了文档中的有效块,我们就可以按照它们的写入顺序在每个文本块之间导航:

    QTextBlock currentBlock = textDocument->begin();
    while (currentBlock.isValid())
    {
        processBlock(currentBlock);  // processBlock处理块
        currentBlock = currentBlock.next();
    }
    

    当只想从文档中提取富文本时,此方法非常有用,因为它忽略框架、表和其他类型的结构。

    QTextBlock提供比较运算符,使操作块更容易:operator==()operator!=()用于测试两个块是否相同,而运算符operator<()用于确定文档中哪个块最先出现。

    文本框架:QTextFrame

    文本框架由QTextFrame类提供。

    文本框架将文本块和子框架组合在一起,创建大于段落的文档结构。框架的格式指定如何在页面上呈现和定位它。框架要么插入到文本流中,要么浮在页面的左侧或右侧。每个文档都包含一个根框架,其中包含所有其他文档元素。因此,除了根文本框架之外的所有文本框架都有父文本框架。

    由于文本块用于分隔其他文档元素,因此每个框架将始终至少包含一个文本块和零个或多个子框架。我们可以使用QTextFrame::iterator遍历文本框架的子元素来检查文本框架的内容:

    QDomElement frameElement = ...
    QTextFrame::iterator it;
    for (it = frame->begin(); !(it.atEnd()); ++it)
    {
        QTextFrame *childFrame = it.currentFrame();
        QTextBlock childBlock = it.currentBlock();
        if (childFrame)
        {
            processFrame(frameElement, childFrame);
        }else if (childBlock.isValid())
        {
            processBlock(frameElement, childBlock); 
        }
    }
    

    注意迭代器同时选择文本框架和块,所以有必要检查它引用的是哪个。这允许逐文本框架导航文档结构,但如果需要,仍然可以访问文本块。QTextBlock::iterator和QTextFrame::iterator类都可以互补地用于从文档中提取所需的结构。

    表格:QTextTable

    表由QTextTable类提供。

    表是按行和列排列的单元格集合。每个表单元格都是具有自己字符格式的文档元素,但也可以包含其他元素,如框架和文本块。在构造表或添加额外的行或列时,将自动创建表单元格。它们也可以在桌子之间移动。

    QTextTable是QTextFrame的一个子类,因此在文档结构中将表视为框架。对于我们在文档中遇到的每个文本框架,我们可以测试它是否表示一个表,并以不同的方式处理它:

    QDomElement frameElement = ...
    QTextFrame::iterator it;
    for (it = frame->begin(); !(it.atEnd()); ++it)
    {
        QTextFrame *childFrame = it.currentFrame();
        QTextBlock childBlock = it.currentBlock();
    if (childFrame) 
        {
            QTextTable *childTable = qobject_cast<QTextTable*>(childFrame);
            if (childTable)
            {
                processTable(frameElement, childTable);
            }
            else
            {
                processFrame(frameElement, childFrame);
            }
         } else if (childBlock.isValid())
         {
            processBlock(frameElement, childBlock);
         }
    }
    

    列表:QTextList

    列表由QTextList类提供。

    列表是按常规方式格式化的文本块序列,但也提供了标准的列表修饰,如项目符号和枚举项。列表可以嵌套,如果列表的格式指定了非零缩进,则列表将缩进。

    们可以通过列表中的索引引用每个列表项:

    for (int index = 0; index < list->count(); ++index)
    {
        QTextBlock listItem = list->item(index);
        processListItem(listItem);
    }
    

    由于QTextList是QTextBlockGroup的一个子类,因此它不将列表项分组为子元素,而是提供各种功能来管理它们。这意味着我们在遍历文档时发现的任何文本块实际上都可能是一个列表项。我们可以使用以下代码确保正确识别列表项:

    QTextFrame::iterator it;
    for (it = frame->begin(); !(it.atEnd()); ++it)
    {
        QTextBlock block = it.currentBlock();
        if (block.isValid())
        {
            QTextList *list = block.textList();
            if (list)
            {
                int index = list->itemNumber(block);
                processListItem(list, index);
            }
        }
    }
    

    图像:QTextFragment

    QTextDocument中的图像由文本片段表示,文本片段通过资源机制引用外部图像。图像是使用光标界面创建的,以后可以通过更改图像文本片段的字符格式进行修改:

    if (fragment.isValid()) 
    {
        QTextImageFormat newImageFormat = fragment.charFormat().toImageFormat();
        if (newImageFormat.isValid())
        {
            newImageFormat.setName(":/images/newimage.png");
            QTextCursor helper = cursor;
            helper.setPosition(fragment.position());
            helper.setPosition(fragment.position() + fragment.length(),
                            QTextCursor::KeepAnchor);
            helper.setCharFormat(newImageFormat);
        }
    }
    

    通过遍历包含图像的文本块中的片段,可以找到表示图像的片段。

     

    原博主博客地址:https://blog.csdn.net/qq21497936
    原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
    本文章博客地址:https://blog.csdn.net/qq21497936/article/details/105594953

    展开全文
  • 文本分类过程概述

    千次阅读 2019-01-09 19:15:11
    传统的文本分类过程通常包括训练模块和分类模块如下图所示:一般来讲文本分类过程包括预处理、文本表示、特征降维、训练分类器和分类性能评估。  文本分类过程图 1、文本分类预处理  由于计算机很难直接处...

    传统的文本分类过程通常包括训练模块和分类模块如下图所示:一般来讲文本分类过程包括预处理、文本表示、特征降维、训练分类器和分类性能评估。

                                                                                               文本分类过程图

    1、文本分类预处理

            由于计算机很难直接处理网络上存在的大量半结构化或结构化的文本数据,所以在文本分类之前需要对这些数据进行相应的预处理。

            文本的预处理包括文本分词、去除停用词(包括标点、数字和一些无意义的词)、词义消歧、统计等处理。中文与英文相比,在分类上关键的区别是在数据集的预处理阶段。对中文文本进行分类之前,首先要进行分词处理,而英文文本单词与单词之间则有空格进行分割,无需进行分词。近几年,中文文本的分词技术主要有三类:基于字符串匹配的分词方法、基于理解的分词方法和基于统计的分词。

            A、基于字符串匹配的分词方法

            该方法也成为机械分词方法,其主要思想是预想构造一个“充分大的”词典,它是按照一定的策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行匹配,若在词典中找到某个字符串,则匹配成功(识别出一个词)。按照不同的长度优先匹配的情况,可以分为最大(最长)匹配和最小(最短)匹配;按照是否与词性标注过程相结合,又可以分为单纯分词方法和分词与标注相结合的一体化方法。常用的几种机械分词方法如下:正向最大匹配法(由左到右的方向)、逆向最大匹配法(由有到左的方向)、最少切分(使每一句中切出的词数最小)。

            还可以将上述各种方法相结合,例如,可以将正向最大匹配方法和逆向最大匹配方法结合起来构成双向匹配法。由于汉语单字成词的特点,正向最小匹配和逆向最小匹配一般很少使用。一般说来,逆向匹配的切分精度略高于正向匹配,遇到的歧义现象也较少。统计结果表明,单纯使用正向最大匹配的错误率为1/169,单纯使用逆向最大匹配的错误率为1/245.但这种精度还远远不能满足实际的需要。实际使用的分词系统,都是把机械分词作为一种初分手段,还需通过利用各种其他的语言信息来进一步提高切分的准确率。

            一种方法是改进扫描方式,称为特征扫描或标志切分,优先在待分析字符串中识别和切分出一些带有明显特征的词,以这些词作为断点,可将原字符串分为较小的串再来进行机械分词,从而减少匹配的错误率。另一种方法是将分词和词类标注结合起来,利用丰富的词类信息对分词决策提供帮助,并且在标注过程中又反过来对分词结果进行检验、调整,从而极大地提高切分的准确率。

            B、基于理解的分词方法

            该方法是让计算机人工智能化,通过对句子的理解,达到对词进行识别的效果。其主要思想就是分词和句法、语义分析同时进行,利用句法信息和语义信息来处理歧义现象。它通常包括三个部分:分词子系统、句法语义子系统、总控部分。通过总控部分的协调,分词子系统获得有关词、句子的句法和语义信息来对分词歧义进行判断,即人对句子的理解过程应用到计算机上。该分词方法需要使用大量的语言知识和信息。由于汉语语言知识的庞统、复杂性,难以将各种语言信息组织成机器可直接读取的形式,因此目前基于理解的分词系统还处在试验阶段。

            C、基于统计的分词方法

    2、文本表示

            A、布尔模型

            B、向量空间模型

            C、潜在语义索引模型

            D、概率模型

    3、特征降维

            由于使用的数据集特征的集合通常非常巨大,例如DNA微阵列数据中,一条样本含有的基因维数可达到几千或者几万。Web文本数据中包含非常多的术语,维数可达到几万甚至几十万。这些数据中经常含有大量的对分类有副作用的噪声特征,假如在文本表示中使用这些特征会大大影响最终的分类效果,因此需要减少特征的维数,来提高分类的精度和文本数据的处理速度。特征选择是特征空间降维的重要方法,它从总的特征集中选择对文本分类贡献度较大的特征子集,过滤掉噪声和分类贡献低的特征进行独立的评估,这样特征会获得一个评估分值,然后对所有的特征按照其评估分值的大小进行排序,选取预定数目的最佳特征作为特征子集,其中阈值的选取要根据具体问题的实验来确定。特征选择在减少特征维数的同时还要保证不影响文本的主题信息,这样在提高分类精度的同时也会大大提高文本数据的处理效率。特征选择容易实现,且方法很多,目前常用的特征选择方法有文档频率、信息增益、互信息、期望交叉熵。

    4、分类器

            文本分类的核心问题是如何构造分类器,根据分类体系将一个文本分到一个或几个相关联的类别中。文本分类的具体过程是,用已知的训练集训练分类器,再利用分类器对未知的文本进行分类。在众多的分类算法中,常用的典型分类算法有决策树、最大熵(MaxEnt)、贝叶斯和支持向量机(SVM)算法等。下面简单介绍这几种分类算法。

    5、分类性能评估

    展开全文
  • 综合多种停用词表,进行合并去重处理,http://blog.csdn.net/kevinelstri/article/details/70227981
  • 文本分类方法总结

    万次阅读 多人点赞 2020-01-17 15:01:42
    1 机器学习的文本分类方法 1.1 特征工程 1.1.1 文本预处理 1.1.2 文本表示和特征提取 1.1.3 基于语义的文本表示 1.2 分类器 朴素贝叶斯分类(Naïve Bayes) 用朴素贝叶斯分类算法做中文文本分类 KNN SVM ...

    目录

    1 机器学习的文本分类方法

    1.1 特征工程

    1.1.1 文本预处理

    1.1.2 文本表示和特征提取

    1.1.3 基于语义的文本表示

    1.2 分类器

    朴素贝叶斯分类(Naïve Bayes)

    用朴素贝叶斯分类算法做中文文本分类

    KNN

    SVM

    最大熵

    2 深度学习的文本分类方法

    2.1 文本的分布式表示:词向量(word embedding)

    2.2 深度学习文本分类模型

    2.2.1 fastText

    2.2.2 TextCNN

    2.2.3 TextRNN

    2.2.4 TextRNN + Attention

    2.2.5 TextRCNN

    2.2.6 EntNet/DMN

    2.3 总结

    Reference


    1 机器学习的文本分类方法

    文本分类问题算是自然语言处理领域中一个非常经典的问题了,相关研究最早可以追溯到上世纪50年代,当时是通过专家规则(Pattern)进行分类,甚至在80年代初一度发展到利用知识工程建立专家系统,这样做的好处是短平快的解决top问题,但显然天花板非常低,不仅费时费力,覆盖的范围和准确率都非常有限。

    后来伴随着统计学习方法的发展,特别是90年代后互联网在线文本数量增长和机器学习学科的兴起,逐渐形成了一套解决大规模文本分类问题的经典玩法,这个阶段的主要套路是人工特征工程+浅层分类模型。训练文本分类器过程见下图:

    整个文本分类问题就拆分成了特征工程和分类器两部分,玩机器学习的同学对此自然再熟悉不过了

    1.1 特征工程

    特征工程在机器学习中往往是最耗时耗力的,但却极其的重要。抽象来讲,机器学习问题是把数据转换成信息再提炼到知识的过程,特征是“数据-->信息”的过程,决定了结果的上限,而分类器是“信息-->知识”的过程,则是去逼近这个上限。然而特征工程不同于分类器模型,不具备很强的通用性,往往需要结合对特征任务的理解。

    文本分类问题所在的自然语言领域自然也有其特有的特征处理逻辑,传统分本分类任务大部分工作也在此处。文本特征工程分为文本预处理、特征提取、文本表示三个部分,最终目的是把文本转换成计算机可理解的格式,并封装足够用于分类的信息,即很强的特征表达能力。

    1.1.1 文本预处理

    文本预处理过程是在文本中提取关键词表示文本的过程,中文文本处理中主要包括文本分词去停用词两个阶段。

    预处理不是本文重点,在此就不具体介绍了。

    1.1.2 文本表示和特征提取

    文本表示:

    文本表示的目的是把文本预处理后的转换成计算机可理解的方式,是决定文本分类质量最重要的部分。传统做法常用词袋模型(BOW, Bag Of Words)或向量空间模型(Vector Space Model),最大的不足是忽略文本上下文关系,每个词之间彼此独立,并且无法表征语义信息。词袋模型的示例如下:

                   ( 0, 0, 0, 0, .... , 1, ... 0, 0, 0, 0)

    一般来说词库量至少都是百万级别,因此词袋模型有个两个最大的问题:高纬度、高稀疏性。词袋模型是向量空间模型的基础,因此向量空间模型通过特征项选择降低维度,通过特征权重计算增加稠密性。

    特征提取:

    向量空间模型的文本表示方法的特征提取对应特征项的选择特征权重计算两部分。特征选择的基本思路是根据某个评价指标独立的对原始特征项(词项)进行评分排序,从中选择得分最高的一些特征项,过滤掉其余的特征项。常用的评价有文档频率、互信息、信息增益、χ²统计量等。

    特征权重主要是经典的TF-IDF方法及其扩展方法,主要思路是一个词的重要度与在类别内的词频成正比,与所有类别出现的次数成反比。

    关于特征选择和特征权重计算可以看这篇博文 NLP --- 文本分类(向量空间模型(Vector Space Model)VSM)

    1.1.3 基于语义的文本表示

    传统做法在文本表示方面除了向量空间模型,还有基于语义的文本表示方法,比如LDA主题模型、LSI/PLSI概率潜在语义索引等方法,一般认为这些方法得到的文本表示可以认为文档的深层表示,而word embedding文本分布式表示方法则是深度学习方法的重要基础,下文会展现。

    1.2 分类器

    朴素贝叶斯分类(Naïve Bayes)

    用朴素贝叶斯分类算法做中文文本分类

    KNN

    该算法的基本思想是:根据传统的向量空间模型,文本内容被形式化为特征空间中的加权特征向量。对于一个测试文本,计算它与训练样本集中每个文本的相似度,找出K个最相似的文本,根据加权距离和判断测试文本所属的类别,具体算法步骤如下:

    1. 对于一个测试文本,根据特征词形成测试文本向量。
    2. 计算该测试文本与训练集中每个文本的文本相似度,按照文本相似度,在训练文本集中选出与测试文本最相似的k个文本。
    3. 在测试文本的k个近邻中,依次计算每类的权重。
    4. 比较类的权重,将文本分到权重最大的那个类别中。

    针对海量文本数据的改进方法可见这篇博文:用于大数据分类的KNN算法研究

    SVM

    基于支持向量机SVM的文本分类的实现

    最大熵

     

    2 深度学习的文本分类方法

    上文介绍了传统的文本分类做法,传统做法主要问题的文本表示是高纬度高稀疏的,特征表达能力很弱,而且神经网络很不擅长对此类数据的处理;此外需要人工进行特征工程,成本很高。而深度学习最初在之所以图像和语音取得巨大成功,一个很重要的原因是图像和语音原始数据是连续和稠密的,有局部相关性。应用深度学习解决大规模文本分类问题最重要的是解决文本表示,再利用CNN/RNN等网络结构自动获取特征表达能力,去掉繁杂的人工特征工程,端到端的解决问题。接下来会分别介绍:

    2.1 文本的分布式表示:词向量(word embedding)

    分布式表示(Distributed Representation)其实Hinton 最早在1986年就提出了,基本思想是将每个词表达成 n 维稠密、连续的实数向量,与之相对的one-hot encoding向量空间只有一个维度是1,其余都是0。分布式表示最大的优点是具备非常powerful的特征表达能力,比如 n 维向量每维 k 个值,可以表征 k^{^{n}} 个概念。事实上,不管是神经网络的隐层,还是多个潜在变量的概率主题模型,都是应用分布式表示。下图是03年Bengio在 A Neural Probabilistic Language Model 的网络结构:

    这篇文章提出的神经网络语言模型(NNLM,Neural Probabilistic Language Model)采用的是文本分布式表示,即每个词表示为稠密的实数向量。NNLM模型的目标是构建语言模型:

    词的分布式表示即词向量(word embedding)是训练语言模型的一个附加产物,即图中的Matrix C。

    尽管Hinton 86年就提出了词的分布式表示,Bengio 03年便提出了NNLM,词向量真正火起来是google Mikolov 13年发表的两篇word2vec的文章 Efficient Estimation of Word Representations in Vector Space 和 Distributed Representations of Words and Phrases and their Compositionality,更重要的是发布了简单好用的word2vec工具包,在语义维度上得到了很好的验证,极大的推进了文本分析的进程。下图是文中提出的CBOW 和 Skip-Gram两个模型的结构,基本类似于NNLM,不同的是模型去掉了非线性隐层,预测目标不同,CBOW是上下文词预测当前词,Skip-Gram则相反。

    除此之外,提出了Hierarchical Softmax 和 Negative Sample两个方法,很好的解决了计算有效性,事实上这两个方法都没有严格的理论证明,有些trick之处,非常的实用主义。详细的过程不再阐述了,有兴趣深入理解word2vec的,推荐读读这篇很不错的paper:word2vec Parameter Learning Explained。额外多提一点,实际上word2vec学习的向量和真正语义还有差距,更多学到的是具备相似上下文的词,比如“good”“bad”相似度也很高,反而是文本分类任务输入有监督的语义能够学到更好的语义表示,有机会后续系统分享下。

    至此,文本的表示通过词向量的表示方式,把文本数据从高纬度高稀疏的神经网络难处理的方式,变成了类似图像、语音的的连续稠密数据。深度学习算法本身有很强的数据迁移性,很多之前在图像领域很适用的深度学习算法比如CNN等也可以很好的迁移到文本领域了,下一小节具体阐述下文本分类领域深度学习的方法。

    2.2 深度学习文本分类模型

    词向量解决了文本表示的问题,该部分介绍的文本分类模型则是利用CNN/RNN等深度学习网络及其变体解决自动特征提取(即特征表达)的问题。

    2.2.1 fastText

    fastText 是上文提到的 word2vec 作者 Mikolov 转战 Facebook 后16年7月刚发表的一篇论文 Bag of Tricks for Efficient Text Classification。把 fastText 放在此处并非因为它是文本分类的主流做法,而是它极致简单,速度快,模型图见下:

    具体结构参考这篇文章 fastText原理及实践

    fastText的核心思想就是:将整篇文档的词及n-gram向量叠加平均得到文档向量,然后使用文档向量做softmax多分类。这中间涉及到两个技巧:字符级n-gram特征的引入以及分层Softmax分类。

    2.2.2 TextCNN

    本篇文章的题图选用的就是14年这篇文章提出的TextCNN的结构(见下图)。fastText 中的网络结果是完全没有考虑词序信息的,而它用的 n-gram 特征 trick 恰恰说明了局部序列信息的重要意义。卷积神经网络(CNN Convolutional Neural Network)最初在图像领域取得了巨大成功,CNN原理就不讲了,核心点在于可以捕捉局部相关性,具体到文本分类任务中可以利用CNN来提取句子中类似 n-gram 的关键信息。

    TextCNN的详细过程原理图见下:

    2.2.3 TextRNN

    尽管TextCNN能够在很多任务里面能有不错的表现,但CNN有个最大问题是固定 filter_size 的视野,一方面无法建模更长的序列信息,另一方面 filter_size 的超参调节也很繁琐。CNN本质是做文本的特征表达工作,而自然语言处理中更常用的是递归神经网络(RNN, Recurrent Neural Network),能够更好的表达上下文信息。具体在文本分类任务中,Bi-directional RNN(实际使用的是双向LSTM)从某种意义上可以理解为可以捕获变长且双向的的 "n-gram" 信息。

    RNN算是在自然语言处理领域非常一个标配网络了,在序列标注/命名体识别/seq2seq模型等很多场景都有应用,Recurrent Neural Network for Text Classification with Multi-Task Learning文中介绍了RNN用于分类问题的设计,下面介绍两种structure。

    1)structure 1

    流程:embedding--->BiLSTM--->concat final output/average all output----->softmax layer

    2)structure 2

    流程:embedding-->BiLSTM---->(dropout)-->concat ouput--->UniLSTM--->(droput)-->softmax layer

    结构图如下图所示:

    与之前结构不同的是,在双向LSTM(上图不太准确,底层应该是一个双向LSTM)的基础上又堆叠了一个单向的LSTM。把双向LSTM在每一个时间步长上的两个隐藏状态进行拼接,作为上层单向LSTM每一个时间步长上的一个输入,最后取上层单向LSTM最后一个时间步长上的隐藏状态,再经过一个softmax层(输出层使用softamx激活函数,2分类的话则使用sigmoid)进行一个多分类。

    2.2.4 TextRNN + Attention

    CNN和RNN用在文本分类任务中尽管效果显著,但都有一个不足的地方就是不够直观,可解释性不好,特别是在分析badcase时候感受尤其深刻。而注意力(Attention)机制是自然语言处理领域一个常用的建模长时间记忆机制,能够很直观的给出每个词对结果的贡献,基本成了Seq2Seq模型的标配了。实际上文本分类从某种意义上也可以理解为一种特殊的Seq2Seq,所以考虑把Attention机制引入近来,研究了下学术界果然有类似做法。

    这其中比较典型的就是HAN,具体可以见这篇文章HAN(Hierarchical Attention Network)

    2.2.5 TextRCNN

    我们参考的是中科院15年发表在AAAI上的这篇文章 Recurrent Convolutional Neural Networks for Text Classification 的结构:

    2.2.6 EntNet/DMN

    对这两个网络没有研究过,具体参考这篇文章 基于深度学习的文本分类

    2.2.7 Bert

    Ber的结构讲解有很多,大家可自行搜索。

    2.2.8 DPCNN

    DPCNN可参考这篇文章DPCNN深度金字塔卷积神经网络介绍

    2.3 总结

    文本分类在深度学习的时代逃过了特征提取类似距离的定义的过程, 但是依然逃不了模型的选择, 参数的优化,编码和预处理的考量(one-hot, n-gram等等) ,以及时间的平衡。

    概况说来,主要有5大类模型:

    1. 词嵌入向量化:word2vec, FastText等等
    2. 卷积神经网络特征提取:Text-CNN, Char-CNN等等
    3. 上下文机制:Text-RNN, BiRNN, RCNN等等
    4. 记忆存储机制:EntNet, DMN等等
    5. 注意力机制:HAN等等

    最后再推荐下Github上关于文本分类的总结,讲的非常全面:https://github.com/brightmart/text_classification

    Reference

    用深度学习(CNN RNN Attention)解决大规模文本分类问题 - 综述和实践

    用于大数据分类的KNN算法研究

    fastText原理及实践

    textRNN & textCNN的网络结构与代码实现!

    基于深度学习的文本分类

    展开全文
  • A Survey on Text Classification: From Shallow to Deep Learning ...根据所涉及的文本以及用于特征提取和分类的模型创建用于文本分类的分类法。然后,详细讨论这些类别中的每一个类别,涉及支持预测测试的技术.
  • 基于gensim的文本主题模型(LDA)分析

    热门讨论 2016-01-05 20:52:00
    博客《基于gensim的文本主题模型(LDA)分析》对应文档
  • 【C语言】C语言读取文本文件

    万次阅读 多人点赞 2019-01-28 20:44:26
    文章目录【C语言】C语言读取文本文件一 前言二 按字符读取文本文件1、程序实现一2、程序实现二三、按行读取文本文件1、程序实现一2、程序实现二四、说明 【C语言】C语言读取文本文件 一 前言 &amp;amp;amp;nbsp;...
  • 文本分类(二)文本数据数值化,向量化,降维

    千次阅读 多人点赞 2019-05-25 17:14:55
    上面一篇博客文本分类流程(一)文本分类的大致步骤+数据预处理------毕业论文的纪念已经讲述了文本处理中的两个步骤,网页获取+数据清洗,得到了干净的文本数据。 下面开始介绍如何将我们能够识别的文本数据转化为...
  • 文本检测综述(2017 ~ 2021 持续更新)

    万次阅读 多人点赞 2019-08-29 10:42:55
    文本检测 + 文本识别 传统OCR 图像预处理;版面处理;图像切分;特征提取、匹配及模型训练;识别后处理 预处理:灰度化、二值化、倾斜检测与矫正,平滑、规范化 版面处理:版面分析、版面理解、版面重构 图像...
  • 用深度学习(CNN RNN Attention)解决大规模文本分类问题 - 综述和实践 近来在同时做一个应用深度学习解决淘宝商品的类目预测问题的项目,恰好硕士毕业时论文题目便是文本分类问题,趁此机会总结下文本分类领域特别...
  • linux 文本编辑器Text editors play a major role for Linux users. Whether it is setting up user instructions, editing configuration files or writing code scripts to run on your system, everyone has a ...
  • NLP之文本分类

    万次阅读 2018-09-26 15:08:07
    文本自动分类简称文本分类(text categorization),是模式识别与自然语言处理密切结合的研究课题。传统的文本分类是基于文本内容的,研究如何将文本自动划分成政治的、经济的、军事的、体育的、娱乐的等各种类型。 ...
  • 文本摘要旨在将文本文本集合转换为包含关键信息的简短摘要。文本摘要按照输入类型可分为单文档摘要和多文档摘要。单文档摘要从给定的一个文档中生成摘要,多文档摘要从给定的一组主题相关的文档中生成摘要。按照...
  • 文本分析是指: 从文本中抽取特征词进行量化以表示文本信息。 文本一般指文字。 它是自然语言处理的一个小分支,自然语言处理还包括语音识别(常见的)等。 目的: 先决条件:将无结构化的原始文本转化为结构化的,...
  • 511遇见易语言文本处理寻找文本

    千次阅读 2020-06-27 17:20:50
    本课讲解了寻找文本和寻找字节集来实现对单字节和双字节多次寻找文本的方法。 视频链接: 511遇见易语言教程 教程源码 .版本 2 .程序集 窗口程序集_启动窗口 .子程序 _按钮1_被单击, , , 寻找文本 .局部...
  • 文本特征提取

    万次阅读 多人点赞 2019-03-05 20:36:57
    在自然语言处理中我们把文本数据变成向量数据,在向量数据中我们可以得到很多来自于文本数据当中的语言特性,这种方式叫做文本表示或文本特征构造。 文本特征的通用信息源 文本分类问题当中的对象 词:在英文文本...
  • 单行文本水平滑动/文本折叠点击展开

    千次下载 热门讨论 2015-05-06 14:01:56
    简易实现单行文本水平滑动(http://blog.csdn.net/qiaoidea/article/details/41252959) 以及第二篇,点击折叠长文本查看详情,添加动画效果,详情见本人Blog。 单文本水平滑动,长文本折叠展开
  • python 文本聚类分析案例说明摘要1、结巴分词2、去除停用词3、生成tfidf矩阵4、K-means聚类5、获取主题词 / 主题词团 说明 实验要求:对若干条文本进行聚类分析,最终得到几个主题词团。 实验思路:将数据进行预处理...
  • 文本匹配(语义相似度/行为相关性)技术综述

    万次阅读 多人点赞 2019-01-13 13:08:39
    NLP 中,文本匹配技术,不像 MT、MRC、QA 等属于 end-to-end 型任务,通常以文本相似度计算、文本相关性计算的形式,在某应用系统中起核心支撑作用,比如搜索引擎、智能问答、知识检索、信息流推荐等。本篇将纵览...
  • 本文要点刚要:(一)读文本文件格式的数据函数:read_csv,read_table1.读不同分隔符的文本文件,用参数sep2.读无字段名(表头)的文本文件 ,用参数names3.为文本文件制定索引,用index_col4.跳行读取文本文件,用...
  • 文本处理

    千次阅读 2019-01-29 22:08:00
    文本(Rich Text)或者叫做富文本格式,简单来说就是在文档中可以使用多种格式,比如字体颜色、图片和表格等等。它是与纯文本(Plain Text)相对而言的,比如Windows上的记事本就是纯文本编辑器,而Word就是富文本...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,075,750
精华内容 1,230,300
关键字:

文本