Python+機器學習的學習日記(2020.4.17-2020.4.21)

2020.4.17

學習了《Python編程 從入門到實踐》 第二章

對字符串的首字母大寫、全部大寫、全部小寫的操作

message.upper()
message.lower()
message.title()

去除字符串首端的空白、末端的空白、同時去除首尾的空白

message.lstrip()
message.lstrip()
message.strip()

粗略閱讀Python之禪

學習了 李宏毅2020機器學習 Regression、誤差來源、Gradient Decent部分

(小部分內容摘抄自:
the github page is: https://Sakura-gh.github.io/ML-notes)

Regression部分從預測口袋妖怪的戰鬥力開始引入,講解了線性迴歸的基本原理,梯度下降的基本原理。隨後講解了利用高次方程來擬合一個更爲複雜的曲線模型,越高次的方程越能更好的匹配訓練集,但是也正是因爲太過依賴於訓練集,導致泛化性能不好,在測試集的表現中就非常不好,這就是過擬合。而欠擬合則是方程過於簡單,對無論是測試集還是訓練集來說都不能很好的進行匹配,這就是欠擬合。

在模型中加入了正則化的因子來限制模型中權重值的大小,是權重值儘可能的小,這樣逼迫擬合出來的曲線趨近於平滑,從而有更強的泛化性能和抗噪聲特性。當然正則化因子的選擇也是有一個度的,當這個值過於小,對於曲線模型就不能起到平滑的作用,所以訓練集中的噪聲對模型的影響就很大,也就是模型過擬合,泛化能力差。那麼相對的,當正則化因子過大,曲線過於平滑,則會導致欠擬合。

誤差主要是來源於Bias和Variance,中文不知道怎麼翻譯算合適。圖片表達的很直觀:
在這裏插入圖片描述
這裏涉及到一些統計學的內容,學習之後需要再次觀看。

經過多次取樣之後,對每一組樣本進行線性迴歸,然後分以下2種情況:
1.如果使用簡單的方程對這機組樣本分別進行線性迴歸,可以發現這些曲線都是比較平滑的,並且聚的比較緊,這樣的一組曲線他的Variance是比較小的。同時這些曲線的平均值所形成的曲線也是比較平滑的,但這樣的平均值曲線是欠擬合的,所以它與真實的曲線(就是能產生樣本的那個曲線)之間是有Bias的,而且曲線越平滑Bias就越大,這種情況局對應的左下角的圖像。

2.如果使用複雜的方程對這機組樣本分別進行線性迴歸,可以發現這些曲線都是比較彎彎曲曲,並且分散的很開,這樣的一組曲線他的Variance是比較大的。同時這些曲線的平均值所形成的曲線也是比較彎曲的,但這樣的平均值曲線是跟貼近真實曲線(就是能產生樣本的那個曲線)的,所以它的Bias就會小,,這種情況局對應的右上角的圖像。

所以選擇模型應該綜合考慮Bias和Variance這兩個誤差,取到一個比較中和的值。當Variance大的時候,說明你的模型過擬合了,可以增加更多的樣本,或者引入正則化。當Bias大的時候,說明你的模型欠擬合了,可以增加更多的特徵,或者使用更高次數的方程來代替你的模型。

隨後還介紹了n折交叉驗證的操作方法。

Gradient Decent部分介紹了learning rate的自適應改變方法,因爲learning rate過小可能導致模型計算過於緩慢,learning rate過大則會導致梯度下降步子太大,直接越過最低點,無法得到loss function的最小值,所以要選擇自適應的learning rate。

Adagrad是learning rate的自適應方法,在gradient descent中,我們希望微分值越大(斜率越大)更新的步伐要更大一些,因爲這個時候表示離loss function的最低點還遠。但是Adagrad的表達式中,分母表示梯度越大步伐越大,分子卻表示梯度越大步伐越小,兩者似乎相互矛盾。這其實是因爲gradient越大,離最低點越遠這件事情在有多個參數的情況下是不一定成立的。
在這裏插入圖片描述
可以看到a點離最小值點更遠,但是微分卻小。b點離最低點近,而微分更大。這種情況下就直接考慮最優步長的問題了。

在這裏插入圖片描述
面對loss function是一個橢圓時,通常要考慮Adagrad,因爲正如圖像中w1和w2的方向,在同一點處,兩個方向的微分和它們距離最低點的距離並不是成正比的。

接下來是Stochastic Gradicent Descent(隨機梯度下降),傳統的梯度下降算法在進行loss 評估時,要將目前這個模型與所有樣本點比對,大大增加了時間。而Stochastic Gradicent Descent只是隨機選取一個樣本點進行loss分析。如果有20個樣本點,傳統Gradicent Descent下降一步,Stochastic Gradicent Descent已經下降了20步,這種方法的最大優點就是快。

Feature Scaling(特徵縮放)的思想是:樣本的有些特徵,轉換爲數字後很大,如房屋的面積。而有些特徵轉換爲數字後又會很小,比如衛生間的個數。這樣我們在對一個房屋價格進行預測(對收集到的房屋樣本的特徵對價格進行線性迴歸)時,這兩種特徵如果不加處理就放入模型,對模型而言是不好的。以爲面積這個特徵相對於衛生間的個數來說,二者的數值相差太大,導致loss function的俯視圖從一個正圓,變到一個橢圓,而且這兩個特徵的數值差距越大,這個橢圓就更加橢。這樣的結果前面已經說過,就要使用Adagrad。而且如果loss function是一個正圓的話,對模型的效率也是有提升的。

最後是利用Taylor Series(泰勒級數)來進行梯度下降。對於一個loss function(這裏默認無窮階可導)我們可以用Taylor Series來近似它,並且近似的級數越高,近似收斂域也越大(也就是近似函數與原函數相等的區域越大),所以我們可以使用Taylor Series在收斂域內求得loss function的最小值,然後一步一步逼近全局最小值。

2020.4.18

學習了《Python編程 從入門到實踐》 第三章

學習了構建Python中的列表,訪問其中的元素

#創建列表
names=['shanghai','chengdu','hangzhou']
#訪問其中第二個元素
names[1]

向列表中修改、添加、刪除元素

#修改其中第二個元素爲'xian'
names[1]='xian'
#向列表最後增加元素'shenzhen'
names.append('shenzhen')
#向任意位置(選三號位)增加元素'qingdao'
names.insert(2,'qingdao')
#按位置刪除
del names[1]
#刪除之後還需使用
v=names.pop(1)
#根據值刪除
names.remove('shanghai')

組織列表,列表排序是按首字母和首數字大小進行的

#永久性排序
names.sort()
#永久性倒序排序
names.sort(reverse=True)
#臨時排序
names.sorted()
#l臨時性倒序排序
names.sorted(reverse=True)
#永久在現有順序上進行倒序
names.reverse()

獲取列表長度

len(names)
學習了 李宏毅2020機器學習Classification: Probabilistic Generative Model部分

(小部分內容摘抄自:
the github page is: https://Sakura-gh.github.io/ML-notes)

這部分的學習真的讓人回味無窮,醍醐灌頂。

課程根據口袋妖怪的各種屬性(生命值,防禦力,速度,特攻,特防…),來將口袋妖怪歸類到不同的系(草,水,火,飛行,格鬥,鋼鐵…)。個人覺得這個分類不可能太成功,因爲每個系都有不同類型的口袋妖怪,就像每個系裏都有擅長防禦的妖怪,也有擅長攻擊的妖怪,所以各種屬性在各個系中的分佈應該是差不多的,但是李宏毅老師最後還是做出了70%多的正確率,看來數據中隱藏的東西確實是有很多。

爲了方便,就取通用系和水系兩種妖怪來做實驗。然後在各種屬性裏面取兩個屬性作爲一個樣本的基本屬性。接下來畫出兩個系的樣本分佈圖,應該是兩個不同的散點圖。那麼之後再來一個新樣本,我們也可以把它畫到相應的散點圖中去。

這兩個散點圖畫出來以後,一定是有密有疏的,密集的地方代表這個地方出現的樣本點,大概率屬於這個系。那麼對於新來的樣本點來說,我們就可以根據它所處的位置的樣本點疏密程度,來判斷新樣本點屬於該系的概率大小,有點概率密度的意思。
在這裏插入圖片描述
兩幅散點圖,我們都可以認爲都是從一個高斯分佈中抽樣而來(也可以是別的分佈,這個可以根據個人喜好和實際情況而定)。那麼這樣一來,我們就可以根據現有的訓練樣本來確定出最符合抽樣結果的那個高斯分佈(就是找出一個高斯分佈,在這個模型上抽樣,抽到現有的這麼多訓練樣本的概率是最大的),其實就是最大似然估計。最後得到水系和通用系的兩個高斯分佈模型。

有了這兩個模型之後我們就藉助貝葉斯概率:
在這裏插入圖片描述
c1代表水系,c2代表通用系,等式是左邊的p表示,x是來自水系的概率。現在p(x|c1)和p(x|c2)都已經知道(根據前面的高斯模型得出)。因爲訓練樣本中有79只水系,61只通用系,所以p(c1)是79/(79+61),p(c2)以此類推。那麼至此p(c1|x)的概率也知道了。把概率值的圖畫出來就是左上角那個,以0.5作爲分界線就是右上角那個:
在這裏插入圖片描述
概率論與數理統計學過,確定一個高斯分佈,需要知道mu和sigma,mu決定它的頂點位置,sigma決定它的胖瘦、拉伸。我們之前得到的水系和通用系的mu和sigma都是不一樣的,其實我們可以只將mu設置不同,而sigma讓兩者相同,這樣的話,上面模型中的0.5分界線就會變成直線,接下來就是最閃光的時刻。

我們分析貝葉斯概率公式,可以得到如下結果:
在這裏插入圖片描述
這就是大名鼎鼎的sigmoid函數的由來。

再將圖中的z化簡,得到如下結果:
在這裏插入圖片描述當兩個高斯模型共用sigma的時候,就變成了一個線性模型,這樣就解釋了上面分界線變成直線的現象了。

這樣子其實有點複雜,因爲繞了一大圈,又求mu又求sigma,回來還是求w和b,明天將介紹直接求解w和b的方法。

2020.4.19
今日出門、頭疼,只學了Python。

學習了《Python編程 從入門到實踐》 第四章
#遍歷整個列表
place=['shanghai','guangzhou','shenzhen','beijing','xian']
for i in place:
    print(i)

其中i是作爲臨時變量存在的。注意不要忘記縮進和冒號。

range()函數的用法:

#規定循環次數
for i in range(1,5)
    print(i)
#結果是打印1到4。
#使用range()創建數字列表
numbers=list(range(1,5))
#結果是[1,2,3,4]

對列表進行簡單的計算:

#就是字面意思
sum(numbers)
min(numbers)
max(numbers)

列表切片:

number[0:3]   #表示numbers中第一到第三個元素
number[-3:]    #表示numbers中倒數第三到最後

遍歷切片:

for i in numbers[3:]     
    print(i)      # 表示打印numbers中第二個到最後的元素們

複製列表:

numbers_ok=numbers[:]   #注意不能使用 numbers_ok=numbers 這樣其實是兩個變量指向了同一個列表。

Python中的元組使用小括號()來定義,元組不可修改,但是可以對元組變量名進行重新賦值,也可以同列表一樣使用便利操作。

2020.4.20

學習了《Python編程 從入門到實踐》 第五章

這一章Python的主要內容是if語句的使用,很簡單就不再多說了。
檢查特定值是否包含在列表中:

'shanghai' in place
'shanghai' not in place

檢查列表是不是空的:

place=[]
if place:
     ...
else:
     print('這是個空列表')

2020.4.21

學習了《Python編程 從入門到實踐》 第六章

這一章的主要內容是字典。
首先是創建字典,字典使用花括號創建,每一項包括一個健和一個值,鍵和值之間使用冒號分割,每一項之間使用逗號分割。

sun={'name':'sun','age':18,'home':'xinjiang'}

訪問字典中的值

sun['name']

添加鍵值對

sun['glass']=True

刪除鍵值對

del sun['age']

遍歷字典

for key,value in sun.items()

遍歷字典中的健、值

for key in sun.keys()

for value in sun.values()

多個字典可以存放在列表裏,列表也可以作爲值存放在字典裏,字典也可以作爲值存放在字典裏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章