Tạo câu từ từ khóa Python

Điên phải không? . Không một người trưởng thành nào lại nghĩ ra một thứ vô lý như vậy…

“Donald Trump Là” Kỳ Lân, Cưỡi Kỳ Lân Trên Cầu Vồng”, Theo Sean Spicer

Oh Boy
Đối với tôi, điều đó nghe có vẻ như nó được tạo ra bởi một trình tạo câu ngẫu nhiên. Mặc dù đáng buồn là không phải vậy, nhưng tôi tự hỏi có bao nhiêu (hoặc nếu) các tiêu đề tin tức được tạo ngẫu nhiên có thể trở nên điên rồ hơn thế. Vì vậy, tôi quyết định xây dựng một tập lệnh Python và tự mình xem

Tập lệnh bao gồm một công cụ quét web nhanh để lấy càng nhiều tiêu đề tin tức càng tốt và sử dụng chúng trong trình tạo câu mẫu Markov để tạo tiêu đề 'tin thật giả' của riêng tôi. Mặc dù kiểu dữ liệu từ điển Python ban đầu có vẻ phù hợp với mô hình Markov, nhưng tôi muốn sử dụng khung dữ liệu và gấu trúc cho nó. Đơn giản vì tôi muốn thực hành một số chức năng của pandas và cuối cùng tôi không quan tâm đến cách làm “thanh lịch” nhất trong trường hợp này, nhưng tôi muốn có kết quả nhanh chóng và học được điều gì đó trong quá trình thực hiện
Đầu tiên, tôi thiết lập một tập lệnh đang truy cập một trang tin tức phổ biến bằng từ khóa 'Donald Trump'. Sau đó, tôi tách văn bản chứa các tiêu đề và viết chúng vào một tệp văn bản. Tôi thấy trang web này cực kỳ hữu ích để thiết lập đoạn mã nhỏ của tôi

https. //trăn thật. com/python-web-scraping-practical-giới thiệu/

Vào bất kỳ ngày nào, điều này sẽ cung cấp cho tôi khoảng 100–120 tiêu đề tin tức. Không tệ, nhưng tất nhiên làm điều đó một lần sẽ mang lại rất ít từ để sử dụng và chuỗi Markov của tôi có nguy cơ thường xuyên rơi vào một chuỗi từ duy nhất — và trong trường hợp xấu nhất — chỉ lặp lại tiêu đề tin tức đã có sẵn. Rất may, thật dễ dàng để thiết lập một bộ lập lịch tác vụ trong Windows sẽ thực thi tệp của tôi hàng ngày ở chế độ nền và để tệp văn bản của tôi phát triển liên tục. Tất cả những gì tôi phải làm bây giờ là kiên nhẫn và đợi cho đến khi một lượng tiêu đề đáng kể được tích lũy. Sau khoảng 1 tuần rưỡi tôi đã có hơn 1000 tiêu đề. Tôi quyết định rằng điều đó là đủ cho một dự án rất phi khoa học và vô nghĩa như vậy. Sau khi tải tệp văn bản của tôi và thực hiện một số thao tác dọn dẹp thô sơ để loại bỏ một số chữ ký cửa hàng tin tức định kỳ và dấu chấm câu kép, v.v. , cuối cùng thì tôi cũng có thể bắt đầu đưa văn bản vào mô hình Markov của mình. Tôi quyết định sử dụng tiền tố hoặc 'dẫn đầu' của một từ. Tôi không muốn đi sâu vào chi tiết về chuỗi Markov, nhưng ngắn gọn thì tôi sẽ tóm tắt nó như thế này
Đối với mỗi từ, chúng tôi thu thập từng từ sau trong bất kỳ câu nào. Dựa trên tần suất xuất hiện của một từ theo sau so với 'đối thủ' của nó, chúng tôi sẽ chỉ định khả năng xuất hiện của một từ theo sau một từ dẫn đầu nhất định. Sau đó, chúng tôi có thể bắt đầu với một từ ngẫu nhiên từ toàn bộ danh sách các từ trong văn bản của mình và sau đó chọn ngẫu nhiên từ tiếp theo trong câu của chúng tôi với xác suất dựa trên khả năng chúng tôi đã chỉ định. Từng chữ chúng ta sẽ tạo một câu mới dựa trên các thuộc tính của văn bản mà chúng ta đã sử dụng làm đầu vào. Tin thật vào → tin thật giả ra

