如何用自然語言處理判斷一句話是否是問句?

請問在自然語言處理中怎麼做呢?

大概的處理思路和流程是怎樣的? 謝謝


我說個我知道的。用LSTM來做language model,即根據先前說的話,預測下一詞的可能性。

同時如果不用雙向LSTM,還可以用來自己生成有特點的句子。

比如用莎士比亞的詩集訓練的LSTM生成的句子就有莎士比亞的風格。

在這裡不論是單詞還是標點符號。都是平等對待的。

-----------------------------------------------------------------------

拿到訓練數據後,先決定辭彙大小,也就向量長度。

按頻率將辭彙排序,去掉超過辭彙大小的低頻辭彙。把所有單詞編碼,包括標點符號

再加入起始、結束符號。

例:

假如就有7個字元:今天,你吃了嗎?

再加上句子開始句子結束符號,並全部編上序號。

-----------------------------------------------------------------------

開始($):0

今:1

天:2

,:3

你:4

吃:5

了:6

嗎:7

?:8

結束(#):9

-----------------------------------------------------------------------

input和output是同一句話,但是output前移一位。

input: [$今天,你吃了嗎? ]----&>[012345678]

output: [今天,你吃了嗎? #]----&>[123456789]

再把序號轉成one-hot vector(只有序號的位置是1,其他位置都是0)。

一個句子就變成了一個矩陣:row是辭彙數;colum是vector的dimension,也是辭彙大小。

該句子的矩陣如下:(我舉例用的辭彙僅有10個,但是正常情況下會有上千個辭彙。行向量的維度會非常高,比如8000維度,12000維度;而且index是按照出現頻率排列的話,就不會像我下面的矩陣那樣像單位矩陣似的,而是矩陣內,對應著1的index的位置根據單詞而定)

left[
 egin{matrix}
  1000000000\
  0100000000 \
  0010000000 \
  0001000000 \
  0000100000 \
  0000010000 \
  0000001000 \
  0000000100 \
  0000000010 \
  end{matrix}
  
ight]

輸入到網路的時候,一個一個行向量輸入。LSTM會記住之前的vector的信息。

-----------------------------------------------------------------------

Input layer:

content: a sequence of one-hot vectors

shape:[batch_size, timestep, one-vector dimension]

word embedding layer:

shape:[batch_size, timestep, embedding dimension]

LSTM/GRU:

shape:[batch_size, timestep, hidden dimension]

more LSTM/GRUs

...

softmax output layer:

shape:[batch_size, timestep, one-vector dimension]

這裡可以輸入出整個的矩陣,但一般只需要一個。也就是最後一個詞。

-----------------------------------------------------------------------

比如輸入信息:[$今天,你吃]

矩陣如下:

left[
 egin{matrix}
  1000000000\
  0100000000 \
  0010000000 \
  0001000000 \
  0000100000 \
 0000010000 \

  end{matrix}
  
ight]

輸出只要「吃」後面可能出現的字的概率。

輸出是一個向量,每一維表示著最後一個字是你辭彙中對應字的概率。

比如輸出就可能為: left[
 egin{matrix}
  0.030.01 0.01 0.050.050.050.8000
  end{matrix}
  
ight]

其中對應著「了」的概率最大

-----------------------------------------------------------------------

如果要生成句子:

輸入起始符號,生成第一個詞,再把生成詞和之前的所有詞的作為輸入不斷循環生成,直到得到結束符號為止。

其中詞從多大的概率中選擇是可以調節的。概率的門檻降低,生成的句子的更有創造力,概率的門檻高,生成的句子更符合語法。


問句很多都是語氣來判斷的

就比如

"有人邀請我。"

"有人邀請我?"

"怎麼這麼大?"

"怎麼這麼大。"

上面的語句僅僅是語氣的變化,語境甚至都是可以通用的,沒有標點人類都很難知道是不是問句

從機器學習的角度來講,可以找很多句子,標明問句,監督學習,樸素貝葉斯處理垃圾郵件的那套思路

比較好的結果就是提取到"為什麼","到底","怎麼","嗎"之類的詞,是問句的權值就變大,就更像是一個問句

但是還是有我提到的問題,有些句子是沒法判斷的

你要是讀研做課題,你可以試試這個方法,但是可能經不起推敲

你要是做項目還不如判斷一下常用的問句的詞,判斷一下問號,正確率都要比演算法要高


先聲明,本人沒做過自然語言處理,但是看見別人做過一些。所以說的有可能不對,或者不全。

據我所知,主要有這麼幾步。

1,分詞。

也就是把整個句子斷成數個片語。比如「你幾點去吃飯?」,會斷成,「你」,「幾點」,「去」,「吃飯」,「?」。在這裡就可以看出英文比中文好分析的多,因為英文不用分詞。分詞是中文分析中的一個難點,不過應該已經有很多人做了,我看同學用的分詞器已經挺準確的了,但是運算量很大。

2,詞義分析。

這個你需要一個資料庫,當然也有現成的。這一步要為每一個詞提供一個可能的詞性,詞義列表。

3,句式分析。

根據句式機構來確定每個詞的在句子中的作用。比如主謂賓什麼的。然後根據每個詞的作用從上一步的列表中選擇正確的詞性詞義。這裡也有可能會有多種結果。

4,句意分析。

這就就是核心了,具體怎麼做的我就不清楚了。這邊就需要AI了,有時候還要根據上下文來確定句意。順便吐槽一下。題主所問的疑問句分析,在中文中應該是靠詞義來確定的,比如「幾點」就帶有疑問的含義,但是這也要結合語境。比如「這都幾點了!你怎麼還不去睡覺?!」雖然第二句有疑問的意思,但是這裡的「幾點」並沒有疑問的意思。相對的英文分析就簡單的多。正規的疑問句全都倒裝,好分析的多。


直接統計下問號,等一些語言上的規則,如 嗎 do you 應該效果就不錯了吧?人自己其實也是根據這些依賴判斷,真正需要依賴上下文的case應該不多


沒用LSTM,就用了SVM做,測試正確率99.5%(ps訓練模型和例子都挺標準,沒樓上舉例子的那麼邊緣特例)


看有沒有問號


做一個分類器就可以,可以根據輸出倒推輸入,我們可以根據已有問句實例,分析此句子如何構成問句的,在大量樣本後,你就可以得出如何構造問句的模式,然後利用此模式去識別輸入的句子是否為問句。


從句子內容中提取特徵,例如POS,詞語,N-gram等特徵,做個分類器,例如使用最大熵,來決定結尾使用句號還是問號還是嘆號~~balabala~估計可以~


推薦閱讀:

MLE,MAP,EM 和 point estimation 之間的關係是怎樣的?

TAG:Python | 數據挖掘 | 機器學習 | 自然語言處理 | 文本分析 |