1. 程式人生 > >Fasttext文字分類

Fasttext文字分類

一、簡介

1、簡介

fasttext是facebook開源的一個詞向量與文字分類工具,在2016年開源,典型應用場景是“帶監督的文字分類問題”。提供簡單而高效的文字分類和表徵學習的方法,效能比肩深度學習而且速度更快。

fastText結合了自然語言處理和機器學習中最成功的理念。這些包括了使用詞袋以及n-gram袋錶徵語句,還有使用子字(subword)資訊,並通過隱藏表徵在類別間共享資訊。我們另外採用了一個softmax層級(利用了類別不均衡分佈的優勢)來加速運算過程。

2、原理

fastText方法包含三部分,模型架構,層次SoftMax和N-gram特徵。

  • 模型架構

    fastText的架構和word2vec中的CBOW的架構類似,因為它們的作者都是Facebook的科學家Tomas Mikolov,而且確實fastText也算是words2vec所衍生出來的。

    fastText 模型輸入一個詞的序列(一段文字或者一句話),輸出這個詞序列屬於不同類別的概率。

    序列中的詞和片語組成特徵向量,特徵向量通過線性變換對映到中間層,中間層再對映到標籤。

    fastText 在預測標籤時使用了非線性啟用函式,但在中間層不使用非線性啟用函式。fastText 模型架構和 Word2Vec 中的 CBOW 模型很類似。不同之處在於,fastText 預測標籤,而 CBOW 模型預測中間詞。

  • 層次SoftMax

    對於有大量類別的資料集,fastText使用了一個分層分類器(而非扁平式架構)。不同的類別被整合進樹形結構中(想象下二叉樹而非 list)。在某些文字分類任務中類別很多,計算線性分類器的複雜度高。為了改善執行時間,fastText 模型使用了層次 Softmax 技巧。層次 Softmax 技巧建立在哈弗曼編碼的基礎上,對標籤進行編碼,能夠極大地縮小模型預測目標的數量。

    fastText 也利用了類別(class)不均衡這個事實(一些類別出現次數比其他的更多),通過使用 Huffman 演算法建立用於表徵類別的樹形結構。因此,頻繁出現類別的樹形結構的深度要比不頻繁出現類別的樹形結構的深度要小,這也使得進一步的計算效率更高。

  • N-gram特徵

    fastText 可以用於文字分類和句子分類。不管是文字分類還是句子分類,我們常用的特徵是詞袋模型。但詞袋模型不能考慮詞之間的順序,因此 fastText 還加入了 N-gram 特徵。“我 愛 她” 這句話中的詞袋模型特徵是 “我”,“愛”, “她”。這些特徵和句子 “她 愛 我” 的特徵是一樣的。如果加入 2-Ngram,第一句話的特徵還有 “我-愛” 和 “愛-她”,這兩句話 “我 愛 她” 和 “她 愛 我” 就能區別開來了。當然啦,為了提高效率,我們需要過濾掉低頻的 N-gram。

二、安裝

1、使用make構建fastText(首選)

$ wget https://github.com/facebookresearch/fastText/archive/v0.1.0.zip
$ unzip v0.1.0.zip
$ cd fastText-0.1.0
$ make

這個方法下載是在fastTest的最新穩定版本。

2、使用cmake構建fastText

$ git clone https://github.com/facebookresearch/fastText.git
$ cd fastText
$ mkdir build && cd build && cmake ..
$ make && make install

這將建立fasttext二進位制檔案以及所有相關庫(共享,靜態,PIC),這個下載是最新的主幹版本。

3、為Python構建fastText

$ git clone https://github.com/facebookresearch/fastText.git
$ cd fastText
$ pip install .

三、語料準備

語料準備絕對是在文字分類裡面佔大頭的重頭戲,比較花精力。

這裡測試用了輿情資料的標題資料,資料量如下

訓練資料 測試資料 分類數
1.4w 3.5k 16類

語料的處理我這邊是用java進行處理的,畢竟java才是最熟悉的。。

