Grafik untuk menghubungkan kalimat

Aug 20 2020

Saya memiliki daftar kalimat dari beberapa topik (dua) seperti di bawah ini:

Sentences
Trump says that it is useful to win the next presidential election. 
The Prime Minister suggests the name of the winner of the next presidential election.
In yesterday's conference, the Prime Minister said that it is very important to win the next presidential election. 
The Chinese Minister is in London to discuss about climate change.
The president Donald Trump states that he wants to win the presidential election. This will require a strong media engagement.
The president Donald Trump states that he wants to win the presidential election. The UK has proposed collaboration. 
The president Donald Trump states that he wants to win the presidential election. He has the support of his electors. 

Seperti yang Anda lihat, ada kesamaan dalam kalimat.

Saya mencoba menghubungkan banyak kalimat dan memvisualisasikan karakteristiknya dengan menggunakan grafik (diarahkan). Grafik tersebut dibangun dari matriks kemiripan, dengan menerapkan urutan kalimat seperti gambar di atas. Saya membuat kolom baru, Waktu, untuk menunjukkan urutan kalimat, jadi baris pertama (Trump mengatakan bahwa ....) adalah pada waktu 1; baris kedua (Perdana Menteri menyarankan ...) pada jam ke-2, dan seterusnya. Sesuatu seperti ini

Time    Sentences
1           Trump said that it is useful to win the next presidential election. 
2           The Prime Minister suggests the name of the winner of the next presidential election.

3           In today's conference, the Prime Minister said that it is very important to win the next presidential election. 

...

Saya kemudian ingin menemukan hubungan agar memiliki gambaran yang jelas tentang topik tersebut. Beberapa jalur untuk kalimat akan menunjukkan bahwa ada beberapa informasi yang terkait dengannya. Untuk menentukan kesamaan antara dua kalimat, saya mencoba mengekstrak kata benda dan kata kerja sebagai berikut:

noun=[]
verb=[]
for  index, row in df.iterrows():
      nouns.append([word for word,pos in pos_tag(row[0]) if pos == 'NN'])
      verb.append([word for word,pos in pos_tag(row[0]) if pos == 'VB'])

karena merupakan kata kunci dalam kalimat apa pun. Jadi ketika kata kunci (kata benda atau kata kerja) muncul di kalimat x tetapi tidak muncul di kalimat lain, ini mewakili perbedaan antara kedua kalimat ini. Saya pikir pendekatan yang lebih baik, bagaimanapun, bisa menggunakan word2vec atau gensim (WMD).

Kesamaan ini harus dihitung untuk setiap kalimat. Saya ingin membuat grafik yang menunjukkan isi kalimat dalam contoh saya di atas. Karena ada dua topik (Trump dan Menteri China), untuk masing-masing saya perlu mencari sub-topik. Trump memiliki pemilihan presiden sub-topik, misalnya. Sebuah simpul di grafik saya harus mewakili sebuah kalimat. Kata-kata di setiap node mewakili perbedaan kalimat, menunjukkan info baru dalam kalimat. Misalnya, kata statesdalam kalimat pada waktu 5 berada dalam kalimat yang berdekatan pada waktu 6 dan 7. Saya hanya ingin mencari cara untuk mendapatkan hasil yang serupa seperti yang ditunjukkan pada gambar di bawah. Saya telah mencoba menggunakan ekstraksi terutama kata benda dan kata kerja, tetapi mungkin itu bukan cara yang tepat untuk melanjutkan. Apa yang saya coba lakukan adalah mempertimbangkan kalimat pada waktu 1 dan membandingkannya dengan kalimat lain, menetapkan skor kesamaan (dengan ekstraksi kata benda dan kata kerja tetapi juga dengan word2vec), dan mengulanginya untuk semua kalimat lainnya. Tapi masalah saya sekarang adalah bagaimana mengekstrak perbedaan untuk membuat grafik yang masuk akal.

Untuk bagian grafik, saya akan mempertimbangkan untuk menggunakan networkx (DiGraph):

G = nx.DiGraph()
N = Network(directed=True) 

untuk menunjukkan arah hubungan.

Saya memberikan contoh yang berbeda untuk membuatnya lebih jelas (tetapi jika Anda bekerja dengan contoh sebelumnya, itu akan baik-baik saja juga. Maaf atas ketidaknyamanan ini, tetapi karena pertanyaan pertama saya tidak begitu jelas, saya harus memberikan juga yang lebih baik, mungkin lebih mudah, misalnya).

Jawaban

4 ilia Oct 10 2020 at 17:42

Tidak menerapkan NLP untuk pemisahan kata kerja / kata benda, hanya menambahkan daftar kata yang bagus. Mereka dapat diekstraksi dan dinormalisasi dengan spacy yang relatif mudah. Harap dicatat bahwa walkterjadi dalam 1,2,5 kalimat dan membentuk triad.

import re
import networkx as nx
import matplotlib.pyplot as plt

plt.style.use("ggplot")

