定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别
计算距离公式:利用欧式距离定义 ( a 1 − b 1 ) 2 + . . . + ( a n − b n ) 2 \sqrt{(a_1-b_1)^2+...+(a_n-b_n)^2} (a1−b1)2+...+(an−bn)2
由上述公式可看出k近邻算法需要进行标准化处理
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors = 5)
knn.fit(x_train, y_train)
y_predict = knn.predict(x_test) # 根据测试集得出预测结果
knn.score(x_test, y_test) # 根据测试集得出准确率
算法分析
1、优点:简单,易于理解,易于实现,无需估计参数,无需训练
2、缺点:懒惰算法,对测试样本分类时的计算量大,内存开销大;必须指定K值,K值选择不当则分类精度不能保证
3、使用场景:小数据场景,几千~几万样本,具体场景具体业务去测试
贝叶斯公式: P ( C ∣ W ) = P ( W ∣ C ) P ( C ) P ( W ) P(C|W) = \frac{P(W|C)P(C)}{P(W)} P(C∣W)=P(W)P(W∣C)P(C)
注:W为给定文档的特征值(频数统计,预测文档提供),C为文档类别
计算出每个类别的后验概率,选取概率最大的作为其类别。
计算方法: P ( F 1 │ C ) = N i / N P(F_1│C)=N_i/N P(F1│C)=Ni/N (训练文档中去计算, N i N_i Ni为该 F 1 F_1 F1词在C类别所有文档中出现的次数,N为所属类别C下的文档所有词出现的次数和, P ( F 1 , F 2 , . . . ) P(F_1,F_2,...) P(F1,F2,...):预测文档中每个词的概率。
问题:有时得到一些类别的概率为0,这是不合理的,如果词频列表里面有很多出现次数都为0,很可能计算结果都为零。
解决办法:拉普拉斯平滑系数
P ( F 1 ∣ C ) = N i + α N + α m P(F_1|C)=\frac{N_i+\alpha}{N+\alpha m} P(F1∣C)=N+αmNi+α, α \alpha α为指定的系数,一般取为1,m为训练文档中统计出的特征词个数。
sklearn朴素贝叶斯实现API:sklearn.naive_bayes.MultinomialNB
from sklearn.naive_bayes import MultinomialNB
news = fetch_20newsgroups(subset='all') # 导入数据集
# 进行数据集分割
x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.25)
# 对数据集进行特征抽取
tf = TfidfVectorizer()
# 以训练集当中的词的列表进行每篇文章重要性统计
x_train = tf.fit_transform(x_train)
x_test = tf.transform(x_test)
# 进行朴素贝叶斯算法的预测
mlt = MultinomialNB(alpha=1.0)
mlt.fit(x_train, y_train)
y_predict = mlt.predict(x_test)
mlt.score(x_test, y_test)
算法分析
精确率:预测结果为正例样本中真实为正例的比例(查得准)
召回率:真实为正例的样本中预测结果为正例的比例(查的全,对正样本的区分能力)
分类模型评估API:sklearn.metrics.classification_report
from sklearn.metrics import classification_report
print(classification_report(y_test, y_predict, target_names=news.target_names))
交叉验证:为了让被评估的模型更加准确可信。
交叉验证过程:将拿到的数据,分为训练和验证集。例如将数据分成5份,其中一份作为验证集。然后经过5次(组)的测试,每次都更换不同的验证集。即得到5组模型的结果,取平均值作为最终结果。又称5折交叉验证。
网格搜索:通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。
网格搜索API:sklearn.model_selection.GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
knn = KNeighborsClassifier()
# 构造一些参数的值进行搜索
param = {"n_neighbors": [3, 5, 10]}
# 进行网格搜索
gc = GridSearchCV(knn, param_grid=param, cv=10)
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_)