1. 程式人生 > 其它 >20192103 2020-2021-2 《Python程式設計》實驗四報告

20192103 2020-2021-2 《Python程式設計》實驗四報告

20192103 2020-2021-2 《Python程式設計》實驗四報告

課程:《Python程式設計》
班級: 1921
姓名: 劉廷奇
學號:20192103
實驗教師:王志強
實驗日期:2021年6月24日
必修/選修: 公選課

一、實驗內容

  • Python綜合應用:爬蟲、資料處理、視覺化、機器學習、神經網路、遊戲、網路安全等。

(1)程式能執行,功能豐富。(需求提交原始碼,並建議錄製程式執行的視訊)10分
(2)綜合實踐報告,要體現實驗分析、設計、實現過程、結果等資訊,格式規範,邏輯清晰,結構合理。10分。
(3)在實踐報告中,需要對全課進行總結,並寫課程感想體會、意見和建議等。5分

二、實驗過程

1. 概念理解:

(1)詞袋模型

  詞袋模型(Bag-of-words model),像是句子或是檔案這樣的文字可以用一個袋子裝著這些詞的方式表現,這種表現方式不考慮文法以及詞的順序。
  文件的向量表示可以直接將各詞的詞向量表示加和。例如:
  John likes to watch movies. Mary likes too
  John also likes to watch football games.
  以上兩句可以構造一個詞典,**{“John”: 1, “likes”: 2, “to”: 3, “watch”: 4, “movies”: 5, “also”: 6, “football”: 7, “games”: 8, “Mary”: 9, “too”: 10} **
那麼第一句的向量表示為:[1,2,1,1,1,0,0,0,1,1],其中的2表示likes在該句中出現了2次,依次類推。
  詞袋模型同樣有一下缺點:

  • 詞向量化後,詞與詞之間是有大小關係的,不一定詞出現的越多,權重越大。
  • 詞與詞之間是沒有順序關係的。

(2)連續詞彙(CBOW)學習

  在連續的單詞模型中,上下文由給定目標單詞的多個單詞表示。例如,我們可以使用“cat”和“tree”作為“攀爬”的上下文單詞作為目標單詞。這需要修改神經網路架構。如下所示,修改包括將隱藏層連線的輸入複製C次,上下文單詞的數量,以及在隱藏層神經元中新增除C操作。[警報讀者指出,下圖可能會讓一些讀者認為CBOW學習使用了幾個輸入矩陣。不是這樣。它是相同的矩陣WI,它接收代表不同上下文詞的多個輸入向量]

  利用上述配置來指定C上下文字,使用1-out-of-V表示編碼的每個字意味著隱藏層輸出是與輸入處的上下文字相對應的字向量的平均值。輸出層保持不變,並且以上面討論的方式完成訓練。


(3)Skip-Gram模型

  Skip-gram模型反轉了目標和上下文單詞的使用。在這種情況下,目標字在輸入處被饋送,隱藏層保持相同,並且神經網路的輸出層被多次複製以適應所選數量的上下文字。以“cat”和“tree”為例,作為上下文單詞,“爬”作為目標詞,skim-gram模型中的輸入向量為[0 0 0 1 0 0 0 0] t,而兩個輸出層將具有[0 1 0 0 0 0 0 0] t和[0 0 0 0 0 0 0 1] t分別作為目標向量。代替產生一個概率向量,將為當前示例產生兩個這樣的向量。以上面討論的方式產生每個輸出層的誤差向量。然而,將來自所有輸出層的誤差向量相加以通過反向傳播來調整權重。這確保了每個輸出層的權重矩陣WO在整個訓練中保持相同。

2. 使用CBOW模型,分析莎士比亞文選中的詞彙:

(1)準備材料並作預料清洗:

由於材料中存在非英文單詞的其他字元,所以需要先對其進行清洗得到需要的單詞文字。

# -*- coding:utf-8 -*-
"""
作者:亦 皓
時間:20210621
"""
import re

my_file_path = 'shakespeare.txt'
save_file_path = 'shakespeare_cleaned.txt'
# 開啟檔案
my_file = open(my_file_path, 'r', encoding='utf-8')
# 只保留中英文、數字和.的正則表示式
cop = re.compile("[^\u4e00-\u9fa5^.^a-z^A-Z^0-9]")
line_num=1
for line in my_file.readlines():
print('---- processing ', line_num, ' article----------------')
line_num=line_num+1
string = cop.sub(" ", line)
save_file = open(save_file_path, 'a', encoding='utf-8')
save_file.write(string)
save_file.flush()
save_file.close()