下面是語料的格式,我的語料是通過分詞的,分詞是使用HanLP的分詞實現的:

申能股份 啟動 回購   __label__104003
湯臣倍健 海外 併購 疑點 難 消 標的 公司 虛增 利潤 嫌疑   __label__104001
現金流 硬 約束 大面積 回購 潮 難 現   __label__104003
美都能源 出售 房地產 業務 資產 集 中發展 新能源車 產業   __label__104001
四通股份 1.69億 限售股 月 日 上市 流通   __label__104004
贏合科技 兩 名 董事 名 監事 辭職   __label__103006
上海建工 部分 高 合計 增持 公司 125萬 股   __label__104001
中海油 原 副 總經理 李凡榮 調任 國家能源局 副局長   __label__103006
銀信科技 7920萬 股 日 解禁   __label__104004
新潮實業 兩 高 工作 原因 辭職   __label__103006
中國 債市 上證所 高 評級 可轉債 參與 質押 式 回購 助 增 流動性   __label__104008
重慶啤酒 總 會計師 總經理 助理 辭職   __label__103006
重磅 觀 汽車 官方 確認 決定 引進 新的 戰略 投資者   __label__104006
振華重工 控股 股東 變更 事宜 獲 批   __label__104007
內蒙華電 控股 股東 方面 完成 增持 計劃   __label__104001
......

每一行是一組資料,前一部分是經過分詞後的標題資料,後面是固定格式__label__加上所屬分類的id,兩組之間用3個空格分割。

四、用例示例

FastText主要可以用於單詞表示學習和文字分類。單詞表示學習說白了就是詞向量模型的訓練,我們著重介紹文字分類。

1、採用命令列的方式

FastText提供命令列的方式來進行訓練模型和分類,主要使用的命令有訓練、評估模型、對資料分類。

  • 訓練
$ ./fasttext supervised -input train.txt -output model

./fasttext:這個即為在2.1中使用make構建fastText的目錄

supervised:表示監督學習,即訓練資料

-input train.txt:表示輸入檔案為train.txt,即是我們訓練的語料檔案,每行包含一個訓練語句以及標籤。默 認情況下,標籤是以字串為字首的單詞__label__

-output model:表示輸出的模型路徑

訓練操作這將輸出兩個檔案:model.binmodel.vec

  • 評估模型

訓練模型後,您可以通過計算精度並在測試集上以k(P @ k和R @ k)呼叫來評估它:

$ ./fasttext test model.bin test.txt k

test.txt是我們的測試檔案,引數k是可選的,預設情況下等於1,例如為了獲得一段文字的10個最可能的標籤,可使用:

$ ./fasttext predict model.bin test.txt 10
  • 獲取概率

    predict-prob用來獲得每個標籤的概率

$ ./fasttext predict-prob model.bin test.txt k

其中test.txt包含一行文字以按行分類。這樣做會向標準輸出列印每行最有可能的k個標籤。引數k是可選的,預設情況下等於1

  • 量化模型

可以使用以下命令量化受監控的模型以減少其記憶體使用量:

$ ./fasttext quantize -output model

這將建立一個.ftz記憶體佔用較小的檔案。所有操作和model.bin的模型一樣,例如評估模型:

$ ./fasttext test model.ftz test.txt

實際操作一下

//訓練
$ ./fastText-0.1.0/fasttext supervised -input 0821-title/train.txt -output model
Read 0M words
Number of words:  17352
Number of labels: 15
Progress: 100.0%  words/sec/thread: 524129  lr: 0.000000  loss: 0.191040  eta: 0h0m 
//評估
$ ./fastText-0.1.0/fasttext test ./model.bin ./0821-title/test.txt
N       0
[email protected]1     -nan
[email protected]1     -nan
Number of examples: 0

2、採用python的方式

編寫了python指令碼,評估使用了sklean的文字分類的評估方法,直接上程式碼,簡單幹脆,具體的都已經註釋在指令碼中。

