【scikit-learn】用Python進行機器學習實驗

概要

本文是用Python編程語言來進行機器學習小實驗的第一篇。主要內容如下:

  1. 讀入數據并清洗數據
  2. 探索理解輸入數據的特點
  3. 分析如何為學習算法呈現數據
  4. 選擇正確的模型和學習算法
  5. 評估程序表現的準確性

讀入數據 Reading the data

當讀入數據時,你將面臨處理無效或丟失數據的問題,好的處理方式相比于精確的科學來說,更像是一種藝術。因為這部分處理適當可以適用于更多的機器學習算法并因此提高成功的概率。

用NumPy有效地咀嚼數據,用SciPy智能地吸收數據

Python是一個高度優化的解釋性語言,在處理數值繁重的算法方面要比C等語言慢很多,那為什么依然有很多科學家和公司在計算密集的領域將賭注下在Python上呢?因為Python可以很容易地將數值計算任務分配給C或Fortran這些底層擴展。其中NumPy和SciPy就是其中代表。
NumPy提供了很多有效的數據結構,比如array,而SciPy提供了很多算法來處理這些arrays。無論是矩陣操作、線性代數、最優化問題、聚類,甚至快速傅里葉變換,該工具箱都可以滿足需求。


讀入數據操作

這里我們以網頁點擊數據為例,第一維屬性是小時,第二維數據是點擊個數。

import scipy as sp
data = sp.genfromtxt('web_traffic.tsv', delimiter='\t')

預處理和清洗數據

當你準備好了你的數據結構用于存儲處理數據后,你可能需要更多的數據來確保預測活動,或者擁有了很多數據,你需要去思考如何更好的進行數據采樣。
在將原始數據(raw data)進行訓練之前,對數據進行提煉可以起到很好的作用,有時,一個用提煉的數據的簡單的算法要比使用原始數據的高級算法的表現效果要好。這個工作流程被稱作特征工程(feature engineering)。Creative and intelligent that you are, you will immediately see the results。

由于數據集中可能還有無效數值(nan),我們可以事先看一下無效值的個數:

hours = data[:,0]
hits = data[:,1]
sp.sum(sp.isnan(hits))

用下面的方法將其過濾掉:

#cleaning the data
hours = hours[~sp.isnan(hits)]
hits = hits[~sp.isnan(hits)]

為了將數據給出一個直觀的認識,用Matplotlib的pyplot包來將數據呈現出來。

import matplotlib.pyplot as plt
plt.scatter(hours,hits)
plt.title("Web traffic over the last month")
plt.xlabel("Time")
plt.ylabel("Hits/hour")
plt.xticks([w*7*24 for w in range(10)],
 ['week %i'%w for w in range(10)])
plt.autoscale(tight=True)
plt.grid()
plt.show()

其顯示效果如下:


選擇合適的學習算法

選擇一個好的學習算法并不是從你的工具箱中的三四個算法中挑選這么簡單,實際上有更多的算法你可能沒有見過。所以這是一個權衡不同的性能和功能需求的深思熟慮的過程,比如執行速度和準確率的權衡,,可擴展性和易用性的平衡。

現在,我們已經對數據有了一個直觀的認識,我們接下來要做的是找到一個真實的模型,并且能推斷未來的數據走勢。

用逼近誤差(approximation error)來選擇模型

在很多模型中選擇一個正確的模型,我們需要用逼近誤差來衡量模型預測性能,并用來選擇模型。這里,我們用預測值和真實值差值的平方來定義度量誤差:

def error(f, x, y):
    return sp.sum((f(x)-y)**2)

其中f表示預測函數。

用簡單直線來擬合數據

我們現在假設該數據的隱含模型是一條直線,那么我們還如何去擬合這些數據來使得逼近誤差最小呢?
SciPy的polyfit()函數可以解決這個問題,給出x和y軸的數據,還有參數order(直線的order是1),該函數給出最小化逼近誤差的模型的參數。

fp1, residuals, rank, sv, rcond = sp.polyfit(hours, hits, 1, full=True)

fp1是polyfit函數返回模型參數,對于直線來說,它是直線的斜率和截距。
如果polyfit的參數full為True的話,將得到擬合過程中更多有用的信息,這里只有residuals是我們感興趣的,它正是該擬合直線的逼近誤差。
然后將該線在圖中畫出來:

#fit straight line model
fp1, residuals, rank, sv, rcond = sp.polyfit(hours, hits, 1, full=True)
fStraight = sp.poly1d(fp1)

#draw fitting straight line
fx = sp.linspace(0,hours[-1], 1000) # generate X-values for plotting
plt.plot(fx, fStraight(fx), linewidth=4)
plt.legend(["d=%i" % fStraight.order], loc="upper left")

用更高階的曲線來擬合數據

用直線的擬合是不是很好呢?用直線擬合的誤差是317,389,767.34,這說明我們的預測結果是好還是壞呢?
我們不妨用更高階的曲線來擬合數據,看是不是能得到更好的效果。

fCurve3p = sp.polyfit(hours, hits, 3)
fCurve3 = sp.poly1d(fCurve3p)
print "Error of Curve3 line:",error(fCurve3,hours,hits)

fCurve10p = sp.polyfit(hours, hits, 10)
fCurve10 = sp.poly1d(fCurve10p)
print "Error of Curve10 line:",error(fCurve10,hours,hits)

fCurve50p = sp.polyfit(hours, hits, 50)
fCurve50 = sp.poly1d(fCurve50p)
print "Error of Curve50 line:",error(fCurve50,hours,hits)

其逼近誤差為:

Error of straight line: 317389767.34
Error of Curve2 line: 179983507.878
Error of Curve3 line: 139350144.032
Error of Curve10 line: 121942326.364
Error of Curve50 line: 109504587.153


這里我們進一步看一下實驗結果,看看我們的預測曲線是不是很好的擬合數據了呢?尤其是看一下多項式的階數從10到50的過程中,模型與數據貼合太緊,這樣模型不但是去擬合數據背后的模型,還去擬合了噪聲數據,導致曲線震蕩劇烈,這種現象叫做過擬合

小結

從上面的小實驗中,我們可以看出,如果是直線擬合的話就太簡單了,但多項式的階數從10到50的擬合又太過了,那么是不是2、3階的多項式就是最好的答案呢?但我們同時發現,如果我們以它們作為預測的話,那它們又會無限制增長下去。所以,我們最后反省一下,看來我們還是沒有真正地理解數據。

衡量性能指標

作為一個ML的初學者,在衡量學習器性能方面會遇到很多問題或錯誤。如果是拿你的訓練數據來進行測試的話,這可能是一個很簡單的問題;而當你遇到的不平衡的訓練數據時,數據就決定了預測的成功與否。

回看數據

我們再仔細分析一下數據,看一下再week3到week4之間,好像是有一個明顯的拐點,所以我們把week3.5之后的數據分離出來,訓練一條新的曲線。

inflection = 3.5*7*24 #the time of week3.5 is an inflection
time1 = hours[:inflection]
value1 = hits[:inflection]
time2 = hours[inflection:]
value2 = hits[inflection:]

fStraight1p = sp.polyfit(time1,value1,1)
fStraight1 = sp.poly1d(fStraight1p)
fStraight2p = sp.polyfit(time2,value2,1)
fStraight2 = sp.poly1d(fStraight2p)

顯然,這兩條直線更好的描述了數據的特征,雖然其逼近誤差還是比那些高階多項式曲線的誤差要大,但是這種方式的擬合可以更好的獲取數據的發展趨勢。相對于高階多項式曲線的過擬合現象,對于低階的曲線,由于沒有很好的描述數據,而導致欠擬合的情形。所以為了更好的描述數據特征,使用2階曲線來擬合數據,來避免過擬合和欠擬合現象的發生。

訓練與測試

我們訓練得到了一個模型,這里就是我們擬合的兩個曲線。為了驗證我們訓練的模型是否準確,我們可以在最初訓練時將一部分訓練數據拿出來,當做測試數據來使用,而不僅僅通過逼近誤差來判別模型好壞。

總結

這一小節作為機器學習小實驗的引入,主要傳遞兩點意思:
1、要訓練一個學習器,必須理解和提煉數據,將注意力從算法轉移到數據上
2、學習如何進行機器學習實驗,不要混淆訓練和測試數據
未來,我將加快速度,學習并實踐。

參考文獻

Building Machine Learning Systems with Python. Richert,W . Coelho,L P

轉載請注明作者Jason Ding及其出處
Github主頁(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
簡書主頁(http://www.lxweimin.com/users/2bd9b48f6ea8/latest_articles)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內容