# 關閉檔案
my_file.close()

(2)gensim訓練詞向量模型:

  gensim訓練詞向量分為三步,第一步獲取sentences,第二部設定超引數,第三步模型儲存。
  <1> 獲取sentences:直接讀取shakespeare_cleaned.txt檔案,sentences是已經分詞過的字串列表,其為一維陣列。
 <2> 設定超引數:word2vec模型的超引數如下所示:

model = word2vec.Word2Vec(sentences, hs=1, min_count=1, window=5, size=200)
  • sentences: 我們要分析的語料,可以是一個列表,或者從檔案中遍歷讀出。後面我們會有從檔案讀出的例子。
  • size: 詞向量的維度,預設值是100。這個維度的取值一般與我們的語料的大小相關,如果是不大的語料,比如小於100M的文字語料,則使用預設值一般就可以了。如果是超大的語料,建議增大維度。
  • window:即詞向量上下文最大距離,這個引數在我們的演算法原理篇中標記為c,window越大,則和某一詞較遠的詞也會產生上下文關係。預設值為5。在實際使用中,可以根據實際的需求來動態調整這個window的大小。如果是小語料則這個值可以設的更小。對於一般的語料這個值推薦在[5,10]之間。
  • sg: 即我們的word2vec兩個模型的選擇了。如果是0, 則是CBOW模型,是1則是Skip-Gram模型,預設是0即CBOW模型。
  • hs: 即我們的word2vec兩個解法的選擇了,如果是0, 則是Negative Sampling,是1的話並且負取樣個數negative大於0, 則是Hierarchical Softmax。預設是0即Negative Sampling。
  • min_count:需要計算詞向量的最小詞頻。這個值可以去掉一些很生僻的低頻詞,預設是5。如果是小語料,可以調低這個值。

<3> 模型儲存

# -*- coding:utf-8 -*-
"""
作者:亦 皓
時間:2021年06月16日
"""
# import modules & set up logging shakespeare
import logging
import os
from gensim.models import word2vec

logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

sentences = word2vec.LineSentence('./shakespeare_cleaned.txt')

model = word2vec.Word2Vec(sentences, hs=1, min_count=1, window=5, size=200)
model.save("shakespeare.model")

(3)呼叫詞向量模型進行測試:

1、相似性

持數種單詞相似度任務:
相似詞+相似係數(model.most_similar)、model.doesnt_match、model.similarity(兩兩相似)

2、詞向量

通過以下方式來得到單詞的向量:

 1 # -*- coding:utf-8 -*-
 2 """
 3 作者:亦 皓
 4 時間:2021年02月16日
 5 """
 6 from gensim.models import Word2Vec
 7 
 8 model = Word2Vec.load("shakespeare.model")  # 匯入訓練好的model
 9 print("測試1# 單詞 honest,love 的相似詞中相似率最高的為:", model.wv.most_similar(positive=['honest', 'love'], topn=1))
10 
11 print("測試2# First Better greatest lunch 中差別最大的詞為:", model.wv.doesnt_match("First Better greatest lunch".split()))
12 
13 print("測試3# honours, Whether的相似度為:", model.wv.similarity('honours', 'Whether'))
14 
15 print("測試4# 輸出fight的近似詞:")
16 for key in model.wv.similar_by_word("fight", topn=5):
17     print(key[0], key[1])
18 print("測試5# 輸出的向量:", model.wv.__getitem__('Better'))

結果顯示:

