機器學習 使用交叉驗證為KNN調優引數
阿新 • • 發佈:2018-12-24
# KNN的距離演算法 使用的是歐氏距離 即算空間中點的距離 (根號下的 差的平方和) # 要注意的是knn演算法是需要做 標準化處理的 # API:(引數:n_neighbors=5)預設使用5個鄰居 鄰居的數量對演算法的結果有影響 數量越大則要判斷的點越多 from sklearn.neighbors import KNeighborsClassifier import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # 網格引數最優搜尋 from sklearn.model_selection import GridSearchCV def knncls(): data = pd.read_csv("./data/facebook/train.csv") # 處理資料 print(data.head(10)) # 縮小資料集 # 使用query查詢資料篩選資料 輸入字串 用& 表示與 data = data.query("x>1.0 & x<1.25 &y>2.5 & y <2.75") # 處理時間戳 轉換成年月日 時分秒 # 呼叫pd.to_datatime() 可以吧時間戳轉換為時間年月日 time_values = pd.to_datetime(data['time']) print(time_values) # 構造更多的特徵 年月都一致 不再使用年月 # 獲取引數 使用打他timeindex time_values = pd.DatetimeIndex(time_values) data['day'] = time_values.day data['hour'] = time_values.hour data['weekday'] = time_values.weekday data['weekday'] = time_values.weekday # 刪除時間戳特徵 # 第一個引數是一個列表 傳入要刪除的特徵lable 第二個引數表示軸 在sklearn裡邊0 代表列 # 而在pandas裡邊 1 表示列 data = data.drop(['time'], axis=1) print('*' * 100) print(data) # 簽到數 比較少的 篩選掉 # 即簽到數量少於n place_count = data.groupby("place_id").count() tf = place_count[place_count.row_id > 3].reset_index() # 篩選在tf裡邊的place data = data[data['place_id'].isin(tf.place_id)] # 區分資料中的目標值 特徵值 y = data['place_id'] x = data.drop(['place_id'], axis=1) # 進行資料分割 (訓練集 測試集) # 引數說明 特徵值 目標值 測試集百分比 # 注意返回順序 X_train, X_test, Y_train, Y_test = train_test_split(x, y, 0.25) # 特徵工程 標準化(不做標準化 準確率大概在 3% ) # 測試集 訓練集 的特徵值都需要標準化 std = StandardScaler() X_train = std.fit_transform(X_train) # 不用再呼叫fit_transform 已經標準化了一次 X_test = std.transform(X_test) # 標準化之後準確率大概為 40% # 進行演算法流程 knn = KNeighborsClassifier() # 構造一些引數的值給它搜尋使用 param = {"n_neighbors":[1,3,5,10]} # 網格引數優化 gc = GridSearchCV(knn,param_grid=param,cv=2) # 輸入資料 gc.fit(X_train, Y_train) # 得出預測結果(測試集) y_predict = gc.predict(X_test) print("在交叉驗證中最好的驗證結果\n",gc.best_score_) print("在交叉驗證中最好的模型",gc.best_estimator_) print("每個超引數每次交叉驗證的結果\n",gc.cv_results_) return None if __name__ == '__main__': knncls()