機器學習的演算法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_:每次交叉驗證後的測試集準確率結果和訓練集準確率結果