測試1# 單詞 honest,love 的相似詞中相似率最高的為: [('lies', 0.9200366139411926)]
測試2# First Better greatest lunch 中差別最大的詞為: greatest
測試3# honours, Whether的相似度為: 0.43724662
測試4# 輸出fight的近似詞:
last 0.9451447129249573
put 0.9314762353897095
watchful 0.9188637733459473
heaven 0.9185464382171631
command 0.9172909259796143
測試5# 輸出的向量: [-0.06699569  0.01617903  0.01823069  0.04562613  0.02445887  0.00284738
 -0.03371223 -0.09672338  0.01900439  0.01873839  0.00463057  0.02441882
  0.03263871 -0.00094737  0.0446073  -0.03870494 -0.04102157 -0.01287576
  0.04451469  0.05489408 -0.00789456 -0.0279666  -0.00838227  0.00983625
 -0.01237774 -0.01247551 -0.0290442  -0.01552401  0.03309647  0.07312648
  0.03531109  0.00187926  0.05684604 -0.01280195  0.01841912  0.03781545
 -0.01112699  0.03274786 -0.02836249 -0.03545839 -0.02025985 -0.03461348
 -0.04703348  0.08335583  0.02305591 -0.02907482 -0.06440009  0.05557092
  0.02365478  0.02517412 -0.06268574  0.02495834 -0.02806567 -0.04015472
 -0.0161448  -0.07507759  0.02799249  0.00547924 -0.05197961  0.03000016
  0.084795   -0.02090319  0.00349557 -0.03505312 -0.02232206 -0.03817129
  0.05356568 -0.03535968  0.0284666  -0.01798884  0.00929409 -0.03288862
  0.03720145 -0.02298678  0.03213813  0.05708868 -0.0102173   0.03067191
 -0.00203374  0.02259132  0.02428583  0.06176442 -0.01030927 -0.04594169
  0.00308089 -0.01238897  0.02096123 -0.00909929 -0.04792728  0.1344735
 -0.04238546  0.04237226 -0.06910371 -0.04969184 -0.08321558 -0.01235363
 -0.05850493  0.08172184 -0.12042347  0.03568861 -0.01371954 -0.08182655
 -0.01754959  0.04139086  0.02987615 -0.00909976 -0.0423135   0.1070986
 -0.01270053 -0.05330019  0.03727992  0.0483785  -0.04232701  0.01060789
  0.00495224 -0.008589   -0.06342883  0.00820889 -0.0170385  -0.03921989
 -0.02200507 -0.00548373 -0.02671601  0.00962604 -0.03535017  0.06872729
 -0.05534382 -0.10688455 -0.01219376 -0.0857593   0.01900148 -0.01204819
 -0.04688123 -0.00704413 -0.00978228  0.0111156   0.00578401 -0.05683793
 -0.01376251 -0.01436697  0.0608184  -0.04045716 -0.03128746 -0.0541997
  0.00266912 -0.00560187  0.04679392 -0.0068001   0.02903086 -0.01399632
  0.02934035  0.00378431 -0.00330732 -0.04056502 -0.01079299  0.03196225
  0.02427186  0.03629823  0.03135628  0.00360445  0.02142306 -0.020002
 -0.03829349  0.04249463 -0.05141458 -0.01234756  0.04370045  0.03112992
 -0.02176946  0.03934734 -0.00982814  0.03035656 -0.01511338 -0.00585528
 -0.03257927  0.01247251 -0.02951111 -0.01081949  0.01928993  0.02217238
 -0.03827615 -0.04731882 -0.0077866   0.0230904   0.01569317 -0.01079687
 -0.00130575  0.0304474   0.03601635  0.01544886 -0.02586186  0.01181022
 -0.01027526  0.00524375 -0.11492699 -0.02224771  0.03087084  0.07214064
 -0.01901922  0.04930056]

三、實驗中遇到的問題

問題一:學習詞向量時涉及到神經網路模型的很多概念不清楚,比如隱層,反向傳播等。

解決方法:對於影響整體理解的內容要花時間去看視訊講解,在公式推導過程中要保持耐心,雖然最終不能理解其中迭代的、反向傳播的公式計算部分,但做到能夠理解引數的含義。

問題二:參考資料和現在使用的庫版本不同。

解決方法:最初下載安裝好gensim、RNN等庫後,寫一些樣例程式碼就全片飛紅,需要去閱讀錯誤提示,之後去網站上查詢最新的庫函式來代替舊的函式。

四、本實驗程式碼連結及參考資料

  https://gitee.com/liu-tingqi/PythonWork/tree/master/lab4

  https://blog.csdn.net/qq_36426650/article/details/87738919

五、課程體會

  python課讓我找到了CS專業學生的感覺——寫程式碼、學技能、知方向,而不是天天寫ppt和word,到了課後實驗需要自己花大量時間去從零初學。python的課程從簡開始,我可以跟得上老師的進度還是要感謝老師給的寶藏資料,課堂上直接以程式碼來講解切實解決了我們實踐上將會遇到的問題,讓我們在課下時間有信心去自己重寫程式碼,回憶老師的思路,回顧上課的內容。學習的過程在於自己動手的過程,本學期老師佈置了適當量的實踐作業,從學習python的基本操作,到網路程式設計,再到網路爬蟲,也給了我們充分的時間來獨立完成。在這門課上我的收穫很多,欣喜~