sentences = [
    "I went out for a walk or walking.",
    "When I was walking, I saw a cat. ",
    "The cat was injured. ",
    "My mum's name is Marylin.",
    "While I was walking, I met John. ",
    "Nothing has happened.",
]

G = nx.Graph()
# set of possible good words
good_words = {"went", "walk", "cat", "walking"}

# remove punctuation and keep only good words inside sentences
words = list(
    map(
        lambda x: set(re.sub(r"[^\w\s]", "", x).lower().split()).intersection(
            good_words
        ),
        sentences,
    )
)

# convert sentences to dict for furtehr labeling
sentences = {k: v for k, v in enumerate(sentences)}

# add nodes
for i, sentence in sentences.items():
    G.add_node(i)

# add edges if two nodes have the same word inside
for i in range(len(words)):
    for j in range(i + 1, len(words)):
        for edge_label in words[i].intersection(words[j]):
            G.add_edge(i, j, r=edge_label)

# compute layout coords
coord = nx.spring_layout(G)

plt.figure(figsize=(20, 14))

# set label coords a bit upper the nodes
node_label_coords = {}
for node, coords in coord.items():
    node_label_coords[node] = (coords[0], coords[1] + 0.04)

# draw the network
nodes = nx.draw_networkx_nodes(G, pos=coord)
edges = nx.draw_networkx_edges(G, pos=coord)
edge_labels = nx.draw_networkx_edge_labels(G, pos=coord)
node_labels = nx.draw_networkx_labels(G, pos=node_label_coords, labels=sentences)
plt.title("Sentences network")
plt.axis("off")

Perbarui
Jika Anda ingin mengukur kesamaan antara kalimat yang berbeda, Anda mungkin ingin menghitung perbedaan antara penyematan kalimat.
Ini memberi Anda kesempatan untuk menemukan kemiripan semantik antara kalimat dengan kata yang berbeda seperti "Pertandingan sepak bola dengan banyak pria bermain" dan "Beberapa pria sedang berolahraga". Hampir pendekatan SoTA menggunakan BERT dapat ditemukan di sini , pendekatan yang lebih sederhana ada di sini .
Karena Anda memiliki ukuran kesamaan, cukup ganti blok add_edge untuk menambahkan edge baru hanya jika ukuran kesamaan lebih besar dari beberapa ambang batas. Hasil add edge code akan terlihat seperti ini:

# add edges if two nodes have the same word inside
tresold = 0.90
for i in range(len(words)):
    for j in range(i + 1, len(words)):
        # suppose you have some similarity function using BERT or PCA
        similarity = check_similarity(sentences[i], sentences[j])
        if similarity > tresold:
            G.add_edge(i, j, r=similarity)
1 mujjiga Oct 10 2020 at 20:09

Salah satu cara untuk mengatasinya adalah dengan membuat token, menghapus kata-kata berhenti dan membuat kosakata. Kemudian gambar grafik berdasarkan kosakata ini. Saya tunjukkan di bawah ini dan contoh token berbasis unigram tetapi pendekatan yang jauh lebih baik adalah mengidentifikasi frasa (ngram) dan menggunakannya sebagai kosa kata daripada unigram. Kalimat serupa akan digambarkan secara bergambar oleh node (dan kalimat yang sesuai) yang memiliki lebih banyak dalam dan derajat.

Sampel:

from sklearn.feature_extraction.text import CountVectorizer
import networkx as nx
import matplotlib.pyplot as plt


corpus = [
  "Trump says that it is useful to win the next presidential election",
  "The Prime Minister suggests the name of the winner of the next presidential election",
  "In yesterday conference, the Prime Minister said that it is very important to win the next presidential election",
  "The Chinese Minister is in London to discuss about climate change",
  "The president Donald Trump states that he wants to win the presidential election. This will require a strong media engagement",
  "The president Donald Trump states that he wants to win the presidential election. The UK has proposed collaboration",
  "The president Donald Trump states that he wants to win the presidential election. He has the support of his electors",
]

vectorizer = CountVectorizer(analyzer='word', ngram_range=(1, 1), stop_words="english")
vectorizer.fit_transform(corpus)


G = nx.DiGraph()
G.add_nodes_from(vectorizer.get_feature_names())

all_edges = []
for s in corpus:
  edges = []
  previous = None
  for w in s.split():
    w = w.lower()
    if w in vectorizer.get_feature_names():
      if previous:
        edges.append((previous, w))
        #print (previous, w)
      previous = w   

  all_edges.append(edges)


plt.figure(figsize=(20,20))
pos = nx.shell_layout(G)
nx.draw_networkx_nodes(G, pos, node_size = 500)
nx.draw_networkx_labels(G, pos)
colors = ['r', 'g', 'b', 'y', 'm', 'c', 'k']
for i, edges in enumerate(all_edges):
  nx.draw_networkx_edges(G, pos, edgelist=edges, edge_color=colors[i], arrows=True)
#nx.draw_networkx_edges(G, pos, edgelist=black_edges, arrows=False)
plt.show()

Keluaran: