1. 程式人生 > >機器學習的演算法knn,貝葉斯,決策樹

機器學習的演算法knn,貝葉斯,決策樹

sklearn資料集與估計器

資料集劃分

機器學習一般的資料集會劃分為兩個部分

訓練資料:用於訓練,構建模型

測試資料:在模型檢驗時使用,用於評估模型是否有效

資料集劃分API

sklearn.model_selection.train_test_split

sklearn.datasets

載入獲取流行資料集
from sklearn.datasets import load_*
datasets.load_*()
獲取小規模資料集,資料包含在datasets裡

datasets.fetch_*(data_home=None)

獲取大規模資料集,需要從網路上下載,函
數的第一個引數是data_home,表示資料集
下載的目錄,預設是 ~/scikit_learn_data/

獲取資料集返回的型別

load*和fetch*返回的資料型別datasets.base.Bunch(字典格式)

data:特徵資料陣列,是 [n_samples * n_features] 的二維numpy.ndarray 陣列

target:標籤陣列,是 n_samples 的一維 numpy.ndarray 陣列

DESCR:資料描述

feature_names:特徵名,新聞資料,手寫數字、迴歸資料集沒有

target_names:標籤名,迴歸資料集沒有

資料集進行分割

from sklearn.model_selection import train_test_split

x: 資料集的特徵值

y: 資料集的標籤值

test_size: 測試集的大小,一般為float

random_state: 隨機數種子,不同的種子會造成不同的隨機
取樣結果。相同的種子取樣結果相同。

return: 訓練集特徵值,測試集特徵值,訓練標籤,測試標籤
(預設隨機取)

sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)	
#subset: 'train'或者'test','all',可選,選擇要載入的資料集.訓練集的“訓練”,測試集的“測試”,兩者的“全部”

datasets.clear_data_home(data_home=None)
#清除目錄下的資料

步驟

例項化類

name=load_*()

切割資料,輸出訓練集和測試集的train,test

x_train,x_test,y_train,y_test=train_test_split(li.data,li.target,test_size=0.25)#test_size是測試集的佔比

sklearn機器學習演算法的實現-估計器

在sklearn中,估計器(estimator)是一個重要的角色,分類器和迴歸器都屬於estimator,是一類實現了演算法的API

1、用於分類的估計器:

sklearn.neighbors	k-近鄰演算法
sklearn.naive_bayes      貝葉斯
sklearn.linear_model.LogisticRegression     邏輯迴歸

2、用於迴歸的估計器:

sklearn.linear_model.LinearRegression     線性迴歸
sklearn.linear_model.Ridge      嶺迴歸 

估計器的工作流程

#分類演算法-k近鄰演算法

定義: 如果一個樣本在特徵空間中的k個最相似(即特徵空間中最鄰近)的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別。

來源: KNN演算法最早是由Cover和Hart提出的一種分類演算法

計算距離公式:
兩個樣本的距離可以通過如下公式計算,又叫歐式距離。比如說,a(a1,a2,a3),b(b1,b2,b3)

sklearn k-近鄰演算法API

from sklearn.neighbors import KNeighborsClassifier(n_neighbors=5,algorithm='auto')
	
	#n_neighbors:int,可選(預設= 5),k_neighbors查詢預設使用的鄰居數 
	#algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可選用於計算最近鄰居的演算法:‘ball_tree’將會使用 BallTree,‘kd_tree’將使用 KDTree。‘auto’將嘗試根據傳遞給fit方法的值來決定最合適的演算法。 (不同實現方式影響效率)

實列流程

資料的處理

1、縮小資料集範圍(a>1&a<2)
DataFrame.query()

2、處理日期資料,轉化為時間序列
pd.to_datetime (data[‘time’],unit=‘s’)
pd.DatetimeIndex #時間序列轉化為dataframe型別

3、增加分割的日期資料

4、刪除沒用的日期資料
pd.drop

5、將簽到位置少於n個使用者的刪除
place_count =data.groupby(‘place_id’).aggregate(np.count_nonzero)
tf = place_count[place_count.row_id > 3].reset_index()
data = data[data[‘place_id’].isin(tf.place_id)]

