七夕,送上這份最美情話+AI作詩的大禮

七夕到了下面,程序猿同志們都在想怎么送女朋友禮物复颈,送包包?太俗氣沥割!送口紅耗啦?沒有新意!

沒有點(diǎn)子的同志們不妨看看這篇机杜,滿滿的干貨:LDA 主題模型提取知乎情話中最美的意象 + AI 根據(jù)提取出的意象自動(dòng)寫情詩芹彬!送給女朋友一首這樣的情詩,比口紅包包什么的的有格調(diào)叉庐!

0.jpg

動(dòng)手實(shí)現(xiàn)

不想看代碼的同志可以跳過這部分去文末看實(shí)現(xiàn)效果和代碼下載鏈接。

爬取知乎高贊回答

以話題【你聽過哪些讓人怦然心動(dòng)的情話或者詩句会喝?】為例陡叠,爬取該話題下質(zhì)量最高的前 100 個(gè)回答玩郊。

1.png

首先分析接口,不難定位到回答在圖示所在的接口返回的內(nèi)容中枉阵。

2.png

切換到 headers 欄可查看該請(qǐng)求的 URL 地址為

https://www.zhihu.com/api/v4/questions/285989317/answers?include=data%5B%2A%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_labeled%2Cis_recognized%2Cpaid_info%2Cpaid_info_content%3Bdata%5B%2A%5D.mark_infos%5B%2A%5D.url%3Bdata%5B%2A%5D.author.follower_count%2Cbadge%5B%2A%5D.topics&limit=5&offset=10&platform=desktop&sort_by=default

需要注意 offset 這個(gè)參數(shù)即可译红,用于請(qǐng)求翻頁,一頁答案的個(gè)數(shù)由參數(shù) limit 決定兴溜。

編碼發(fā)現(xiàn)侦厚,對(duì)于請(qǐng)求頭信息,需要在代碼中給出 user-agent 和 cookies拙徽,cookies 需要自己手動(dòng)去知乎登錄后獲取刨沦。這部分代碼如下:

headers = {
    'cookies': '''改成你自己的 cookies''',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0',
}

url = 'https://www.zhihu.com/api/v4/questions/285989317/answers?include=data%5B*%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_labeled%2Cis_recognized%2Cpaid_info%2Cpaid_info_content%3Bdata%5B*%5D.mark_infos%5B*%5D.url%3Bdata%5B*%5D.author.follower_count%2Cbadge%5B*%5D.topics&offset={}&limit=5&sort_by=default&platform=desktop'

def worker(pageNum):
    try:
        res = requests.get(url=url.format(pageNum),headers=headers)
        data = res.json()['data']
        for item in data:
            author = item['author']['name']
            # 一條答案包括 content 和 excerpt 兩部分
            content = item['content']
            excerpt = item['excerpt']
            answer = content + excerpt
            # 去掉富文本標(biāo)簽
            answer = re.sub("<.*?>","",answer)
            return [author,answer]

    except Exception as e:
        print(e)

在返回的 json 內(nèi)容里答案分布在字段 content 和 excerpt 中,需要拼接膘怕,又由于內(nèi)容里有許多富文本標(biāo)簽想诅,不利于后續(xù)處理,在此利用正則表達(dá)式作了富文本過濾岛心。

為了加速爬蟲来破,使用了 concurrent.futures 中的 ThreadPoolExecutor,即線程池對(duì)象忘古。

executor = ThreadPoolExecutor(max_workers=4)
# 只獲取質(zhì)量高的前 100 個(gè)回答
all_tasks = [executor.submit(worker, (i)) for i in range(100)]

同時(shí)需要獲取線程執(zhí)行結(jié)束后的結(jié)果徘禁,引入 concurrent.futures 中的 as_completed 方法,其用法如下:

answers = []
for future in as_completed(all_tasks):
    data = future.result()
    answers.append(data)

as_completed()方法是一個(gè)生成器髓堪,在沒有任務(wù)完成的時(shí)候會(huì)阻塞送朱,一旦有某個(gè)任務(wù)完成,會(huì) yield 這個(gè)任務(wù)旦袋,從而執(zhí)行 for 循環(huán)下面的語句骤菠,然后繼續(xù)阻塞住,循環(huán)到所有的任務(wù)結(jié)束疤孕。