# -*- coding: utf-8 -*-
"""
Created on Wed Aug  1 11:12:10 2018
@author: chenyang
"""
#這裡是匯入fasttext庫
import fasttext
import os
import sys
#這裡是匯入sklearn庫
from sklearn import metrics

#這裡是為了中文亂碼做的一些轉碼
if sys.version_info[0] > 2:
    is_py3 = True
else:
    is_py3 = False

def native_content(content):
    if not is_py3:
        return content.decode('utf-8')
    else:
        return content

#這個方法是讀取檔案,主要是訓練集和測試集
def open_file(filename, mode='r'):
    if is_py3:
        return open(filename, mode, encoding='utf-8', errors='ignore')
    else:
        return open(filename, mode)

#這個方法是切割資料,以3個空格進行分割,返回內容和對應標籤的2個list
def read_file(filename):
    """讀取檔案資料"""
    contents, labels = [], []
    with open_file(filename) as f:
        for line in f:
            try:
                content,label = line.strip().split('   ')
                if content:
                    contents.append(native_content(content))
                    labels.append(native_content(label))
            except:
                pass
    return contents, labels

#主方法
if __name__ == '__main__':
    #判斷輸入引數是否含有語料路徑的引數
    if len(sys.argv) != 2:
        print("The number of parameters is not correct!")
        exit()

    filename=sys.argv[1]
    print("input param:%s" % filename)
    print(os.path.exists('./%s/model.bin' % filename))

    classifier = None
    #判斷是否已經存在模型,如果存在則載入,不存在則進行訓練
    if(os.path.exists('./%s/model.bin' % filename)):
        classifier =fasttext.load_model('./%s/model.bin' % filename)
    else:
        #訓練模型
        if(not os.path.exists('./%s/' % filename)):
            os.mkdir('./%s/' % filename)
        fasttext.supervised('../%s/train.txt' % filename,'./%s/model' % filename)
        classifier =fasttext.load_model('./%s/model.bin' % filename)

    #讀取測試資料
    lines, test_cls = read_file("../%s/test.txt" % filename);

    print("data sum: ",len(lines))
    #獲取測試資料的分類結果
    pred = classifier.predict(lines)

    pred_cls = []
    for x in pred:
        pred_cls.append(x[0])
    # 評估
    print("Precision, Recall and F1-Score...")
    print(metrics.classification_report(test_cls, pred_cls))
    # 混淆矩陣
    print("Confusion Matrix...")
    cm = metrics.confusion_matrix(test_cls, pred_cls)
    print(cm)

呼叫指令碼方式:

//進入指令碼所在目錄
$ python fasttext-train.py 0820-title

0820-title:為語料所在的路徑名

五、附預料處理程式碼:

/**
 * @description: 構建訓練語料
 * @author: chenyang
 * @create: 2018-06-08
 **/
public class BuildCorpus {

    //訓練語料所在路徑
    private final static String PATH = "C:\\Users\\chenyang\\Desktop\\0821";
    //生成的訓練檔案
    private final static String TRAIN = "C:\\Users\\chenyang\\Desktop\\train.txt";
    //生成的測試檔案
    private final static String TEST = "C:\\Users\\chenyang\\Desktop\\test.txt";