2、分割資料集

#進行資料的分割訓練集和測試集
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)

3、對資料集進行標準化

#特徵工程(標準化)
std=StandardScaler()

#對測試集和訓練集進行標準化
x_train = std.fit_transform(x_train)
x_test=std.transform(x_test)

4、estimator流程進行分類預測

#進行演算法流程
knn=KNeighborsClassifier()
knn.fit(x_train,y_train)

#得出預測結果
y_predict=knn.predict(x_test)
print('預測的目標值簽到位置為:\n',y_predict)

#得出準確率
print("預測的準確率\n",knn.score(x_test,y_test))

交叉驗證

#構造一些引數
param = {'n_neighbors':[3,5,10]}

#進行網格搜尋
gc = GridSearchCV(knn,param_grid=param,cv = 2)
gc.fit(x_train,y_train)

#預測準確率
print('在測試集上準確率:', gc.score(x_test,y_test))
print('在交叉驗證當中最好的結果:', gc.best_score_)
print('選擇最好的模型是:',gc.best_estimator_)
print('每個超引數每次交叉驗證的結果是:',gc.cv_results_)

k近鄰演算法例項-預測入住位置

def knn():
    """
    knn演算法
    :return:
    """
    #讀取資料
    data=pd.read_csv(r"E:\QQ\Download\File\day2\train.csv")
    #取出規定範圍的資料(縮小資料範圍)
    print(data)
    data=data.query("0<x&x<1.0&y>1.0&y<2.0")
    # data = data.query("x > 1.0 &  x < 1.25 & y > 2.5 & y < 2.75")

    #處理時間資料
    time_value=pd.to_datetime(data["time"],unit="s")

    # 把日期格式轉化成字典格式
    time_value = pd.DatetimeIndex(time_value)

    #構造一些特徵
    data['day']=time_value.day
    data['hour'] = time_value.hour
    data['weekday'] = time_value.weekday

    #把時間戳資料刪除
    data = data.drop(['time'],axis=1)
    # print(data)

    #把標籤減少至n的位置(只要>n的資料)
    place_count=data.groupby(by='place_id').count()
    tf=place_count[place_count.row_id>3].reset_index()
    data=data[data['place_id'].isin(tf.place_id)]
    print(tf)

    # 取出資料中發特徵值和目標值
    y = data["place_id"]
    x = data.drop(["place_id"], axis=1)


    #進行資料的分割訓練集和測試集
    x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)

    #特徵工程(標準化)
    std=StandardScaler()

    #對測試集和訓練集進行標準化
    x_train = std.fit_transform(x_train)
    x_test=std.transform(x_test)

    #進行演算法流程
    knn=KNeighborsClassifier()
    knn.fit(x_train,y_train)

    #得出預測結果
    y_predict=knn.predict(x_test)
    print('預測的目標值簽到位置為:\n',y_predict)

    #得出準確率
    print("預測的準確率\n",knn.score(x_test,y_test))
##交叉驗證
    #構造一些引數
    param = {'n_neighbors':[3,5,10]}

    #進行網格搜尋
    gc = GridSearchCV(knn,param_grid=param,cv = 2)
    gc.fit(x_train,y_train)

    #預測準確率
    print('在測試集上準確率:', gc.score(x_test,y_test))
    print('在交叉驗證當中最好的結果:', gc.best_score_)
    print('選擇最好的模型是:',gc.best_estimator_)
    print('每個超引數每次交叉驗證的結果是:',gc.cv_results_)
if __name__ == '__main__':
    knn()

問題

k值取很小:容易受異常點影響
k值取很大:容易受最近資料太多導致比例變化

優缺點

優點:
簡單,易於理解,易於實現,無需估計引數,無需訓練
缺點:
懶惰演算法,對測試樣本分類時的計算量大,記憶體開銷大
必須指定K值,K值選擇不當則分類精度不能保證
**應用場景:**小資料場景,幾千~幾萬樣本,具體場景具體業務
去測試

