6 minute read

Tags: , ,

NLP Basics - Meaning Representation

  • Meaning Representations

    • Defintion of “Meaning”

      • the idea that is represented by a word, phrase, etc.
      • the idea that a person wants to express by using words, signs, etc.
      • the idea that is expressed in a word of writing, art, etc
  • Meaning Representations in Computers

    • Knowledge-Based Representation
      • 有一本辭典,一位老師,去查特徵
    • Corpus-Based Representation
      • 靠 big data 去認字,從前後文去猜 "某字"

Knowledge-Based Representation

  • Hypernyms (is-a) relationships of WordNet

Imgur

NLP Basics - Corpus Based Representation

Meaning Representations in Compters

  • Corpus-Based Representation

    Imgur

    Imgur

  • Windoe-Based Co-occurrence Matrix

    • sparsity (資料內很多0)

    Imgur

  • Low-Dimensional Dense Word Vector

    Imgur

    Imgur

    Imgur

  • Summary

    • Knowledge-based representation
    • Corpus-based representation
      • Atomic symbol
      • Neighbors
        • High-dimensional sparse word vector
        • Low-dimensional dense word vector
          • Method 1 - dimension reduction
          • Method 2 - direct learning

text mining 文字探勘

  • 甚麼是文字探勘?

    • 從文本產生有價值的訊息
      • 從非結構化到結構化
      • 分析結構化並得到有價值的訊息
  • 文字探勘應用

    • 垃圾郵件檢測
    • 情感分析
    • 命名實體辨識
    • 文本摘要

Imgur

Imgur

中文分詞

  • 與英文文字類似,差別在於需要做斷詞處理

  • jieba

text mining preprocess

文章斷詞

  • jieba

    • 號稱最好的 Python 中文斷詞套件
    • 支持四種斷詞引擎
      • 最大概率法、隱式法爾科夫模型、混合模型、索引模型
    • 可以標註詞性
  • 中研院斷詞系統

    • 號稱地表最強中文斷詞系統(96% 精準度)
    • 自動標註詞性
    • 需要申請…

jieba 斷詞

  • 設定 字典辭庫 與 stopwords 辭庫

    • stop_words
      • EX: 了、阿、吧、我們...
      • 很常出現的字,但沒特別意義
    • set_dictionary
      • 把繁體中文字典加入
## set dictionary (can define yourself)
jieba.set_dictionary('jieba/dict.txt.big')
stop_words = open('jieba/stop_words.txt', encoding='utf8').read().splitlines()
data = pd.read_csv('data/article_preprocessed.csv')
data = data['content'].tolist()

sentences = []

for i, text in enumerate(tqdm_notebook(data)):
    line = []

    for w in jieba.cut(text, cut_all=False):
        
        ## remove stopwords and digits
        ## can define your own rules
        if w not in stop_words and not bool(re.match('[0-9]+', w)):
            line.append(w)

    sentences.append(line)

print(sentences[0:5])
[['韓瑜', '協志', '前妻', '正', '女演員', '周子', '瑜', 'TWICE', '團裡裡面', '台灣', '人', '正', '兩個', '要當', '鄉民', '老婆', '選', '五樓', '真', '勇氣'], ['dear', 'all', '逢甲', '碟仙', '發生', '民國', '七十五年', '三月中', '事情', '一堆', '大學生', '玩', '碟仙', '後發', 'bbs', '成功', '預測', '地震', '小弟', '預言', '都還沒', '出生', '後面', '說', '預言', '一百', '一十六年', '兩岸', '統一', '統一', '對岸', '對岸', '統一', '應該', '不用', '猜', '真的', '存在', '預言', '這種', '事情', '倒底', '被統', '知道', '資料庫', '發文', '日期', '輕鬆', '改變', '拍照', '狀況', '下', '碟仙', '真的假', '有沒有', '科學', '經驗', '法則', '破解', '謠言', '真實', '八卦'], ['晚上', '好', '預備', '唱', '風雲', '山河', '動', '國軍', '早上', '唱', '有沒有', '相關', '八卦', 'Sent', 'from', 'JPTT', 'on', 'my', 'Xiaomi', 'Redmi', 'Note'], ['明天', '早起', '睡覺', '旁邊', 'Youtube', '眼睛', '壞掉', '有沒有', '方法', '早點', '睡', '掛', 'Sent', 'from', 'JPTT', 'on', 'my', 'HTC', 'D10i'], ['一段時間', '注意', 'LOL', '發現', '各大', 'LOL', '討論區', '人數', '明顯', '下降', '趨勢', '實在', '令人', '驚訝', '曾經', '一時', '遊戲', '霸主', '漸漸', '過氣', 'LOL', '確實', '撐', '久', '現在', '算', '厲害', '遊戲', '玩久', '會膩']]

posseg (詞性)

from jieba import posseg as pseg
for w, j in pseg.cut(data[0]):
    print(w, ' ', j)
