什么時候用K近鄰?
交叉驗證的時候。最常見的交叉驗證方法是K折交叉驗證,其中數據集被均勻分成K個子集,稱為折,然后執行K次訓練和測試,每次選擇不同的折作為測試集,其余的作為訓練集。最后,將K次測試結果的平均值作為模型的性能指標。
什么叫交叉驗證?
交叉驗證是一種常用的模型評估技術,用于評估機器學習模型的性能和泛化能力。在機器學習中,我們通常希望評估訓練好的模型對未見過數據的表現情況,以確保模型可以泛化到新的數據上。
交叉驗證的基本思想?
交叉驗證的基本思想是將原始數據集分成若干個子集,然后進行多輪訓練和測試。在每一輪中,選擇一個子集作為測試集,其余子集作為訓練集,然后訓練模型并在測試集上進行評估。
交叉驗證的子集會重復使用嗎?
當K等于原始數據集大小時,這種交叉驗證方法稱為留一法(Leave-One-Out,簡稱LOO),即每個樣本都被用作測試集一次,其余樣本用于訓練模型。在這種情況下,子集不會重復使用。但是,LOO計算代價較高,并且可能過度擬合訓練數據,因此通常不是首選的交叉驗證方法。總之,交叉驗證中的子集會重復使用,以確保我們可以評估模型在不同數據集上的性能,并減少因數據集劃分不合理而引入的偶然性。
K近鄰通常用哪些頭文件?
# 導入pandas和numpy庫
import pandas as pd
import numpy as np
# 導入sklearn庫中的KNeighborsClassifier
from sklearn.neighbors import KNeighborsClassifier
# 導入os庫
import os
# 導入sklearn庫中的GridSearchCV
from sklearn.model_selection import GridSearchCV
K近鄰的頭文件都是什么,都有什么用?
第一、二行:
數據處理庫pandas和科學計算庫numpy。通過這兩個庫,您可以進行各種數據操作和分析。一般來說,習慣上將pandas重命名為pd,numpy重命名為np,以方便在代碼中使用。導入這兩個庫后,您可以使用它們提供的函數和方法進行數據讀取、數據處理、數據分析等操作。例如,使用pandas的read_csv()函數讀取CSV文件,使用numpy的array()函數創建數組等。
第三行:
from sklearn.neighbors import KNeighborsClassifier
: 這一行代碼導入了scikit-learn庫中的KNeighborsClassifier類。K近鄰分類器是一種基于實例的學習算法,通過基于最近鄰居的投票來進行分類。
第四行:
import os
: 這一行代碼導入了Python的os模塊,用于與操作系統進行交互,例如獲取文件路徑、創建目錄等操作。
第五行:
from sklearn.model_selection import GridSearchCV
: 這一行代碼導入了scikit-learn庫中的GridSearchCV類。GridSearchCV是一種用于自動化調優模型參數的方法,它會自動嘗試不同的參數組合,并選擇最佳參數組合以獲得最佳模型性能。
綜上所述:
這幾個導入語句主要用于機器學習中的分類任務和參數調優操作。其中,KNeighborsClassifier用于構建K近鄰分類器模型,os模塊用于與操作系統進行交互,GridSearchCV用于自動化調優模型參數。這些工具可以幫助您更方便地進行機器學習模型的開發和優化。
具體案例-手寫數字識別:
# 導入pandas和numpy庫
import pandas as pd
import numpy as np
# 導入sklearn庫中的KNeighborsClassifier
from sklearn.neighbors import KNeighborsClassifier
# 導入os庫
import os
# 導入sklearn庫中的GridSearchCV
from sklearn.model_selection import GridSearchCV# 獲取訓練數據路徑
Train_data_path = os.listdir("./digits/trainingDigits") # os.listdir返回的是目錄中所有的文件和文件夾的名稱,而不包括子目錄中的內容。
# 初始化訓練集X和Y
Train_X = []
Train_Y = []
# 遍歷訓練數據路徑
for data_file in Train_data_path:# 獲取訓練數據標簽data_file.split("_")# data_file.split("_")會將文件名按照"_"進行分割,得到一個由多個字符串組成的列表,如["digit", "0.txt"]。# 通過索引[0]取出列表中的第一個元素"digit",即數據文件對應的標簽部分。# Train_Y.append() 將提取出的標簽部分添加到 Train_Y 列表中。這樣,每次執行這段代碼,Train_Y 列表都會逐步積累包含各個數據文件標簽的元素。最終 Train_Y 列表可能會包含類似 ["digit", "digit", ...] 的內容,其中每個元素對應一個數據文件的標簽信息。Train_Y.append(data_file.split("_")[0])# 打開訓練數據文件with open(f"./digits/trainingDigits/{data_file}", "r") as f: # 建議別用open,用numpy.load(),因為老師真的會噴# 讀取訓練數據num = f.read().replace("\n", '') # 將無敵的換行符替換為空字符串,并所有數據轉化為一個很長的字符串# 初始化xx = []# 遍歷訓練數據for i in num:# 將訓練數據轉換為整數x.append(int(i)) # x 列表中包含了訓練數據中每個數字所對應的像素點信息,這些信息都以整數形式存儲在列表中# 將x添加到訓練集X中Train_X.append(x) # 通過添加操作,我們可以將所有的訓練數據都存儲在 Train_X 列表中,并且可以通過索引訪問列表中的每個子列表來獲取對應數字的像素點信息。# 打印x# print(x)# 打印x的長度# print(len(x))# 獲取測試數據路徑
Test_data_path = os.listdir("./digits/testDigits")
# 初始化測試集X和Y
Test_X = []
Test_Y = []
# 遍歷測試數據路徑
for data_file in Test_data_path:# 獲取測試數據標簽Test_Y.append(data_file.split("_")[0])# 打開測試數據文件with open(f"./digits/TestDigits/{data_file}", "r") as f:# 讀取測試數據num = f.read().replace("\n", '')# 初始化xx = []# 遍歷測試數據for i in num:# 將測試數據轉換為整數x.append(int(i))# 將x添加到測試集X中Test_X.append(x)# 打印x# print(x)# 打印x的長度# print(len(x))# 定義參數網格
# list(range(1, 12)) 是一個列表,包含了從 1 到 11(不包括 12)的整數。這個列表是作為字典的值存儲的,表示 K最近鄰(K-Nearest Neighbors,KNN)需要測試的鄰居數的范圍。range(1, 12) 包含了從 1 到 11 的整數,因此 KNN 算法將會嘗試從 1 到 11 的不同鄰居數,來確定最佳的鄰居數。也就是說,算法將會嘗試使用 1 個鄰居、2 個鄰居、3 個鄰居......直到 11 個鄰居來進行分類。
param_grid = {'n_neighbors': list(range(1, 12))}
# 初始化KNeighborsClassifier
clf = KNeighborsClassifier() # 創建了一個 KNN(K-最近鄰)分類器對象
# 使用GridSearchCV對KNeighborsClassifier進行參數搜索
# GridSearchCV 是 sklearn 庫中用于執行網格搜索和交叉驗證的類。它接受三個參數:
# clf:要使用的分類器對象,這里傳入了之前創建的 KNN 分類器對象 clf。
# param_grid:一個字典,表示要搜索的參數空間。這里傳入了之前定義的 param_grid 字典,用于指定 KNN 算法中的鄰居數的范圍。
# cv:整數或交叉驗證迭代器,表示進行交叉驗證的折數。這里設置為 10,表示使用 10 折交叉驗證。老登說10折好用,有理論基礎。
GS_model = GridSearchCV(clf, param_grid, cv=10)
# 對訓練集進行參數搜索
GS_model.fit(Train_X, Train_Y)
# 打印最優參數和最優配置
# GS_model.best_params_:最佳的鄰居數
# GS_model.best_score_:模型在訓練數據集上分類正確的比例
print(f'模型的最優參數最優配置為{GS_model.best_params_},且訓練精度為{GS_model.best_score_:.3f}')# 初始化最優模型
# 創建了一個 K 最近鄰分類器(KNeighborsClassifier)的實例 Best_model,并使用了之前通過網格搜索得到的最佳參數配置中的最優鄰居數量 'n_neighbors' 來初始化這個分類器。
Best_model = KNeighborsClassifier(GS_model.best_params_['n_neighbors'])
# 對訓練集進行訓練
Best_model.fit(Train_X, Train_Y)
# 計算測試集的分類精度
score = Best_model.score(Test_X, Test_Y)
# 打印測試集的分類精度
print(f'交叉驗證得到模型的測試分類精度為{score:.3f}')
# 這段代碼使用了一個循環來嘗試不同的K值,然后訓練KNN模型并輸出每個K值對應的預測得分。這種方法可以幫助你找到最適合數據集的K值,從而提高模型的性能。在循環中,首先創建了一個KNN模型,并使用當前的K值進行初始化。然后,使用訓練數據對模型進行訓練,并計算模型在測試數據上的得分。最終,打印出每個K值對應的模型得分。通過這種方式,你可以比較不同K值下模型的性能表現,以便選擇最佳的K值來構建最終的KNN模型。
# for i in range(1,11):
# model = KNeighborsClassifier(i)
# model.fit(Train_X,Train_Y)
# print(f"當K等于{i}時模型預測得分為:",model.score(Test_X,Test_Y))# K最近鄰(K-Nearest Neighbors,KNN)算法是一種常用的監督學習方法,用于解決分類和回歸問題。在KNN算法中,對于一個給定的未知數據點,根據其在特征空間中與其他已知數據點的距離來進行分類或回歸預測。KNN算法的基本思想是,如果一個樣本在特征空間中的k個最近鄰中的大多數屬于某個類別,則該樣本也屬于這個類別。在分類問題中,KNN算法會將未知數據點分配給與其最近鄰居所屬類別相同的類;在回歸問題中,KNN算法會根據最近鄰居的值來預測未知數據點的數值。KNN算法的優點之一是簡單易理解,易于實現。然而,KNN算法的缺點包括對大規模數據集的計算成本較高,以及在處理高維數據時可能受到“維度災難”的影響。在實際應用中,可以通過交叉驗證等方法來選擇最佳的K值,以及使用特征縮放等技術來提高KNN算法的性能。
結果:
有點小尬,但確實精度提高了,可能這個數據比較符合兩種算法吧
讓我們看一下下一個案例-海倫K近鄰的頭文件:
import pandas as pd
import numpy as np
from sklearn.model_selection import GridSearchCV
from sklearn import preprocessing
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
上面的頭文件都是干嘛的呀?
pandas:pandas是一個數據處理和分析的庫,提供了高效的數據結構和數據分析工具。通過pandas,你可以輕松地讀取、處理和操作數據,例如加載數據集、數據清洗、特征選擇等。
numpy:numpy是Python中用于科學計算的一個核心庫,提供了高性能的多維數組對象和各種數學函數。在機器學習中,常使用numpy來處理和操作數組數據,例如矩陣運算、向量化操作等。
sklearn.model_selection.GridSearchCV:GridSearchCV是scikit-learn(sklearn)庫中的一個模型選擇工具,用于通過交叉驗證來調整模型的超參數。通過GridSearchCV,你可以定義一個參數網格,它會自動嘗試不同參數組合,并選擇最佳的參數配置。
sklearn.preprocessing:sklearn.preprocessing是scikit-learn庫中的一個數據預處理模塊,提供了一系列用于數據預處理的函數和類。這些函數和類可以用來對數據進行縮放、歸一化、標準化等操作,以便更好地適應機器學習模型的要求。
sklearn.neighbors.KNeighborsClassifier:KNeighborsClassifier是scikit-learn中的一個K近鄰分類器模型。它是基于最近鄰算法的一種分類器,用于解決分類問題。KNeighborsClassifier可以根據鄰居的類別來預測未知數據點的類別,并具有簡單易用的接口。
sklearn.model_selection模塊中的cross_val_score函數用于執行交叉驗證并計算模型的評分。它可以幫助你評估機器學習模型的性能。
對了,說句題外話,crtl+z撤銷,ctrl+shift+z還原
批量注釋:ctrl+/ ,取消批量注釋: ctrl+/
批量縮進:tab ,取消批量縮進:shift+tab
import pandas as pd
import numpy as np
from sklearn.model_selection import GridSearchCV
from sklearn import preprocessing
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score# 讀取數據
df = pd.read_csv("datingTestSet.txt", sep="\t",names=['每年獲得的飛行常客里程數', '視頻游戲所耗時間百分比', '每周消費的冰淇淋公升數', '喜愛程度'])
# print(df.head())#使用df.head()函數來查看數據集的前幾行,以確保數據已正確加載。
# 將最后一列數據進行歸一化處理
X = preprocessing.MinMaxScaler().fit_transform(df.iloc[:, :-1])
# iloc函數是pandas庫中用于按照位置索引選取數據的函數。
Y = df.iloc[:, -1]
# 定義參數網格
param_grid = {'n_neighbors': np.arange(1, 10,1)} # param_grid定義了一個名為n_neighbors的超參數,它是KNN算法中k值(即最近鄰居數)的取值范圍。具體來說,np.arange(1, 10, 1)函數生成了一個從1到9的整數序列,其中步長為1,作為n_neighbors超參數的所有可能取值。也就是說,我們將在這個范圍內尋找最佳的k值,以獲得最好的模型性能。
# 定義KNN模型
clf = KNeighborsClassifier()
# 使用網格搜索模型
GS_model = GridSearchCV(clf, param_grid, cv=10)
# 訓練模型
GS_model.fit(X, Y)
# 輸出模型的最優參數最優配置以及訓練精度
print(f'模型的最優參數最優配置為{GS_model.best_params_},且訓練精度為{GS_model.best_score_:.3f}')Max_score = 0.0
# 定義KNN模型,找到最佳的K值
for K in range(1, 11):model = KNeighborsClassifier(K)model.fit(X, Y)# 十折驗證 #求出其10折平均值score = cross_val_score(model, X, Y, cv=10).mean()if Max_score < score:Max_score = scoreBest_K = K
print("最好的K值為:", Best_K, "平均得分為:", Max_score)# 定義KNN模型
model = KNeighborsClassifier(Best_K)
# 訓練模型
model.fit(X, Y)
# 測試樣例
print(model.predict([[0.33193158, 0.41660188,0.24523407]])) # 輸出結果['largeDoses']表示模型對輸入的樣本[0.33193158, 0.41660188, 0.24523407]進行了分類預測,并將其歸類為"largeDoses"。在一些分類問題中,類別可能被編碼為字符串形式,而不是數值。類別的具體含義取決于你的具體應用場景。例如,在某個社交網絡應用中,"largeDoses"可能代表用戶對某種活動的興趣程度;在醫療診斷中,"largeDoses"可能代表患者疾病的嚴重程度等等。# 使用fit_transform函數進行擬合和轉換操作。在擬合過程中,它會根據數據集中的最小值和最大值來計算每個特征的轉換規則,然后將數據按照這些規則進行轉換。具體地,它會將數據縮放到給定的特征范圍內,通常是0到1之間。這個函數的作用是將數據集進行歸一化,使得不同特征的取值范圍都在相同的尺度上,避免了某些特征由于數值范圍的差異而對建模產生較大的影響。這樣,在進行后續的機器學習模型訓練時,各個特征的權重更平衡,提高了模型的穩定性和準確性。總結起來,fit_transform函數的作用就是對數據進行歸一化處理,并返回歸一化后的結果。# 這段代碼會報錯,添加for item in s.items(),通過使用items()函數,你可以避免未來版本中對iteritems()函數的移除所帶來的問題。
結果:
上下代碼是一樣的,上面是學生寫的,下面是老登寫的