最后使用 pandas 模塊把答案保存到 csv 文件中商乎。

col = ['author','answer']
df = pd.DataFrame(data=answers,columns=col)

df.to_csv("answers.csv",encoding="utf-8")
3.png

這樣就完成了三步走中的第一步!

LDA 模型抽取回答主題得到常見意象

當(dāng)今社會(huì)是一個(gè)高度信息化的社會(huì)祭阀,如何從浩如煙海的文本中提取出主題鹉戚,是一個(gè)具有挑戰(zhàn)性的話題。主題提取有很多方法专控,其中最常見的就是隱含狄利克雷分布(Latent Dirichlet allocation)抹凳,簡(jiǎn)稱LDA。

LDA 是一種文檔主題生成模型伦腐,也稱為一個(gè)三層貝葉斯概率模型赢底,包含詞、主題和文檔三層結(jié)構(gòu)。所謂生成模型幸冻,就是說粹庞,我們認(rèn)為一篇文章的每個(gè)詞都是通過“以一定概率選擇了某個(gè)主題,并從這個(gè)主題中以一定概率選擇某個(gè)詞語”這樣一個(gè)過程得到洽损。文檔到主題服從多項(xiàng)式分布庞溜,主題到詞服從多項(xiàng)式分布。

關(guān)于 LDA 的原理碑定,我這里簡(jiǎn)單闡釋下流码,有兩個(gè)概率分布模型,一個(gè)是文檔關(guān)于主題的延刘,另一個(gè)是主題關(guān)于單詞的漫试,在初始條件下,這兩個(gè)概率分布模型都不是準(zhǔn)確的访娶,甚至是隨機(jī)給出的商虐,根據(jù)貝葉斯公式,由這兩個(gè)概率分布可以計(jì)算出文檔關(guān)于單詞的概率分布崖疤,而這個(gè)概率分布秘车,也可以直接根據(jù)文檔統(tǒng)計(jì)得出,如果不相符劫哼,則調(diào)整初始的兩個(gè)概率分布叮趴,直至根據(jù)貝葉斯公式間接計(jì)算出的文檔-單詞概率分布模型同基于文檔統(tǒng)計(jì)直接計(jì)算出來的概率分布模型相吻合。至于具體怎么調(diào)整概率分布权烧,有興趣的同學(xué)可以查閱相關(guān)資料眯亦。

在 Python 中,有直接實(shí)現(xiàn)了 LDA 的庫 pyLDAvis般码,我們只需要指定單詞個(gè)數(shù)上限和主題個(gè)數(shù)等參數(shù)即可妻率,同時(shí) pyLDAvis 也提供了非常好的動(dòng)態(tài)交互可視化界面的 API。

上一步我們將高贊回答保存到了 csv,這一步首先加載這個(gè)文件板祝,然后進(jìn)行分詞處理(也可自行設(shè)置停用詞)宫静,分詞向量化、調(diào)整 LDA 模型的參數(shù)券时,最后將數(shù)據(jù)填進(jìn)模型孤里,抽取出主題,并可視化出來橘洞。

這部分代碼如下:

df = pd.read_csv("answers.csv")

def chinese_word_cut(text):
    return " ".join(jieba.cut(text))

df["answer"] = df.answer.apply(chinese_word_cut)


from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer

# 向量化
n_features = 1000

tf_vectorizer = CountVectorizer(strip_accents = 'unicode',
                                max_features=n_features,
                                stop_words='english',
                                max_df = 0.5,
                                min_df = 10)
tf = tf_vectorizer.fit_transform(df.answer)

from sklearn.decomposition import LatentDirichletAllocation

n_topics = 5
# LDA 處理
lda = LatentDirichletAllocation(n_topics=n_topics, max_iter=50,
                                learning_method='online',
                                learning_offset=50.,
                                random_state=0)
lda.fit(tf)

抽取出的 5 個(gè)主題中的前 20 高頻詞匯如下:

Topic 0:
39 我見 看過 森林 一切 之中 無數(shù) 看見 真的 還有 感受 他們 大海 如同 找到 呼吸 情書 月亮 一次 這樣
Topic 1:
圖片 三分 情話 只是 宇宙 大家 真的 生活 無數(shù) 我會(huì) 心里 時(shí)間 開始 以下 最后 生命 永恒 這樣 想起 然后
Topic 2:
鄧穎超 周恩來 妻子 官方 情話 心里 怎么 時(shí)間 懷里 一把 太陽 情書 堅(jiān)定不移 身體 有來生 所有 看著 這個(gè) 那么 世界
Topic 3:
看到 不敢 從此 原因 世界 希望 這個(gè) 情話 溫柔 不要 只有 所有 別人 怎么 一直 但是 真的 永遠(yuǎn) 一定 只是
Topic 4:
34 世界 所有 這個(gè) 希望 只有 溫柔 一定 這樣 不要 還是 永遠(yuǎn) 那么 情話 所以 可愛 遇見 不會(huì) 一樣 心里

最后可視化:

import pyLDAvis.sklearn
data = pyLDAvis.sklearn.prepare(lda, tf, tf_vectorizer)
pyLDAvis.show(data)#可視化主題模型
4.png

可交互的動(dòng)態(tài)圖表還是非常具有視覺沖擊力的:

5.gif

根據(jù)抽取出的主題 AI 作詩

AI 作詩是一門非常具有挑戰(zhàn)性的自然語言處理課題捌袜,在嘗試了很多模型未果后,我發(fā)現(xiàn)了九歌——人工智能詩歌寫作系統(tǒng)炸枣,來自清華大學(xué)自然語言處理與社會(huì)人文計(jì)算實(shí)驗(yàn)室的研究成果虏等,于是就索性采用九歌的接口弄唧,這個(gè)接口沒有高級(jí)的反爬措施,但是請(qǐng)求結(jié)果卻很奇怪博其,需要多次請(qǐng)求才能返回正確結(jié)果套才;根據(jù)上一步的提取出來的主題作詩,同時(shí)做了個(gè)簡(jiǎn)單的封裝慕淡,其效果如下:

比如輸入【情話】【大海】沸毁,會(huì)生成如下的詩歌:

天
大海東流日夜圓
情何限
把酒話離筵

輸入 【愛】 【月亮】峰髓,生成詩歌:

漁
月白蘆花愛水魚
風(fēng)吹帽
露濕小荷鋤

非常含蓄的詩詞,深究發(fā)現(xiàn)采用了多種修辭和藝術(shù)手法息尺,讀起來也別有一番韻味携兵。

6.gif

相信這樣的七夕禮物,一定別有一番情趣搂誉。

代碼在微信公眾號(hào)后臺(tái)回復(fù):七夕徐紧。即可獲得。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末炭懊,一起剝皮案震驚了整個(gè)濱河市并级,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌侮腹,老刑警劉巖嘲碧,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異父阻,居然都是意外死亡愈涩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門加矛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來履婉,“玉大人,你說我怎么就攤上這事斟览』偻龋” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵趣惠,是天一觀的道長(zhǎng)狸棍。 經(jīng)常有香客問我,道長(zhǎng)味悄,這世上最難降的妖魔是什么草戈? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮侍瑟,結(jié)果婚禮上唐片,老公的妹妹穿的比我還像新娘丙猬。我一直安慰自己,他們只是感情好费韭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布茧球。 她就那樣靜靜地躺著,像睡著了一般星持。 火紅的嫁衣襯著肌膚如雪抢埋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天督暂,我揣著相機(jī)與錄音揪垄,去河邊找鬼。 笑死逻翁,一個(gè)胖子當(dāng)著我的面吹牛饥努,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播八回,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼酷愧,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了缠诅?” 一聲冷哼從身側(cè)響起溶浴,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滴铅,沒想到半個(gè)月后戳葵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汉匙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年拱烁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片噩翠。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡戏自,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伤锚,到底是詐尸還是另有隱情擅笔,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布屯援,位于F島的核電站猛们,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏狞洋。R本人自食惡果不足惜弯淘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吉懊。 院中可真熱鬧庐橙,春花似錦假勿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至浆竭,卻和暖如春浸须,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背兆蕉。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工羽戒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人虎韵。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像缸废,于是被迫代替她去往敵國(guó)和親包蓝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353