韓瑜   nr
是   v
協志   n
的   uj
前妻   n
    x
也   d
是   v
很正   a
的   uj
女演員   x
    x
周子瑜   nr
是   v
TWICE   eng
團裡   q
裡面   f
的   uj
台灣   ns
人   n
    x
也   d
是   v
很正   d
    x
這   zg
兩個   x
要   v
當   p
鄉民   x
的   uj
老婆   n
,   x
你   r
要   v
怎麼   x
選   v
呢   y
?   x
?   x
    x
五   m
樓   n
你   r
真   d
有   v
勇氣   x

feature engineering

  • 定義 y

    • 發文收到的推比噓多則 1,反之 0
    • 中間地帶 (定一個 threshold)
      • 推噓文數量差異不超過 threshold 則剔除資料

      • Imgur
  • 文本可以產生甚麼特徵?

    • 基本資訊
      • 字數、標點符號數、中文字比例、”問號”佔字數比例、…
    • 關鍵字
      • 有/無某關鍵字、關鍵字出現比例/佔比、…
    • 關鍵字詞組
      • 名詞、正面情緒詞、…
    • 文本情緒分數
  • 基本資訊

    • 特徵
      • 字數
      • 標點符號數
      • “問號’佔字數比例
    • 一般都會用到正則表達式子處理

    • Imgur
  • 基本資訊結果範例

    • Imgur
  • 關鍵字

    • 關鍵字出現次數(bag of words)

    • Imgur

Term Frequency-Inverse Document Frequency (TF-IDF)

  • 文字、關鍵字在文件上出現的相對的頻率
  • Why TF-IDF ?

    • bag of words 看文字統計的量,都是 the、were、said… 等,沒有重要訊息的文字
    • 引入 TF-IDF 關鍵字,可以看得出重要訊息

Imgur

  • TF-IDF 定義

Imgur

  • TF-IDF 範例

    • Doc. 1: I love dogs.
    • Doc. 2: I hate dogs and knitting.
    • Doc. 3: Knitting is my hobby and my passion.
  I love dogs hate and knitting is my hobby passion
Doc.1 0.18 0.48 0.18              
Doc.2 0.18   0.18 0.48 0.18 0.18        
Doc.3         0.18 0.18 0.48 0.95 0.48 0.48

feature engineering code

  • 把 data load 進來
import re
import pandas as pd
import numpy as np
import pickle
import os

## turn back to main directory
os.chdir("../")
os.getcwd()
df = pd.read_csv('data/article_preprocessed.csv')
## load 'article_cutted'
with open("article_cutted", "rb") as file:
    sentences = pickle.load(file)
  • define y (push > boo)
## drop data
diff_threshold = 20
df = df[abs(df['push']-df['boo']) > diff_threshold].copy()
## define y
df['type'] = np.clip(df['push']-df['boo'], 0, 1)
df = df.reset_index(drop=True)
df['type'].value_counts()
  • simple feature

    • 中文 utf8
      ## word count
      ## http://blog.csdn.net/gatieme/article/details/43235791 (中文正則表達式)
      df['word_count'] = df['content'].str.count('[a-zA-Z0-9]+') + df['content'].str.count('[\u4e00-\u9fff]')
      
## punctuation count
df['punctuation'] = df['content'].str.replace('[\w\s]', '')
df['punctuation_count'] = df['punctuation'].str.len()
## question mark count
df['question_count'] = df['punctuation'].str.count('[??]')
## drop punctuation column
df = df.drop(['punctuation'],axis=1)
df.iloc[:5, -4:]
  type word_count punctuation_count question_count
0 1 175 0 0
1 1 145 4 1
2 1 393 17 8
3 1 295 15 6
4 1 41 4 0
  • pandas .corr() 方法
## compute correlation
df.iloc[:, -4:].corr()
  type word_count punctuation_count question_count
type 1.000000 -0.045100 -0.024124 -0.056966
word_count -0.045100 1.000000 0.738419 0.534900
punctuation_count -0.024124 0.738419 1.000000 0.342150
question_count -0.056966 0.534900 0.342150 1.000000
  • bag of words
from sklearn.feature_extraction.text import CountVectorizer
## define transformer (轉換器)
vectorizer = CountVectorizer()
count = vectorizer.fit_transform([' '.join(x) for x in sentences])
## save data as pickle format
with open("article_count", "wb") as file:
    pickle.dump([vectorizer, count], file)
  • select top 10 frequency of words
## create a dictionary: id as key ; word as values
id2word = {v:k for k, v in vectorizer.vocabulary_.items()}
## columnwise sum: words frequency
sum_ = np.array(count.sum(axis=0))[0]
## top 10 frequency's wordID
most_sum_id = sum_.argsort()[::-1][:10].tolist()
most_sum_id

[73627, 198934, 95899, 37001, 243708, 258736, 257519, 305714, 256024, 283981]

## print top 10 frequency's words
features = [id2word[i] for i in most_sum_id]
features