Sau khi chia tệp văn bản thành các từ riêng lẻ và lưu trữ chúng trong một biến ‘words’, tôi đã xác định khung dữ liệu gấu trúc có ba cột. một cột ‘lead’ xác định từ hàng đầu. Đối với mỗi từ dẫn đầu, có một từ 'theo sau' và được ghi lại trong cột thứ hai của chúng tôi ‘follow’. Cột thứ ba -‘freq’- sẽ hiển thị số lần chúng ta có thể quan sát thấy sự kết hợp nhất định giữa 'dẫn dắt' và 'theo dõi' trong văn bản của chúng ta. Chúng ta sẽ điền gì vào các cột này? . Đối với mỗi từ có chỉ số i trong văn bản của chúng tôi, từ tiếp theo sau đó là từ có chỉ số i + 1. Chúng tôi chỉ cần bắt đầu bằng cách điền lại cột 'theo dõi' bằng văn bản của mình, nhưng lần này bắt đầu bằng từ thứ hai trong văn bản. Đối với một văn bản gồm n hàng ban đầu, văn bản này sẽ lấp đầy n-1 từ “theo dõi”. Từ cuối cùng trong văn bản của chúng tôi không tự động có người theo dõi, vì vậy chúng tôi sẽ sử dụng một biến chuỗi tổng hợp để lấp đầy khoảng trống. Tôi gọi nó là 'EndWord' (xin đừng nhầm lẫn nó với một thứ nghe có vẻ tương tự mà tổng thống được cho là đã nói trong một đoạn băng học việc bí ẩn nào đó)

import pandas as pd
dict_df = pd.DataFrame(columns = [‘lead’, ‘follow’, ‘freq’])
dict_df['lead']=words
follow = words[1:]
follow.append('EndWord')

Trước khi tiếp tục, tôi sẽ tạo một mảng từ riêng chứa tất cả các từ cuối cùng của mỗi câu. Trong mã sau này, tôi sẽ sử dụng các từ kết thúc này để kết thúc câu được tạo ngẫu nhiên một cách “tự nhiên”. Điều này có một tác dụng phụ thú vị là tôi không phải lo lắng về chuỗi Markov của mình chạy 'ngang qua' các tiêu đề, nghĩa là từ cuối cùng của một tiêu đề không nên được coi là dẫn đầu cho từ đầu tiên của tiêu đề tiếp theo. Rốt cuộc, tôi không xử lý một văn bản liên tục, mà với các câu riêng lẻ và độc lập. Bằng cách cắt câu của tôi sau khi trình tạo câu của tôi đạt đến mức

end_words = []
for word in words:
if word[-1] in ['.','!','?'] and word != '.':
end_words.append(word)
print(end_words)
0 như vậy, điều này không đáng lo ngại

end_words = []
for word in words:
if word[-1] in ['.','!','?'] and word != '.':
end_words.append(word)
print(end_words)

Càng xa càng tốt. Bây giờ tôi đếm số lần xuất hiện của từng tổ hợp từ dẫn đầu và từ theo dõi và gán kết quả cho cột tần suất bằng cách sử dụng group_by và biến đổi

dict_df['freq']= dict_df.groupby(by=['lead','follow'])['lead','follow'].transform('count').copy()

Các hàng vẫn không phải là duy nhất, vì vậy tôi xóa các hàng trùng lặp trước khi sử dụng chức năng trục trong Python để tạo một ma trận lớn với mỗi từ dẫn đầu làm chỉ mục hàng và mọi từ theo sau làm cột. Tần suất của sự kết hợp giữa từ dẫn đầu ở hàng i và từ theo sau ở cột j khi đó là phần tử a_ij trong ma trận này

dict_df = dict_df.drop_duplicates()
pivot_df = dict_df.pivot(index = 'lead', columns= 'follow', values='freq')

Đối với mỗi hàng, sau đó tôi tổng hợp tất cả các tần số và chia từng phần tử trong hàng i cho tổng của hàng i. Điều này dẫn đến tỷ lệ phần trăm tổng bằng 1 mà trình tạo câu của tôi sẽ sử dụng làm phân phối xác suất khi chọn từ tiếp theo cho một từ dẫn đầu nhất định. e. g. nếu sau từ ‘fake’, chúng ta quan sát 7 lần từ tiếp theo ‘news’ và 3 lần từ ‘tan’, thì xác suất được chọn sẽ là 0. 7 và 0. 3 tương ứng

sum_words = pivot_df.sum(axis=1)
pivot_df = pivot_df.apply(lambda x: x/sum_words)