4、分類評估之混淆矩陣

其他分類標準,F1-score,反映了模型的穩健型

分類模型評估API

from sklearn.metrics import classification_report
	
sklearn.metrics.classification_report(y_true, y_pred, target_names=None)
	#y_true:真實目標值		y_pred:估計器預測目標值
	#target_names:目標類別名稱   return:每個類別精確率與召回率

5、分類演算法-樸素貝葉斯演算法

概率基礎: 概率定義為一件事情發生的可能性

###聯合概率和條件概率
聯合概率: 包含多個條件,且所有條件同時成立的概率

記作:p(A,B)

條件概率:就是事件A在另外一個事件B已經發生條件下的發生概率

記作:p(A|B)

特性:P(A1,A2|B) = P(A1|B)P(A2|B)
注意:此條件概率的成立,是由於A1,A2相互獨立的結果
##樸素貝葉斯-貝葉斯公式

拉普拉斯平滑係數

sklearn樸素貝葉斯實現API

from sklearn.naive_bayes import MultinomialNB

sk=sklearn.naive_bayes.MultinomialNB(alpha = 1.0)
#例項化樸素貝葉斯分類	alpha:拉普拉斯平滑係數(基本為1)

樸素貝葉斯的優缺點

優點:
樸素貝葉斯模型發源於古典數學理論,有穩定的分類效率。對缺失資料不太敏感,演算法也比較簡單,常用於文字分類。分類準確度高,速度快。

缺點:
需要知道先驗概率P(F1,F2,…|C),因此在某些時候會由於假設的先驗
模型的原因導致預測效果不佳。
#6、樸素貝葉斯演算法例項
def news():
“”"
樸素貝葉斯演算法預測:
:return:
“”"
news=fetch_20newsgroups(subset=‘all’)
# print(news.data)

    #進行資料分割 (20篇文章3:1分為訓練集,測試集)
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.25)

    # 對資料集進行特徵抽取
    tf = TfidfVectorizer()

    # 以訓練集當中的詞的列表進行每篇文章重要性統計['a','b','c','d']
    x_train = tf.fit_transform(x_train)

    # print(tf.get_feature_names())

    x_test = tf.transform(x_test)

    # 進行樸素貝葉斯演算法的預測
    mlt = MultinomialNB(alpha=1.0)
    print(x_train.toarray())

    mlt.fit(x_train, y_train)

    y_predict = mlt.predict(x_test)

    print("預測的文章類別為:", y_predict)

    # 得出準確率
    print("準確率為:", mlt.score(x_test, y_test))

    print("每個類別的精確率和召回率:", classification_report(y_test, y_predict, target_names=news.target_names))

    return None

7、模型的選擇與調優

交叉驗證:為了讓被評估的模型更加準確可信
##1、交叉驗證
**交叉驗證:**將拿到的資料,分為訓練和驗證集。以下圖為例:將資料分
成5份,其中一份作為驗證集。然後經過5次(組)的測試,每次都更換不同
的驗證集。即得到5組模型的結果,取平均值作為最終結果。又稱5折交叉
驗證

2、超引數搜尋-網格搜尋

通常情況下,有很多引數是需要手動指定的(如k-近鄰演算法中的K值),
這種叫超引數。但是手動過程繁雜,所以需要對模型預設幾種超引數組
合。每組超引數都採用交叉驗證來進行評估。最後選出最優引數組合建
立模型。

sklearn.model_selection.GridSearchCV

from sklearn.model_selection import GridSearchCV

sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
對估計器的指定引數值進行詳盡搜尋

estimator:估計器物件
param_grid:估計器引數(dict){“n_neighbors”:[1,3,5]}
cv:指定幾折交叉驗證
fit:輸入訓練資料
score:準確率
結果分析:
best_score_:在交叉驗證中測試的最好結果
best_estimator_:最好的引數模型
cv_results_:每次交叉驗證後的測試集準確率結果和訓練集準確率結果

8、決策樹與隨機森林