最近老哥潛心修煉"機器學習"相關知識,發現高大上的機器學習,入門竟然是如此的簡單。了解了基本原理之後,上手只需要10分鐘。今天,老哥用自己寫的一個小案例,帶你走進機器學習的世界~
本次老哥使用了sklearn提供的案例數據集「fetch_20newsgroups」,採用樸素貝葉斯算法對新聞進行分類,並用pyecharts對結果可視化。
數據集劃分是影響機器學習的準確率的重要參數,因此老哥編寫了一個循環來測試最佳參數,最終在測試集佔比22%的時候得到最優結果,訓練的準確率高達91.8%
公眾號回復4月18日即可獲得代碼和數據集。數據集的使用請看後面的「數據探索」章節。
話不多說,一起開啟今天的10分鐘老哥「機器學習小課堂」吧。
器學習分為監督學習、無監督學習。監督學習(supervised learning)指從給定的訓練數據集中學習出一個函數模型,可根據該模型來預測新數據的結果。
無監督學習(unsupervised learning)輸入數據沒有被標記,也沒有確定的結果。樣本數據類別未知,需要根據樣本間的相似性聚類(clustering),試圖將類內差距最小化,類間差距最大化。
舉個監督學習的例子。假如現在有個問題,大象是不是「suckler」?(你不必理解suckler的含義)
鑑於你和電腦都不知道什麼是「suckler」,那麼給你一些參考:
現在你是否知道大象是不是「suckler」呢,不知道也關係,如果再給你10000個例子,你一定會知道。
事實上,大象是「suckler」,分類標準為哺乳動物。根據一些特徵進行分類,就是監督學習了。
必須有訓練集和測試集,在訓練集找規律,在測試集檢驗準確率。
沒有標籤,如果數據集有聚集性,則可按自然的聚集性分類
計學中將數據分為連續變量(Continuous)和離散變量(Discrete)。連續變量是一定區間內可任意取值的變量,可以是小數,相鄰數值間可無限制分割,例如長度、時間等。
離散變量必須是整數且不可分割,數據之間的差值不固定。離散變量一般通過計數方法都得到,例如人數、店鋪數等。
如果離散變量的變動幅度較小,則每個變量值可以對應一組分類,稱為單項式分組。如果變動幅度很大,那麼可以劃分幾個區間,稱為組距式分組,相鄰組的組限可重疊。
離散數據,對應機器學習的分類應用,而連續數據,常常對應預測、聚類等應用。
又叫分類型屬性。指一些符號或實物名稱,每個值代表某種類別。
指只有兩個類別的標稱屬性:0、1。若將0、1對應False、True,則稱為布爾屬性
可用於記錄不能客觀度量的主觀質量評估。比如:0>優,1>良,2>中,3>差。
數值屬性是可度量的量,用整數或實數值表示,有區間標度和比率標度兩種類型。
案例使用sklearn自帶的測試數據集「fetch_20newsgroups」。第一次調用該數據集可能要下載半天,老哥將數據集下好,大家將壓縮包解壓到「C:\Users\Administration\scikit_learn_data」路徑下即可,sklearn默認的數據集路徑均在此路徑下。公眾號回復4月18日即可獲得代碼和數據集。
from sklearn.datasets import fetch_20newsgroups
news = fetch_20newsgroups(subset="all")print(news.data)print(news.target)print(news.DESCR)首先從sklearn.datasets這個API中調用該數據集,數據集的參數中,subset="all"代表使用全部數據。subset="train」表示只調用訓練集,subset="test"表示只調用測試集。
接下來調用data、target等數據集API查看數據格式。可以看到,該數據集內容是18846條新聞文本,目標集則是將這18000條新聞對應到了20個新聞類別標籤上。
們用樸素貝葉斯這個監督算法來解決分類問題,就必須要劃分訓練集。train_test_split()是sklearn包的model_selection模塊中提供的數據分割函數,它可以將原始數據集按照一定比例隨機劃分訓練集和測試集。一般而言,經驗數值是75%訓練集,25%測試集。
from sklearn.model_selection import train_test_splitx_train, x_test, y_train, y_test = train_test_split(x=news.data, y=news.target, test_size=0.25, random_state=20)本例中,為測試不同的數據分割對準確度的影響,將random_state定為20,保證每次數據劃分結果均相同。數據集劃分默認產生4個值,因此需要4個變量承接。
最後系統講一下train_test_split()函數的參數:0~1之間,代表著測試集的分割比例。如0.25就是25%測試集。
0~1之間,代表著訓練集的分割比例。如0.75就是75%訓練集。
通過「np.random」,使用隨機數生成器作為RandomState。
none或者array/series類型的數據,表示按這列進行分層採樣。例如stratify=data['a'],則按a列採樣,每次劃分結果均相同
於新聞來說,很適合用「TF-IDF」加權,然後「fit」數據,最後「transform」數據。老哥解釋一下這些術語。
TF是詞頻(Term Frequency),某詞在文本中出現的頻率。IDF是逆向文件頻率(Inverse Document Frequency),某一特定詞語的IDF,可以由總文件數目除以包含該詞語的文件的數目,再將得到的商取對數得到。
TF-IDF實際上是:TF * IDF。某一特定文件內的高頻詞語,以及該詞語在整個文件集合中的低文件頻率,可以產生出高權重的TF-IDF。因此,TF-IDF傾向於過濾掉常見的詞語,保留重要的詞語。
本例中,例如「技術、大數據」的詞頻在全部1.8w條新聞中並不高,但是卻頻繁出現在科技類新聞中,則這類詞的TF-IDF權重很高,可以作為分類標準看待。
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer()x_train = tf.fit_transform(x_train)x_test = tf.transform(x_test)理論雖然複雜,放到代碼中也就四行而已。首先實例化TfidfVectorizer()為tf,tf來fit_transform特徵值。
在fit的基礎上,進行標準化,降維,歸一化等操作,如(PCA、TF-IDF)
是fit和transform的組合,既包括了訓練又包含了轉換。先fit出整體指標,再根據指令轉換
要注意的是,「fit和transform」沒有任何關係,僅僅是數據處理的兩個不同環節,之所以出來fit_transform()這個函數名,僅僅是為了寫代碼方便。
本例中,首先用TF-IDF作為加權手段,fit並且transform了訓練特徵值。這時候,對於訓練集的fit已經保存在電腦緩存中了,為了保證加權的依據一致,直接transform測試特徵值,即可保證x_train、x_test的fit標準一致。
這是非常重要的一點,如果對於x_test進行fit加transform,因為和前面的方差、均值等數據不同,會導致加權結果有偏差,影響準確率。為了更好的理解這個概念,本例的代碼也可以寫成如下形式:
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer()tf.fit(x_train)x_train = tf.transform(x_train)x_test = tf.transform(x_test)特徵抽取的好壞,直接影響到機器學習的準確率。可以看到kaggle上的比賽,大家算法一致,但是結果天差地別。問題就出在特徵抽取環節,如果你選對了算法和數據分割的比例,那麼即使算法相同,你的準確率也會高於他人。
要被它的名字嚇到了,其實一點點都不難的。老哥帶你通俗易懂的理解「樸素貝葉斯」的含義。
樸素貝葉斯(Naive Bayes),簡稱NB算法。「樸素」的來源是假設各特徵之間相互獨立。這一假設使得樸素貝葉斯算法變得簡單,但有時會犧牲一定的分類準確率。
拿本案例舉例,現在有1.8W條新聞,裡面有14W詞,一共分了20類新新聞。
本例中20類裡面,娛樂類較多有5000條,科技類較少只有1000條。那麼P(娛樂類)=5000/18000,這就是娛樂新聞的概率;相應的,P(科技類)=1000/18000。
例如,P (Big Data | 科技類),指「Big Data」這個詞,在1000篇科技類文檔出現的次數,除以科技類文檔總詞數,就可以得到,「Big Data」這個詞的概率了。
由公式可得,對於目標求解為不同的類別,分母總是相同的,約掉就好了。如果硬要算,那就是:
P(Big Data)=P(科技類)P(Big Data | 科技類)+P(娛樂類)P(Big Data | 娛樂類)+P(財經類)P(Big Data | 財經類)+....+P(第20類)P(Big Data| 第20類)
from sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.model_selection import train_test_splitfrom sklearn.datasets import fetch_20newsgroupsfrom sklearn.naive_bayes import MultinomialNBnews = fetch_20newsgroups(subset="all")x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.25, random_state=20)tf = TfidfVectorizer()x_train = tf.fit(x_train)x_train = tf.transform(x_train)x_test = tf.transform(x_test)mlt = MultinomialNB(alpha=0.01)mlt.fit(x_train, y_train)y_predict = mlt.predict(x_test)y_score = mlt.score(x_test, y_test)print(y_score)通過如上代碼,實際上該機器學習已經算完了。首先實例化MultinomialNB(),裡面的alpha參數叫拉普拉斯平滑係數,默認是1。例如big data在很多文檔一次都沒有出現,那麼NB算法計算出來的概率就為0,這是不合理的,所以就給一個默認參數1,假設讓每個詞在每個文檔都出現一次,這就叫拉普拉斯平滑。
然後只需要.fit(x_train, y_train),將訓練集和訓練集標籤傳入,機器就會自動學習了。
.predict(x_test):可以得到測試集的機器預測分類.score(x_test, y_test):自動判別準確率為樸素貝葉斯是一個概率算法,沒有強參數可以調,所以它的準確率主要來自數據分割。上述代碼中用了25%經驗值,老哥想知道究竟多少是最優解,所以寫了一個循環,將參數與準確率寫入了列表,最後對準確率降冪排序,就得到了最優參數。
可以看到,在分割值為5%和22%的時候,達到了最大值,但是由於5%分割的誤差可能會大,因此最終選擇22%分割值,準確率達到91.8%。
數據探索。sklearn自帶數據集,利用.data、.target函數查看數據。
特徵工程。進行數據集分割。然後使用TF-IDF賦權,或PCA降維等算法。
K-近鄰算法、貝葉斯分類、決策樹與隨機森林、邏輯回歸、神經網絡
k-means、Mean-Shift、DBSCAN、使用GMMs的EM聚類、凝聚層次聚類
調整參數與可視化。基於pyecharts可視化,或調整算法參數、數據集分割參數等,優化準確率。
● 微信號 : jifanglaoge ●