[‘八卦’, ‘有沒有’, ‘台灣’, ‘一個’, ‘現在’, ‘知道’, ‘真的’, ‘覺得’, ‘看到’, ‘肥宅’]

## print the data
data = pd.DataFrame(count[df.idx.values,:][:,most_sum_id].toarray(), columns=features)
data[:5]
  八卦 有沒有 台灣 一個 現在 知道 真的 覺得 看到 肥宅
0 1 1 1 0 2 0 0 1 0 1
1 1 1 0 0 0 0 0 0 0 0
2 0 0 0 1 1 0 0 1 0 0
3 1 2 0 2 0 2 0 0 0 0
4 0 0 0 1 0 0 0 0 1 0
df.iloc[0].content

‘反核覺青現在最強招式就是 不然燃料棒放你家 肥宅我覺得 把燃料棒放到其他國家不就好了 一定會有缺錢的國家 台灣塞錢給他們 買他們國家的空間放 一來燃料棒問題解決 核電重啟 台灣缺點問題解決 大家有冷氣吹 台積電不出走 繼續救台灣 二來有買賣就有貪污空間 政客也有賺頭 不會像現在沒糖吃該該叫 送錢出去 邦交國搞不好也會多幾個 簡直是雙贏 核電燃料棒 跟其他國家買空間放不就好了 有沒有相關八卦 ‘

## compute correlation
data = pd.concat([df.type, data], axis=1)
data.corr()
  type 八卦 有沒有 台灣 一個 現在 知道 真的 覺得 看到 肥宅
type 1.000000 -0.056491 0.000898 -0.048109 -0.032585 -0.018120 -0.019432 -0.021593 -0.012116 -0.048172 -0.013955
八卦 -0.056491 1.000000 0.431786 -0.001901 0.062416 0.052670 0.091136 0.084516 0.066589 0.066047 0.077210
有沒有 0.000898 0.431786 1.000000 0.032712 0.094241 0.105734 0.144891 0.105919 0.095098 0.089291 0.043573
台灣 -0.048109 -0.001901 0.032712 1.000000 0.194281 0.188974 0.166716 0.162471 0.125782 0.137087 -0.033735
一個 -0.032585 0.062416 0.094241 0.194281 1.000000 0.400985 0.523627 0.398092 0.370977 0.327872 0.026330
現在 -0.018120 0.052670 0.105734 0.188974 0.400985 1.000000 0.418126 0.348470 0.306070 0.230148 0.009126
知道 -0.019432 0.091136 0.144891 0.166716 0.523627 0.418126 1.000000 0.486961 0.391520 0.336525 0.037975
真的 -0.021593 0.084516 0.105919 0.162471 0.398092 0.348470 0.486961 1.000000 0.461401 0.331108 0.039239
覺得 -0.012116 0.066589 0.095098 0.125782 0.370977 0.306070 0.391520 0.461401 1.000000 0.270267 0.026513
看到 -0.048172 0.066047 0.089291 0.137087 0.327872 0.230148 0.336525 0.331108 0.270267 1.000000 0.020214
肥宅 -0.013955 0.077210 0.043573 -0.033735 0.026330 0.009126 0.037975 0.039239 0.026513 0.020214 1.000000
  • TF-IDF
from sklearn.feature_extraction.text import TfidfVectorizer
## define transformer (轉換器)
vectorizer = TfidfVectorizer(norm=None) ## do not do normalize
tfidf = vectorizer.fit_transform([' '.join(x) for x in sentences])
## save data as pickle format
with open("article_tfidf", "wb") as file:
    pickle.dump([vectorizer, tfidf], file)
  • select top 10 average tf-idf words
## create a dictionary: id as key ; word as values
id2word = {v:k for k, v in vectorizer.vocabulary_.items()}
## columnwise average: words tf-idf
avg = tfidf.sum(axis=0) / (tfidf!=0).sum(axis=0)

## set df < 20 as 0
avg[(tfidf!=0).sum(axis=0)<20] = 0
avg = np.array(avg)[0]
## top 10 tfidf's wordID
most_avg_id = avg.argsort()[::-1][:10].tolist()
most_avg_id

[90835, 325364, 157970, 263428, 357411, 5490, 47011, 33207, 51405, 183683]

## print top 10 tf-idf's words
features = [id2word[i] for i in most_avg_id]
features

[‘原告’, ‘轉帳’, ‘忍術’, ‘稅後’, ‘震度’, ‘charlie’, ‘中山路’, ‘united’, ‘二段’, ‘支出’]

## print the data
data = pd.DataFrame(tfidf[df.idx.values,:][:,most_avg_id].toarray(), columns=features)
data[:5]
  原告 轉帳 忍術 稅後 震度 charlie 中山路 united 二段 支出
0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000000 0.0
1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000000 0.0
2 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000000 0.0
3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000000 0.0
4 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 9.395045 0.0
## compute correlation
data = pd.concat([df.type, data], axis=1)
data.corr()

Imgur

other features