Với tất cả những điều này, tôi có thể xác định chức năng của mình cho trình tạo câu. Tôi lấy một từ bắt đầu để khởi tạo trình tạo câu. Từ này có thể là một từ được chọn ngẫu nhiên từ tập hợp tất cả các từ. Nhưng vì văn bản của tôi chỉ bao gồm các tiêu đề của Donald Trump, tôi nghĩ sẽ hợp lý nếu đảm bảo rằng tên của ông ấy cũng xuất hiện trong tiêu đề tin giả của chúng tôi. Trong các ví dụ của tôi, do đó tôi bắt đầu với 'Donald'. Bắt đầu với từ này, trình tạo sẽ chọn một từ tiếp theo dựa trên ma trận xác suất mà chúng tôi đã thiết lập. Nó sẽ tiếp tục bằng cách sử dụng từ theo sau đã chọn làm từ dẫn đầu mới để nối từng từ vào câu của chúng ta. Nếu trình tạo câu đến một từ nằm trong mảng các từ cuối của chúng ta, thì câu sẽ lấy từ này làm từ cuối cùng và trả về câu của chúng ta. Nếu trình tạo đến được 'EndWord' tổng hợp của chúng tôi mà chúng tôi đã xác định trước đó, thì nó sẽ chỉ vẽ một từ theo dõi mới cho từ dẫn đầu đã đưa chúng tôi đến con đường cụt này. Điều tương tự cũng áp dụng nếu chúng ta đi đến một từ kết thúc và câu của chúng ta chỉ dài 2 từ (Tôi đã có một vài câu ví dụ chỉ đọc “Donald Trump. ”. Như trong “Donald Trump. ” - nuff nói)

from numpy.random import choice
def make_a_sentence(start):
word= start
sentence=[word]
while len(sentence) < 30:
next_word = choice(a = list(pivot_df.columns), p = (pivot_df.iloc[pivot_df.index ==word].fillna(0).values)[0])
if next_word == 'EndWord':
continue
elif next_word in end_words:
if len(sentence) > 2:
sentence.append(next_word)
break
else :
continue
else :
sentence.append(next_word)
word=next_word
sentence = ' '.join(sentence)
return sentence
sentence = make_a_sentence('Donald')

Và đó là nó

Tôi chắc chắn sẽ không giành chiến thắng trong một cuộc thi sắc đẹp (do Trump tổ chức) với mã này, nhưng nó nhanh, bẩn, thân thiện với Python-noob và thực hiện công việc. Đúng là văn bản càng lớn thì toàn bộ quá trình gán xác suất sẽ càng chậm, nhưng đối với mẫu của tôi, nó vẫn chỉ mất vài giây nên tôi chưa thấy cần phải tối ưu hóa tốn thời gian. Thay vào đó, chúng ta hãy xem một số tiêu đề 'tin thật giả'

Lời chỉ trích của Donald Trump về Trump bị ám ảnh bởi Chiến tranh giữa các vì sao.
- (Nghe có vẻ hợp lý)

Donald Trump đã phá vỡ bài kiểm tra lòng trung thành thực sự của Donald Trump
- (Sẽ tuyệt biết bao nếu điều đó xảy ra?)

Nhóm của Donald Trump nộp đơn khiếu nại chống lại người da trắng
- (Ừ…. chắc là không)

Những người giỏi nhất của Donald Trump khoe khoang
- (Tệ nhất của anh ấy nữa)

Các trợ lý của Donald Trump cảm thấy nhiệm kỳ tổng thống của ông vào mùa thu này
- (Tất cả chúng tôi làm.. tất cả chúng tôi làm)

Donald Trump, Omarosa, và các cá nhân khác, kể cả tổng thống thứ 45 là Junior Mint
-(Tươi?)

Donald Trump, bạn đã tiến rất xa
- (Có lẽ hơi quá so với sở thích của tôi)

Tất nhiên đây là một số ví dụ thành công. Rất nhiều câu xuất hiện hoàn toàn vô nghĩa (không xứng đáng với covfefe, nhưng vẫn vô nghĩa)

Donald Trump Biết Ai Là Tha Franklin Làm việc cho cựu phụ tá của Utah Omarosa Manigault Newman
-(???)

Vậy chúng ta đã học được gì qua điều này? . Nhưng tôi đã có một vài trận cười sảng khoái với mã của mình và phải làm việc với dữ liệu theo cấu trúc mà tôi thường không gặp phải. Nếu bạn có phản hồi hoặc đề xuất, vui lòng liên hệ. Thanks

P. S

Nếu bạn muốn có một phiên bản phức tạp hơn của chuỗi Trump Markov, hãy xem trình tạo Trump Tweet ngẫu nhiên này của một người thông minh hơn