線性迴歸(Linear Regression)是機器學習(Machine Learning)中常用且基本的model之一,但Sckit-Learn中線性迴歸不僅僅只是能處理線性資料,也能以簡單的方式以多項式迴歸(Polynomial Regression)對資料做擬合(fitting)。換句話說,也就是不儘是線性函數:
y = ax + b
也能以多項式擬合(fitting):
y = ax + bx^2 + cx^3+ ........
怎麼做呢? 基本上就是山不轉路轉,動不了特徵值,換個x值總可以吧。
來看看實際例子:
先import會用到的module:
其中PolynomialFeatures就是轉換座標的關鍵函式(Polynomial basis functions)。
舉例來說,若我本來輸入的x值是2,4,6,此函式就會幫我們轉成2次、3次等等。
只要利用.fit_transform就可以輕鬆達成!!!
看一下實際例子吧,假如我們有下列的資料:
這一看就明顯不是"線性",反而像正弦之類的函數,我們這邊嚐試利用多項式來解,
利用剛才的工具:
我們調用了sklearn.linear_model的LinearRegression,並用較高階的語法make_pipeline直接把x值轉換與模型建立一次完成了。注意在PolynomialFeatures中,我們使用到六次項(6)。
接著擬合剛建立的模型(poly_model)poly_model.fit(),其中xfit是我們自己建立的x值:
得到yfit後,再畫出本來的資料與得到的model,看來結果還不錯囉!!!
參考資料:https://jakevdp.github.io/PythonDataScienceHandbook/
2018年6月18日 星期一
2018年6月13日 星期三
jupyter lab module不能import的問題
Jupyter Lab是jupyter notebook的新版,但會常碰到一些module沒法成功import的問題。我就碰過幾次了,都會跑出這個結果:
沒法import pandas-datareader
參考stackoverflow
我的方法就是重裝囉:
沒法import ipywidgets
參考ipywidgets官網
install the JupyterLab Extension
這應該能解決問題囉!!
ImportError: cannot import name 'is_list_like'
這邊把解法記下來:沒法import pandas-datareader
參考stackoverflow
我的方法就是重裝囉:
> pip install git+https://github.com/pydata/pandas-datareader.git
沒法import ipywidgets
參考ipywidgets官網
install the JupyterLab Extension
> jupyter labextension install @jupyter-widgets/jupyterlab-manager
這應該能解決問題囉!!
2018年6月10日 星期日
Python:刪除重複值
最近試著寫個有關於字串的程式,其中必須要把重複值去掉,這才發現沒想像中那麼簡單。把結果紀錄如下。
當然最直觀的做法就是寫個for 迴圈,找出重複的部分再重組成一個新的list,當然這樣做是可以的,但比較麻煩,也容易出錯,最"簡單"(程式碼較少)的作法是利用python的資料結構set。
我們都知道python中的set會把重複的部分去除(這是我們要的):
這邊我們有個list(new_list),內有重複的'def',我們將new_list轉成set,再轉回list就可以把重複值去除了。
但很明顯的是,這樣做的缺點是次序會被打亂,因此解決的方式就是另用sorted函式並加個key:
達成目標了!!!
不過或許會有疑問,為什麼不使用sort函式?
這是因為sort是inline的排列,並不會回傳排序後的新list(回傳值是None):
所以如果排序只是程式中的一個步驟,沒有回傳值會很麻煩,小弟才疏學淺,接下來我實在不知怎寫下去。
當然python資料處理就不能忘了資料清洗之王Pandas,有了pandas,我們就可以利用.drop_duplicates函式處理。先import pandas,再把資料轉成pandas的series:
接下來進行去重複值的工作:
這邊要注意的是,.drop_duplicates函式會回傳一個新的series,並不會更改原來的series。
到這邊好像跟之前的方法大同小異,還要import pandas,好像也沒有更簡單,不過如果這麼想,這就太小看pandas了,.drop_duplicates函式預設的是保留(keep)第一個重複的值(keep='first'),刪除其他的重複值,但如果是你想保留最後一個呢?嘿嘿~~~這就非得用pandas了,將函式中的keep值設為'last':
如果心情不好,重複的值都去掉也可以,keep設為False就可:
當然最直觀的做法就是寫個for 迴圈,找出重複的部分再重組成一個新的list,當然這樣做是可以的,但比較麻煩,也容易出錯,最"簡單"(程式碼較少)的作法是利用python的資料結構set。
我們都知道python中的set會把重複的部分去除(這是我們要的):
這邊我們有個list(new_list),內有重複的'def',我們將new_list轉成set,再轉回list就可以把重複值去除了。
但很明顯的是,這樣做的缺點是次序會被打亂,因此解決的方式就是另用sorted函式並加個key:
達成目標了!!!
不過或許會有疑問,為什麼不使用sort函式?
這是因為sort是inline的排列,並不會回傳排序後的新list(回傳值是None):
所以如果排序只是程式中的一個步驟,沒有回傳值會很麻煩,小弟才疏學淺,接下來我實在不知怎寫下去。
當然python資料處理就不能忘了資料清洗之王Pandas,有了pandas,我們就可以利用.drop_duplicates函式處理。先import pandas,再把資料轉成pandas的series:
接下來進行去重複值的工作:
這邊要注意的是,.drop_duplicates函式會回傳一個新的series,並不會更改原來的series。
到這邊好像跟之前的方法大同小異,還要import pandas,好像也沒有更簡單,不過如果這麼想,這就太小看pandas了,.drop_duplicates函式預設的是保留(keep)第一個重複的值(keep='first'),刪除其他的重複值,但如果是你想保留最後一個呢?嘿嘿~~~這就非得用pandas了,將函式中的keep值設為'last':
如果心情不好,重複的值都去掉也可以,keep設為False就可:
2018年6月3日 星期日
Python: Numpy介紹
List是Python中常用的資料結構,因Python動態型別的特性,可以建立"異質"的list,例如:
In[1]: L1 = [2, True, 'a']
[type(item) for item in L1]
In[1]: L1 = [2, True, 'a']
[type(item) for item in L1]
Out[1]: [int, bool, str]
不過這種"動態"的特性並不是免費的,list中的每一個項目必須包含了資料的型態、大小、參考計數等等額外的資料,所以list的缺乏運算的效率(或者說根本沒法做數學運算),因此若能儲存成同一型態,雖然缺乏型態上的彈性,但卻能大幅增加運算的效率。雖然python提供了標準的array模組,但真的好用且真正多數人使用的是numpy模組。numpy會把陣列中的資料轉成相同的型態,因而提升運算效能:
常用的numpy程式指令:
陣列的串接,可分成水平跟垂直的方式:
有人喜歡用reshape也可:
陣列分割,np.split()中的second argument是分割的位置:
創建陣列,如.linspace這個在往後繪圖中會常用到:
Universal Function提供了方便的矩陣運算,可以看看下列例子:
numpy內的亂數random也是很常用的,非常非常重要。
random函數其實並不是真的"隨機"取樣,而是偽亂數,就是有亂數的樣子,但實際上是先安排好的,所以其實可以避免每一次取的亂數不同,方法就是利用.RandomState(),argument輸入相同的數字,取得的"亂數"就會相同,可以確保每一次執行都有一樣的結果:
另外也可以使用條件式取得布林陣列(True或是False),並用np.sum()或np.count_nonzero()計算符合運算條件的資料數目,這個在數據的分析上非常有用的。
注意np.sum()可以axis=0 or 1限定以行或列的方向進行運算,另外np.any()、np.all()應該看例子就可以理解用途了。
不過這種"動態"的特性並不是免費的,list中的每一個項目必須包含了資料的型態、大小、參考計數等等額外的資料,所以list的缺乏運算的效率(或者說根本沒法做數學運算),因此若能儲存成同一型態,雖然缺乏型態上的彈性,但卻能大幅增加運算的效率。雖然python提供了標準的array模組,但真的好用且真正多數人使用的是numpy模組。numpy會把陣列中的資料轉成相同的型態,因而提升運算效能:
常用的numpy程式指令:
陣列的串接,可分成水平跟垂直的方式:
陣列的改造,如陣列互換,這個在Machine Learning中常用到,非常重要。
有人喜歡用reshape也可:
陣列分割,np.split()中的second argument是分割的位置:
創建陣列,如.linspace這個在往後繪圖中會常用到:
Universal Function提供了方便的矩陣運算,可以看看下列例子:
numpy內的亂數random也是很常用的,非常非常重要。
random函數其實並不是真的"隨機"取樣,而是偽亂數,就是有亂數的樣子,但實際上是先安排好的,所以其實可以避免每一次取的亂數不同,方法就是利用.RandomState(),argument輸入相同的數字,取得的"亂數"就會相同,可以確保每一次執行都有一樣的結果:
另外也可以使用條件式取得布林陣列(True或是False),並用np.sum()或np.count_nonzero()計算符合運算條件的資料數目,這個在數據的分析上非常有用的。
注意np.sum()可以axis=0 or 1限定以行或列的方向進行運算,另外np.any()、np.all()應該看例子就可以理解用途了。
2018年5月20日 星期日
Jupyter Lab
jupyter notebook利用直譯語言的特性可以即時輸出程式的結果,是很多人愛用的程式語言工具。而現在有更新版本出現囉!!!
jupyter lab是jupyter的新版,特別是針對檔案切換的不便作出改善。如下圖示jupyter lab的操作畫面,可以看到左邊多了檔案目錄的視窗,因此要找或轉換檔案比起jupyter notebook方便得多了。多了這些特性與功能,儼然演化成完整的的IDE了。
安裝jupyter lab很簡單:
>>>conda install -c conda-forge jupyterlab
不過有些套件module可能要重裝(pip or conda)。
執行時只要鍵入:
>>>jupyter lab
將出現下面畫面:
選擇Notebook,就大功告成囉!!!
現在jupyter lab版本仍然還是beta版,應該很快最會推出穩定的1.0版。
參考資料:
https://jupyterlab.readthedocs.io/en/latest/
jupyter lab是jupyter的新版,特別是針對檔案切換的不便作出改善。如下圖示jupyter lab的操作畫面,可以看到左邊多了檔案目錄的視窗,因此要找或轉換檔案比起jupyter notebook方便得多了。多了這些特性與功能,儼然演化成完整的的IDE了。
安裝jupyter lab很簡單:
>>>conda install -c conda-forge jupyterlab
不過有些套件module可能要重裝(pip or conda)。
執行時只要鍵入:
>>>jupyter lab
將出現下面畫面:
選擇Notebook,就大功告成囉!!!
現在jupyter lab版本仍然還是beta版,應該很快最會推出穩定的1.0版。
參考資料:
https://jupyterlab.readthedocs.io/en/latest/
2018年3月25日 星期日
Python: list comprehensive (Dictionary Comprehensive)
Python的list comprehensive是python語言中最強大的特色之一,可以讓你使用很簡單的句子就完成list的創建,python list comprehensive的通式如下:
[ __ for __ in ____ ]
舉例來說:
>>>list1 = [num for num in range(0,6)]
就可以創建出 [0, 1, 2, 3, 4]的list
後面還可以加入更複雜的條件式,如:
>>>list2 = [num for num in range(0,10) if num%2 == 0]
就可以創建出 [0, 2, 4, 6, 8]的list
當然還有不少有趣的例子,附在下方:
要注意的是其中最後一個例子運用在string上。
最後,python也允許有複雜的巢式(nested)的函式呼叫,例如:
2018/3/28 補充
此外,Dictionary Comprehensive與List Comprehensive非常類似,通式如下:
{ __:__ for __ in ____ }
例如:
第一個例子中,因預設(default)就是iterate鍵值(key),所以只看到keys。
而在第二個例子中,key及value都用到了,所以要注意最後in的後面必須改成.items,表示要iterate的整個item。
更多創建出dictionary的例子:
[ __ for __ in ____ ]
舉例來說:
>>>list1 = [num for num in range(0,6)]
就可以創建出 [0, 1, 2, 3, 4]的list
後面還可以加入更複雜的條件式,如:
>>>list2 = [num for num in range(0,10) if num%2 == 0]
就可以創建出 [0, 2, 4, 6, 8]的list
當然還有不少有趣的例子,附在下方:
要注意的是其中最後一個例子運用在string上。
最後,python也允許有複雜的巢式(nested)的函式呼叫,例如:
2018/3/28 補充
此外,Dictionary Comprehensive與List Comprehensive非常類似,通式如下:
{ __:__ for __ in ____ }
例如:
第一個例子中,因預設(default)就是iterate鍵值(key),所以只看到keys。
而在第二個例子中,key及value都用到了,所以要注意最後in的後面必須改成.items,表示要iterate的整個item。
更多創建出dictionary的例子:
Python: Interesting Python codes (== and is)
最近發現兩個跟python相關且有趣的code:
第一個:
首先看下方的程式好像很正常:
但是如果變數a與b的值大一點:
ㄟ.......怎會這樣?
找答案前先來看一下id()這個指令:
執行後會回傳變數的記憶體位置。
所以我們看一下a, b記憶體的位置:
所以我們可以看到a與b的值是一樣的,所以a == b當然是對(True)的,但"a is b"必須考量記憶體的位置必須相同,所以當然就是錯(False)的囉。這感覺有點類似於C裡面的指標。
或者是說,只要 == 兩邊的值是一樣的,a == b就是True,但a與b是不同物件,所以如果使用"is",必須是同個物件才是True,否則就是False。
同樣的,我們可以類推類似的結果於list上:
不過還有一個問題沒解決,就是為什麼數字小的"is"跟"=="的結果就是一樣的?
這是因為python為了效率,將-5至256的integer置於cache(快取),所以這些int是指向同一個記憶體位置的,例如下方的例子:
所以既然記憶體位置都一樣,"a is b"當然也是True,不過記得如上述的例子,只要值小於256,更精確的說是-5到256的值是比較特殊的,結果就不同囉!!!我想這邊真的要小心,否則寫出程式很容易有bug。
第二個:
>>> a = range(2,6)
>>> print(a)
會輸出哪個結果?
是 2,3,4,5 還是 range(2,6)??
答案是:
range(2,6)
因為range()必須透過iteration執行,但print()只執行一次,所以當然結果就是range()本身的指令了。
第一個:
首先看下方的程式好像很正常:
但是如果變數a與b的值大一點:
ㄟ.......怎會這樣?
找答案前先來看一下id()這個指令:
執行後會回傳變數的記憶體位置。
所以我們看一下a, b記憶體的位置:
所以我們可以看到a與b的值是一樣的,所以a == b當然是對(True)的,但"a is b"必須考量記憶體的位置必須相同,所以當然就是錯(False)的囉。這感覺有點類似於C裡面的指標。
或者是說,只要 == 兩邊的值是一樣的,a == b就是True,但a與b是不同物件,所以如果使用"is",必須是同個物件才是True,否則就是False。
同樣的,我們可以類推類似的結果於list上:
不過還有一個問題沒解決,就是為什麼數字小的"is"跟"=="的結果就是一樣的?
這是因為python為了效率,將-5至256的integer置於cache(快取),所以這些int是指向同一個記憶體位置的,例如下方的例子:
所以既然記憶體位置都一樣,"a is b"當然也是True,不過記得如上述的例子,只要值小於256,更精確的說是-5到256的值是比較特殊的,結果就不同囉!!!我想這邊真的要小心,否則寫出程式很容易有bug。
第二個:
>>> a = range(2,6)
>>> print(a)
會輸出哪個結果?
是 2,3,4,5 還是 range(2,6)??
答案是:
range(2,6)
因為range()必須透過iteration執行,但print()只執行一次,所以當然結果就是range()本身的指令了。
2018年3月18日 星期日
Microsoft Visual Studio 2017 編寫C語言
我們都知道Microsoft Visual Studio是個很好用(其實應該說很強大,但這個詞太常用了)的IDE,能編寫許多程式語言,也有不少的擴充功能,是提升軟體生產力的好工具,現在已有2017的版本,個人用的版本更是免費的!!!
有需要的可以在這Visual Studio下載。
不過雖然Visual Studio 2017適用於編寫C/C++語言,但其中C語言的編譯過程卻較不那麼直觀,我們接下來看看怎麼使用Visual Studio 2017編寫C吧。
首先於Visual Studio 2017建立新專案(紅框內):
接下來選擇Visual C++,最重要的是接下來一定要選擇空白專案,不然之後就改不了了:
之後利用滑鼠右鍵點選來源檔案、加入、新增項目:
接著可以看到開啟的檔案Source.cpp,.cpp是C++的副檔名:
把.cpp改成.c,另外簡單寫個Hello甚麼的C程式:
執行成功!!!
有需要的可以在這Visual Studio下載。
不過雖然Visual Studio 2017適用於編寫C/C++語言,但其中C語言的編譯過程卻較不那麼直觀,我們接下來看看怎麼使用Visual Studio 2017編寫C吧。
首先於Visual Studio 2017建立新專案(紅框內):
接下來選擇Visual C++,最重要的是接下來一定要選擇空白專案,不然之後就改不了了:
之後利用滑鼠右鍵點選來源檔案、加入、新增項目:
接著可以看到開啟的檔案Source.cpp,.cpp是C++的副檔名:
把.cpp改成.c,另外簡單寫個Hello甚麼的C程式:
執行成功!!!
2018年3月11日 星期日
Tensorflow (Tensorboard)
Tensorboard的使用方式如下:
在jupyter notebook中先運用tensorflow建構一個簡單的tensorflow模型:
之後輸入以下程式碼:
tf.summary.merge_all()
train_writer = tf.summary.FileWrite('你要存的檔案目錄', sess.graph)
就會將所有的tensorflow的資料打包,並存檔。
怎麼打開tensorboard呢?
要先離開jupyter notebook回到cmd,在Tensorflow的Anaconda的虛擬環境之中執行下列命令:
>activate tensorflow
接下來啟動Tensorboard:
>tensorboard --logdir=c:\你剛存檔的目錄
得到如下的畫面:
可以看到紅色框框中有個網址:
這是個人筆電的內部ip
2018年2月3日 星期六
Anaconda下載及更新套件
在此目錄下
:\Users\yourname>
注意不能在anaconda目錄下
升級conda
>conda update conda
>conda update anaconda
下載套件
#安裝模塊
>conda install 套件模塊名稱
#更新模塊
>conda update 模塊名稱
#更新所有模塊
>conda update --all
#升級模塊
>conda upgrade 模塊模組
example:
>conda upgrade spyder
注意在套件(如anaconda)下不要使用pip指令
2018年1月29日 星期一
Keras: CNN辨識Cifar-10
CIRAF-10資料集是一組影像辨識的資料集,共有十種分類(包含有鳥、貓、汽車、卡車等等圖片,因圖片是彩色,雜訊多(有時連人都難以辨認),所以辨識難度比之前的MNIST高得多。我們接下來就以CNN(Convolution neural network)建立模型,進行CIRAF-10資料庫的辨識。
CNN一般來說比先前的基礎ANN多元感知器能達到更高的準確率,利用卷積層及池化層能提取圖片的特徵,增加辨識的能力,CNN的基礎理論從這裡可以看到不錯的介紹,所以就不囉嗦,直接來看看Keras程式吧。
先import需要的資料庫及CIRAF-10資料集,因Keras已內建,可以直接使用cifra10.load_data()的指令讀取:
看一下download的內容:

可以知道有訓練圖形(image)資料50000筆,驗證(Test)資料則有10000筆,每一筆資料為32x32的矩陣,最後一個維度是RGB三原色三個數字,代表圖素的顏色。標籤(label)的資料則有一個數字表示圖片的類別。
我們可以看一筆資料中的一個畫素:
(159, 102, 101)各代表RGB三原色的數字大小,可進一步看圖片:
是一台紅色車子,預期標籤應該是1(注意程式中已利用dictionary轉換標籤了)。
接下來進行數據的預處理,同樣包含了設定類型(float32)並標準化以提升準確率,可以看一下第一筆資料的第一個圖素,確定有沒有錯誤:
另外有一點要注意的是,跟ANN有差異的地方在於資料轉換,MNIST原本資料是(60000, 28, 28),ANN轉換成一維的784個數字(看這邊),而CNN必須保持圖片二維的特性,之後才可以利用卷積層及池化層提取圖片的特徵。
標籤方面也是必需轉換成one hot encoding的型態(也一樣可以參考前篇):
接下來就是模型的設定了:
這邊不得不感恩Keras!讚嘆Keras!!!!把最困難的部分變得簡單極了,我相信只要這篇懂了,也知道CNN的原理,模型建立的程式根本是一塊小蛋糕了,除了每層的參數設定有點小變化,一點難度都沒有(不過程式跑得比較久就是)。
接下來就是進行預測囉,仍然利用model.predict_classes()的指令預測,
從結果看來前三筆預測結果分別是3,8,8,對照先前的dictionary分別為貓、船及船。同樣地直接看前三筆資料的圖檔會比較有真實感:
老實說,我還真不知道怎判斷第一筆資料是貓(cat)耶!
接下來仍然利用pandas的.crosstab指令產生confusion matrix(混淆矩陣),可以清楚哪些是正確預測的部分(對角線),哪些是預測錯誤的部分了。例如這次來看看標籤是0但預測成5的有8筆資料。
同樣地先建立下列標籤與預測值對照的完整表格,先看前三筆資料,跟先前的一樣,所以應該錯誤機率不大:
接下來看看哪些是標籤為0(飛機)但卻是預測為5(狗)的資料:
接下來print出第1898筆資料看看:
ㄟ.......這哪像狗了啊?一看就是飛機啊,只能說人工智慧跟人類思考還是不一樣,對照第一筆資料人類大概很難看出是貓,或許未來機器人跟人類的智慧還是互補的吧!!??
參考資料
TensorFlow+Keras深度學習人工智慧實務應用
CNN一般來說比先前的基礎ANN多元感知器能達到更高的準確率,利用卷積層及池化層能提取圖片的特徵,增加辨識的能力,CNN的基礎理論從這裡可以看到不錯的介紹,所以就不囉嗦,直接來看看Keras程式吧。
先import需要的資料庫及CIRAF-10資料集,因Keras已內建,可以直接使用cifra10.load_data()的指令讀取:
另外開一個dictionary(label_dictionary)儲存每一個label數字代表的類別(共十種)。

可以知道有訓練圖形(image)資料50000筆,驗證(Test)資料則有10000筆,每一筆資料為32x32的矩陣,最後一個維度是RGB三原色三個數字,代表圖素的顏色。標籤(label)的資料則有一個數字表示圖片的類別。
我們可以看一筆資料中的一個畫素:
(159, 102, 101)各代表RGB三原色的數字大小,可進一步看圖片:
是一台紅色車子,預期標籤應該是1(注意程式中已利用dictionary轉換標籤了)。
接下來進行數據的預處理,同樣包含了設定類型(float32)並標準化以提升準確率,可以看一下第一筆資料的第一個圖素,確定有沒有錯誤:
另外有一點要注意的是,跟ANN有差異的地方在於資料轉換,MNIST原本資料是(60000, 28, 28),ANN轉換成一維的784個數字(看這邊),而CNN必須保持圖片二維的特性,之後才可以利用卷積層及池化層提取圖片的特徵。
標籤方面也是必需轉換成one hot encoding的型態(也一樣可以參考前篇):
總結一下整個程式如下:
同樣地以圖表看看最後結果:
可以清楚看到大量使用Dropout(最後一次參數為0.5)確實可以降低overfitting的現象,train及validation的差異較小。
訓練完model之後,接著就是以Test的資料測試,同樣使用model.evaluate指令:
測試結果的loss為0.824而準確率(accuracy)約72.6%,相較於先前的MNIST資料集確實低很多,當然圖片為彩色且雜訊多應該是主要原因吧。
接下來就是進行預測囉,仍然利用model.predict_classes()的指令預測,
從結果看來前三筆預測結果分別是3,8,8,對照先前的dictionary分別為貓、船及船。同樣地直接看前三筆資料的圖檔會比較有真實感:
接下來仍然利用pandas的.crosstab指令產生confusion matrix(混淆矩陣),可以清楚哪些是正確預測的部分(對角線),哪些是預測錯誤的部分了。例如這次來看看標籤是0但預測成5的有8筆資料。
同樣地先建立下列標籤與預測值對照的完整表格,先看前三筆資料,跟先前的一樣,所以應該錯誤機率不大:
接下來看看哪些是標籤為0(飛機)但卻是預測為5(狗)的資料:
參考資料
TensorFlow+Keras深度學習人工智慧實務應用
訂閱:
文章 (Atom)


























































