有趣的 NLP (譯一)

從文本中提取含義并不容易

閱讀和理解英語的過程是非常復雜的,這個過程甚至沒有包括考慮到英語有時并不遵循邏輯和一致的規則。例如,這條新聞標題是什么意思?

「Environmental regulators grill business owner over illegal coal fires.」

是監管者質疑企業所有者非法燃燒煤炭嗎?還是監管者真的在架起企業所有者并用煤炭燒烤?正如你所看到的,用計算機解析英語將會變得非常復雜。

在機器學習中做任何復雜的事情通常意味著需要建立一條流水線 (pipeline)。這個想法是把你的問題分解成非常小的部分,然后用機器學習來分別解決每個部分,最后通過把幾個互相饋送結果的機器學習模型連接起來,這樣你就可以解決非常復雜的問題。

這正是我們要運用在 NLP 上的策略。我們將把理解英語的過程分解成小塊,然后看看每個小塊是如何工作的。

一步一步建立 NLP 流水線

讓我們來看看來自維基百科的一段文字:

London is the capital and most populous city of England and the United Kingdom. Standing on the River Thames in the south east of the island of Great Britain, London has been a major settlement for two millennia. It was founded by the Romans, who named it Londinium.

(倫敦是英格蘭的首都同時也是英國人口最大的城市,是大不列顛東南部的泰晤士河流域兩千年來的主要人類定居點,由羅馬人建立,取名為倫蒂尼恩 (Londinium)。

這一段話包含了一些有用的事實。如果一臺電腦能閱讀這篇文章,理解到倫敦是一座城市,倫敦位于英國,倫敦由羅馬人定居,那就太好了。但是為了達到這個目的,我們首先必須教會計算機最基本的書面語言概念,然后基于此再逐步進行完善。

步驟 1:句子分割

流水線的第一步是把文本拆分成單獨的句子,像這樣:

1.「倫敦是英格蘭的首都同時也是英國人口最多的城市。」

2.「位于大不列顛島東南部的泰晤士河流域的倫敦是兩千年以來的主要人類定居點。」

3.「由羅馬人建立,取名為倫蒂尼恩 (Londinium)。」

我們可以假設英語中的每個句子都表達了一個獨立的思想或想法。編寫一個程序來理解一個句子比理解整個段落要容易得多。

編碼一個句子分割模型可以很簡單地在任何看到標點符號的時候拆分句子。但是,現代 NLP 流水線通常使用更為復雜的技術,以應對那些沒有被格式化干凈的文件。

步驟 2:詞匯標記化

現在我們已經把文檔分割成句子,我們可以一次處理一個。讓我們從文檔中的第一句話開始:

「London is the capital and most populous city of England and the United Kingdom.」

我們的下一步是把這個句子分成不同的單詞或標記,這叫做標記化,下面是標記化后的結果:

「London」,「is」,「the」,「capital」,「and」,「most」,「populous」,「city」,「of」,「England」,「and」,「the」,「United」,「Kingdom」,「.」

英語中的標記化是很容易做到的。只要它們之間有空格,我們就把它們分開。我們也將標點符號當作單獨的記號來對待,因為標點也是有意義的。

步驟 3:預測每個標記的詞性

接下來,我們來看看每一個標記,并嘗試猜測它的詞類:名詞,動詞,形容詞等等。知道每個單詞在句子中的作用將幫助我們弄清楚句子的意思。

我們可以把每個單詞(和它周圍的一些額外的單詞用于上下文)輸入預先訓練的詞性分類模型:

image

詞性模型最初是通過給它提供數以百萬計的英語句子來訓練的,每一個單詞的詞性都已經標注出來,并讓它學會復制這種行為。

需要注意的是,這個模型完全是基于統計數據的,它并沒有真正理解單詞的意思(如人類所思考的一樣)。它只知道如何根據相似的句子和單詞來猜測詞性。

在處理完整個句子之后,我們將得到這樣的結果:

image

有了這些信息,我們就可以開始獲取一些非常基本的意思了。例如,我們可以看到句子中的名詞包括「倫敦」和「首都」,所以這個句子很可能說的的是關于倫敦。

步驟 4:文本詞形還原

在英語(和大多數語言)中,單詞以不同的形式出現。看這兩個句子:

  • I had a pony.

  • I had two ponies.

兩個句子都是在討論一個名詞 - 小馬(pony),但它們分別使用了不同的詞形變化 (一個單數形式,一個復數形式)。當在計算機中處理文本時,了解每個單詞的基本形式是有幫助的,這樣你才知道這兩個句子都在討論同一個概念。否則,對計算機來說字串「pony」和「ponies」看起來就像兩個完全不同的詞匯。

在 NLP 中,我們把這個過程稱為詞形還原——找出句子中每個單詞的最基本的形式或詞條。

同樣也適用于動詞。我們也可以通過找到它們的詞根,通過詞形還原來將動詞轉換成非結合格式。所以「I had two ponies.」變成「I [have] two [pony].」

詞形還原通常是通過基于詞性的詞條形式的查找表來完成的,并且可能通過一些自定義規則來處理一些你從未見過的單詞。

下面是詞形還原加上動詞的詞根形式后,我們的句子變成如下:

image

我們唯一的改變是把「is」變成「be」。

步驟 5:識別停止詞

接下來,我們要考慮句子中每個詞的重要性。英語有很多填充詞,它們經常出現,如「and」、「the」和「a」。當對文本進行統計時,這些詞引入了大量的噪聲,因為它們比其他詞更頻繁地出現。一些 NLP 流水線將它們標記為「停止詞」,也就是說,在進行任何統計分析之前,這可能是你想要過濾掉的單詞。

下面是我們將停止詞變成灰色后的句子:

image

停止詞通常通過檢查已知的停止詞的硬編碼列表來識別。但是沒有適用于所有應用程序的停止詞的標準列表。要忽略的單詞列表可以根據應用程序而變化。

例如,如果你正在建造一個搖滾樂隊搜索引擎,你要確保你不忽略「The」這個詞。因為這個詞出現在很多樂隊的名字中,還有一個著名的 1980 搖滾樂隊叫做「The The」!

步驟 6a:依賴解析

下一步是弄清楚我們句子中的所有單詞是如何相互關聯的,這叫做依賴解析。

我們的目標是構建一棵樹,它給句子中的每個單詞分配一個單一的父詞。樹的根結點是句子中的主要動詞。下面是我們的句子的<mark data-type="technologies" data-id="61ab5a9c-a246-4ae1-b18e-b6d4102b06a7" class="tooltipstered" style="box-sizing: border-box; line-height: 2; background-color: transparent; color: inherit; cursor: pointer; border-bottom: 1px solid rgb(235, 40, 53);">解析樹</mark>一開始的樣子:

image

但我們可以更進一步。除了識別每個單詞的父詞外,我們還可以預測兩個詞之間存在的關系類型:

示例圖片

這棵解析樹告訴我們,句子的主語是名詞「London」,它與「capital」有「be」關系。我們終于知道了一些有用的東西——倫敦是一個首都!如果我們遵循完整的解析樹的句子(除上方所示),我們甚至會發現,倫敦是英國的首都。

就像我們先前使用機器學習模型預測詞性一樣,依賴解析也可以通過將單詞輸入機器學習模型并輸出結果來工作。但是解析單詞的依賴項是一項特別復雜的任務,需要一篇完整的文章來詳細說明。如果你想知道它是如何工作的,一個很好的開始閱讀的地方是 Matthew Honnibal 的優秀文章「Parsing English in 500 Lines of Python」。

但是,盡管作者在 2015 的一篇文章中說這種方法在現在是標準的,但它實際上已經過時了,甚至不再被作者使用。在 2016,谷歌發布了一個新的依賴性分析器,稱為 Parsey McParseface,它使用了一種新的深度學習方法并超越了以前的基準,它迅速地遍及整個行業。一年后,他們發布了一種新的叫做 ParseySaurus 的模型,它改進了更多的東西。換句話說,解析技術仍然是一個活躍的研究領域,在不斷地變化和改進。

同樣需要記住的是,很多英語句子都是模棱兩可的,難以解析的。在這種情況下,模型將根據該句子的解析版本進行猜測,但它并不完美,有時該模型將導致令人尷尬的錯誤。但隨著時間的推移,我們的 NLP 模型將繼續以更好的方式解析文本。

步驟 6b:尋找名詞短語

到目前為止,我們把句子中的每個詞都看作是獨立的實體。但是有時候把代表一個想法或事物的單詞組合在一起更有意義。我們可以使用依賴解析樹中的相關信息自動將所有討論同一事物的單詞組合在一起。

例如:

詞性

我們可以將名詞短語組合以產生下方的形式:

映射

我們是否做這一步取決于我們的最終目標。如果我們不需要更多的細節來描述哪些詞是形容詞,而是想更多地關注提取完整的想法,那么這是一種快速而簡單的方法。

** 步驟 7:命名實體識別 (NER) **

現在我們已經完成所有困難的工作,終于可以超越小學語法,開始真正地提取想法。

在我們的句子中,我們有下列名詞:

image

這些名詞中有一些是真實存在的。例如,「London 倫敦」、「England 英格蘭」和「United Kingdom 英國」代表地圖上的物理位置。很高興能檢測到這一點!利用這些信息,我們可以使用 NLP 自動提取到文檔中提到的真實世界地名的列表。

命名實體識別(NER)的目標是用它們所代表的真實世界的概念來檢測和標記這些名詞。以下是我們在使用 NER 標簽模型運行每個標簽之后的句子:

image

但是 NER 系統不僅僅是簡單的字典查找。相反,他們使用的是一個單詞如何出現在句子中的上下文和一個統計模型來猜測單詞代表的是哪種類型的名詞。一個好的 NER 系統可以通過上下文線索來區分「Brooklyn Decker」這個人名和「Brooklyn」這個位置。

下面是一些典型的 NER 系統可以標記的對象類型:

  • 人名

  • 公司名稱

  • 地理位置(物理和政治)

  • 產品名稱

  • 日期與時間

  • 金錢數量

  • 事件名稱

NER 有大量的用途,因為它可以很容易地從文本中獲取結構化數據。這是從 NLP 流水線中快速獲取有價值信息的最簡單方法之一。

步驟 8:共指解析

到此,我們對句子已經有了一個很好的表述。我們知道每個單詞的詞性、單詞如何相互關聯、哪些詞在談論命名實體。

然而,我們還有一個大問題。英語里充滿了人稱代詞,比如他、她,還有它。這些是我們使用的快捷表述方法,而不需要在每個句子中一遍又一遍地寫名字。人類可以根據上下文來記錄這些詞所代表的內容。但是我們的 NLP 模型不知道人稱代詞是什么意思,因為它一次只檢查一個句子。

讓我們看看文檔中的第三句話:

「It was founded by the Romans, who named it Londinium.」

如果我們用 NLP 流水線來解析這個句子,我們就會知道「it」是由羅馬人建立的。但知道「London」是由羅馬人建立的則更為有用。

人類閱讀這個句子時,可以很容易地理解「it」的意思是「London」。共指解析的目的是通過追蹤句子中的代詞來找出相同的映射。我們想找出所有提到同一個實體的單詞。

下面是我們的文檔中對「London」一詞的共指解析的結果:

示例圖片

利用共指信息與解析樹和命名實體信息相結合,我們可以從文檔中提取大量信息。

共指解析是 NLP 流水線實現中最困難的步驟之一。這比句子分析更困難。深度學習的最新進展研究出了更精確的新方法,但還不完善。如果您想了解更多關于它是如何工作的,請查看:https://explosion.ai/demos/displacy-ent

NLP 流水線的 PYTHON 實現

下面是我們完整的 NLP 流水線的概述:

image

共指解析是一個不一定要完成的可選步驟。

喲,看起來有好多步驟!

注意:在我們繼續之前,值得一提的是,這些是典型的 NLP 流水線中的步驟,但是您可以將跳過某些步驟或重新排序步驟,這取決于您想做什么以及如何實現 NLP 庫。例如,像 spaCy 這樣的一些庫是在使用依賴性解析的結果后才在流水線中進行句子分割。

那么,我們應該如何對這個流水線進行編碼呢?感謝像 spaCy 這樣神奇的 Python 庫,它已經完成了!這些步驟都是編碼過的,可以隨時使用。

首先,假設已經安裝了 Python 3,可以這樣安裝 spaCy:

# Install spaCy 
pip3 install -U spacy

# Download the large English model for spaCy
python3 -m spacy download en_core_web_lg

# Install textacy which will also be useful
pip3 install -U textacy

然后,在一段文本上運行 NLP 流水線的代碼看起來如下:

import spacy

# Load the large English NLP model
nlp = spacy.load('en_core_web_lg')

# The text we want to examine
text = """London is the capital and most populous city of England and 
the United Kingdom.  Standing on the River Thames in the south east 
of the island of Great Britain, London has been a major settlement 
for two millennia. It was founded by the Romans, who named it Londinium.
"""

# Parse the text with spaCy. This runs the entire pipeline.
doc = nlp(text)

# 'doc' now contains a parsed version of text. We can use it to do anything we want!
# For example, this will print out all the named entities that were detected:
for entity in doc.ents:
    print(f"{entity.text} ({entity.label_})")

如果你運行到 z 這里,你將得到一個在我們的文檔中檢測到的命名實體和實體類型的列表:

London (GPE)
England (GPE)
the United Kingdom (GPE)
the River Thames (FAC)
Great Britain (GPE)
London (GPE)
two millennia (DATE)
Romans (NORP)
Londinium (PERSON)

您可以在這里查找這些代碼:https://spacy.io/usage/linguistic-features#entity-types

注意它在「Londinium」上犯了一個錯誤,認為它是一個人的名字而不是一個地方。這可能是因為在訓練數據集中沒有類似的東西,所以它做了最好的猜測。命名實體檢測通常需要一小段模型微調(https://spacy.io/usage/training#section-ner),如果您正在解析具有獨特或專用術語的文本。

讓我們來檢測實體并使用它來建立一個數據洗滌器。假設你正試圖遵守新的 GDPR 隱私規則(https://medium.com/@ageitgey/understand-the-gdpr-in-10-minutes-407f4b54111f),并且你發現你有數以千計的文件,其中包含有個人可識別的信息,比如人的名字。你接到了移除文檔中所有名字的任務。

通過數以千計的文件去搜尋并刪除所有的名字,人工可能需要幾年。但是使用 NLP,這是很容易實現的。這里有一個簡單的洗滌器,去除它檢測到的所有名字:

import spacy

# Load the large English NLP model
nlp = spacy.load('en_core_web_lg')

# Replace a token with "REDACTED" if it is a name
def replace_name_with_placeholder(token):
    if token.ent_iob != 0 and token.ent_type_ == "PERSON":
        return "[REDACTED] "
    else:
        return token.string

# Loop through all the entities in a document and check if they are names
def scrub(text):
    doc = nlp(text)
    for ent in doc.ents:
        ent.merge()
    tokens = map(replace_name_with_placeholder, doc)
    return "".join(tokens)

s = """
In 1950, Alan Turing published his famous article "Computing Machinery and Intelligence". In 1957, Noam Chomsky’s 
Syntactic Structures revolutionized Linguistics with 'universal grammar', a rule based system of syntactic structures.
"""

print(scrub(s))

如果你運行它,你會發現它的結果是符合你的預期的:

In 1950, [REDACTED] published his famous article "Computing Machinery and Intelligence". In 1957, [REDACTED] 
Syntactic Structures revolutionized Linguistics with 'universal grammar', a rule based system of syntactic structures.

提取事實

你能用 spaCy 做的事情是非常多的。但是,您也可以使用 spaCy 解析的輸出作為更復雜的數據提取算法的輸入。有一個 Python 庫叫做 textacy,它在 spaCy 之上實現了幾種常見的數據抽取算法。這是一個很好的起點。

它實現的一種算法被稱為半結構化語句提取。我們可以用它來搜索解析樹,用于簡單的語句,其中主語是「London」,動詞是「be」的形式。這將有助于我們找到有關倫敦的事實。

以下是它的代碼實現:

import spacy
import textacy.extract

# Load the large English NLP model
nlp = spacy.load('en_core_web_lg')

# The text we want to examine
text = """London is the capital and most populous city of England and  the United Kingdom.  
Standing on the River Thames in the south east of the island of Great Britain, 
London has been a major settlement  for two millennia.  It was founded by the Romans, 
who named it Londinium.
"""

# Parse the document with spaCy
doc = nlp(text)

# Extract semi-structured statements
statements = textacy.extract.semistructured_statements(doc, "London")

# Print the results
print("Here are the things I know about London:")

for statement in statements:
    subject, verb, fact = statement
    print(f" - {fact}")

結果如下:

Here are the things I know about London:
 - the capital and most populous city of England and the United Kingdom.
- a major settlement for two millennia.

也許這不太令人印象深刻。但是如果你在整個倫敦維基百科的文章文本上運行相同的代碼而不僅僅是三個句子,你會得到更令人印象深刻的結果:

Here are the things I know about London:
 - the capital and most populous city of England and the United Kingdom
 - a major settlement for two millennia
 - the world's most populous city from around 1831 to 1925
 - beyond all comparison the largest town in England
 - still very compact
 - the world's largest city from about 1831 to 1925
 - the seat of the Government of the United Kingdom
 - vulnerable to flooding
 - "one of the World's Greenest Cities" with more than 40 percent green space or open water
 - the most populous city and metropolitan area of the European Union and the second most populous in Europe
 - the 19th largest city and the 18th largest metropolitan region in the world
 - Christian, and has a large number of churches, particularly in the City of London
 - also home to sizeable Muslim, Hindu, Sikh, and Jewish communities
 - also home to 42 Hindu temples
 - the world's most expensive office market for the last three years according to world property journal (2015) report
 - one of the pre-eminent financial centres of the world as the most important location for international finance
 - the world top city destination as ranked by TripAdvisor users
 - a major international air transport hub with the busiest city airspace in the world
 - the centre of the National Rail network, with 70 percent of rail journeys starting or ending in London
 - a major global centre of higher education teaching and research and has the largest concentration of higher education institutes in Europe
 - home to designers Vivienne Westwood, Galliano, Stella McCartney, Manolo Blahnik, and Jimmy Choo, among others
 - the setting for many works of literature
 - a major centre for television production, with studios including BBC Television Centre, The Fountain Studios and The London Studios
 - also a centre for urban music
 - the "greenest city" in Europe with 35,000 acres of public parks, woodlands and gardens
 - not the capital of England, as England does not have its own government

現在事情正在變得更加趣了!這是我們自動收集的大量信息。

要獲得額外的支持,請嘗試安裝 neuralcoref 庫,并將 Coreference 解析添加到流水線中。這會讓你得到更多的事實,因為它會抓住談論「it」而不是直接提及「London」的句子。

我們還能做些什么呢?

通過瀏覽 spaCy 文檔和 textacy 文檔,你可以看到許多可以用解析文本處理的示例。到目前為止,我們看到的只是一個小型示例。

下面是另一個實際例子:假設你正在構建一個網站,讓用戶使用最后一個例子中提取的信息查看世界上每一個城市的信息。

如果你在網站上有一個搜索功能,那么可以自動完成像谷歌這樣的普通搜索查詢:

Google‘s autocomplete suggestions for「London」

示例圖片

谷歌對「London」的自我完善的建議

但是要做到這一點,我們需要一個可能的完善建議的列表來向用戶提出建議。我們可以使用 NLP 來快速生成這些數據。

下面是從文檔中提取頻繁提到的名詞塊的一種方法:

import spacy
import textacy.extract

# Load the large English NLP model
nlp = spacy.load('en_core_web_lg')

# The text we want to examine
text = """London is [.. shortened for space ..]"""

# Parse the document with spaCy
doc = nlp(text)

# Extract noun chunks that appear
noun_chunks = textacy.extract.noun_chunks(doc, min_freq=3)

# Convert noun chunks to lowercase strings
noun_chunks = map(str, noun_chunks)
noun_chunks = map(str.lower, noun_chunks)

# Print out any nouns that are at least 2 words long
for noun_chunk in set(noun_chunks):
    if len(noun_chunk.split(" ")) > 1:
        print(noun_chunk)

如果你在倫敦維基百科的文章上運行,你會得到這樣的輸出:

westminster abbey
natural history museum
west end
east end
st paul's cathedral
royal albert hall
london underground
great fire
british museum
london eye
.... etc ....

深入探討

這只是一個微小的嘗試,讓你去理解可以用 NLP 做什么。在以后的文章中,我們將討論 NLP 的其他應用,如文本分類以及 Amazon Alexa 等系統如何解析問題。

但在此之前,先安裝 spaCy(https://spacy.io/)并開始去使用它!可能你不是一個 Python 用戶,也可能你最終使用是一個不同的 NLP 庫,但這些想法都應該是大致相同。

原文鏈接: https://medium.com/@ageitgey/natural-language-processing-is-fun-9a0bff37854e

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,908評論 2 372