    public static void main(String[] args) {
        try {
            exportCurpor();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void exportCurpor() throws Exception {
        StopWatch watch = new StopWatch();
        watch.start();
        Path p = Paths.get(PATH);

        List<String> list = new ArrayList<>();

        Files.walkFileTree(p, new FileVisitor<Path>() {

            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                System.out.println("遍歷資料夾:" + dir);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                System.out.println("遍歷檔案:" + file.getFileName());
                Stream<String> s = Files.lines(file);
                List<String> rel = s.map(l -> HanLP.newSegment().enableCustomDictionaryForcing(true)
                        .enablePlaceRecognize(true)
                        .enableOrganizationRecognize(true).seg(l.split("XXXXXX")[4]).stream().map(t -> t.word)
                        .filter(w -> NormalizeUtils.checkStringContainChinese(w)) //必須要有中文
                        .filter(w -> !CoreStopWordDictionary.contains(w))
                        .filter(w -> !w.matches(
                                "^[\\pP|\\pS|\\p{Zs}]+|"
                                        + "[\\-|\\+|\\.|\\,]+$")) //過濾掉數字和標點
                        .collect(Collectors.joining(" "))+"   __label__"+l.split("XXXXXX")[1]
                ).collect(Collectors.toList());
                for (String tool : rel){
                    list.add(tool);
                }
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                return FileVisitResult.CONTINUE;
            }
        });

        Path target = Paths.get(TRAIN);
        FileOutputStream fout = new FileOutputStream(target.toFile(), false);
        OutputStreamWriter out = new OutputStreamWriter(fout, "UTF-8");
        BufferedWriter bw = new BufferedWriter(out);

        Path test = Paths.get(TEST);
        FileOutputStream fout1 = new FileOutputStream(test.toFile(), false);
        OutputStreamWriter out1 = new OutputStreamWriter(fout1, "UTF-8");
        BufferedWriter bw1 = new BufferedWriter(out1);

        Collections.shuffle(list);

        for (int i=0;i<list.size();i++){
            if (i%10==0 || i%10==3 || i%10==7) {
                bw1.write(list.get(i));
                bw1.newLine();
            }else {
                bw.write(list.get(i));
                bw.newLine();
            }
        }

        bw1.close();
        bw.close();
        out.close();
        fout.close();
        out1.close();
        fout1.close();

        watch.stop();

        System.out.println(watch.toString());
    }
}

相關推薦

fasttext文字分類原理

http://www.52nlp.cn/fasttext https://www.jiqizhixin.com/articles/2018-06-05-3   這兩篇文章總結一下      於是fastText的核心思想就是:將整篇文件的

FastText 文字分類使用心得

最近在一個專案裡使用了fasttext[1], 這是facebook今年開源的一個詞向量與文字分類工具,在學術上沒有什麼創新點,但是好處就是模型簡單,訓練速度又非常快。我在最近的一個專案裡嘗試了一下,發現用起來真的很順手,做出來的結果也可以達到上線使用的標準。

Fasttext文字分類

一、簡介 1、簡介 fasttext是facebook開源的一個詞向量與文字分類工具,在2016年開源,典型應用場景是“帶監督的文字分類問題”。提供簡單而高效的文字分類和表徵學習的方法,效能比肩深度學習而且速度更快。 fastText結合了自然語言處理

文字分類需要CNN? No!fastText完美解決你的需求(前篇)

文字分類需要CNN?No!fastText完美解決你的需求(前篇) fastText是個啥?簡單一點說,就是一種可以得到和深度學習結果準確率相同,但是速度快出幾個世紀的文字分類演算法。這個演算法類似與CBOW,可愛的讀著是不是要問CBOW又是個什麼鬼?莫急,聽

FastText快速文字分類

FastTest架構 fastText 架構原理 fastText 方法包含三部分:模型架構、層次 Softmax 和 N-gram 特徵 fastText 模型輸入一個詞的序列(一段文字或者一句話),輸出這個詞序列屬於不同類別的概率。 序列中的詞和片

FastText:快速的文字分類

一、簡介 fasttext是facebook開源的一個詞向量與文字分類工具,在2016年開源,典型應用場景是“帶監督的文字分類問題”。提供簡單而高效的文字分類和表徵學習的方法,效能比肩深度學習而且速度更快。 fastText結合了自然語言處理和

文字分類(六):使用fastText文字進行分類--小插曲

需要注意的問題: 1、linux mac 平臺 2、標籤中的下劃線是兩個!兩個!兩個! 環境說明:python2.7、linux 自己打自己臉,目前官方的包只能在linux,mac環境下使用。誤導大家了,對不起。 測試facebook開源的基於深度學習

fastrtext︱R語言使用facebook的fasttext快速文字分類演算法

FastText是Facebook開發的一款快速文字分類器,提供簡單而高效的文字分類和表徵學習的方法,不過這個專案其實是有兩部分組成的。理論介紹可見部落格:NLP︱高階詞向量表達(二)——FastText(簡述、學習筆記) 本輪新更新的fastr

fasttext ---強大的文字分類

最近接觸到自然語言處理,需要對網上新聞進行文字分類,所以入坑fasttext。 之前用過CNN網路寫過文字分類,直到本渣接觸到了fasttext,才發現,人生苦短,我要快! 這篇文章是轉載自 https://blog.csdn.net/weixin_36604953/a

文字分類(TFIDF/樸素貝葉斯分類器/TextRNN/TextCNN/TextRCNN/FastText/HAN)

目錄 簡介 TFIDF 樸素貝葉斯分類器 貝葉斯公式 貝葉斯決策論的理解 極大似然估計 樸素貝葉斯分類器 TextRNN

5.1、文字分類

1、樸素貝葉斯 NB   三大概率     1、條件概率       Ω是全集,A、B是其中的事件(子集),p是事件發生的概率,則:p(A | B) = p(AB) / p(B),事件B發生,A發生的概率              

tensorflow 教程 文字分類 IMDB電影評論

昨天配置了tensorflow的gpu版本,今天開始簡單的使用一下 主要是看了一下tensorflow的tutorial 裡面的 IMDB 電影評論二分類這個教程 教程裡面主要包括了一下幾個內容:下載IMDB資料集,顯示資料(將陣列轉換回評論文字),準備資料,建立模型(隱層設定,優化器和損失函式的配置),

使用條件隨機場模型解決文字分類問題(附Python程式碼)

對深度學習感興趣,熱愛Tensorflow的小夥伴,歡迎關注我們的網站!http://www.tensorflownews.com。我們的公眾號:磐創AI。   一. 介紹 世界上每天都在生成數量驚人的文字資料。Google每秒處理超過40,000次搜尋,而根據福布斯報道,

斯坦福大學-自然語言處理入門 筆記 第六課 文字分類與樸素貝葉斯

一、文字分類任務概述 1、應用領域 歸類 垃圾郵件識別 作者識別 性別/年齡識別 等等 2、定義 輸入:一個文件d,一系列固定的型別C={c1,c2,…,cj} 輸出:預測類別c ∈ C 3、分類方法

基於協同訓練的半監督文字分類演算法

標籤: 半監督學習,文字分類 作者:煉己者 --- 本部落格所有內容以學習、研究和分享為主,如需轉載,請聯絡本人,標明作者和出處,並且是非商業用途,謝謝! 如果大家覺得格式看著不舒服,也歡迎大家去看我的簡書 半監督學習文字分類系列 用半監督演算法做文字分類(sklearn) sklearn半監督學習(

文字分類-TextCNN

簡介 TextCNN模型是由 Yoon Kim提出的Convolutional Naural Networks for Sentence Classification一文中提出的使用卷積神經網路來處理NLP問題的模型.相比較nlp中傳統的rnn/lstm等模型,cnn能更加高效的提取重要特徵,這些特徵在分類

【線上直播】人工智慧中的文字分類技術

講師:黃鴻波                            講師簡介: 珠海金山辦公軟體有限公司(WPS)人工智慧領域專家,高階演算法工

使用機器學習完成中文文字分類

資料集來自七月線上練習 import jieba import pandas as pd import random from sklearn.model_selection import train_test_split #劃分訓練/測試集 from sk

文字分類——快速kNN設計實現

內容提要 介紹 普通kNN實現 快速kNN實現 實驗對比 分析總結 介紹   文字分類——常見分類模型   kNN分類模型的主要思想:通過給定一個未標註文件d,分類系統在訓練集中查詢與它距離最接近的k篇相鄰(相似或相同)標註

文字分類——NLV演算法研究與實現

內容提要 1 引言 2 NLV演算法理論 2.1 訓練模型 2.2 分類模型 3 NLV演算法實現 3.1 演算法描述 4 實驗及效能評估 4.1 實驗設計 4