一、k近邻算法(KNN)
1.1 定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
1.2 理解:KNN是通过距离间隔的分类算法,通过对每个样本之间的差异大小来对比,选取其中最近的几个(需要自己根据数据集确定)距离,按这几个数据的类别百分比确认最终预测分类。 这就要对高等数学中的距离公式熟悉掌握
1.3 距离公式:√(a1−b1)^2+(a2−b2)^2+(a3−b3)^2
1.4 sklearn k-近邻算法API
sklearn.neighbors.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.5 对数据集的处理
1.5.1 缩小数据集范围【DataFrame.query()】
切割数据集,类似于sql语句,参数为条件语句
eg: data.query("x > 1.0 & x < 1.25 & y > 2.5 & y < 2.75")
1.5.2 处理日期数据
pd.to_datetime()传入需要转化的位置和转化单位(unit)
eg:pd.to_datetime(data['time'], unit='s')
pd.DatetimeIndex()把日期格式转化为字典格式
1.5.3 删除没用的日期数据(pd.drop)
1.5.4 将签到位置少于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)]
1.6 k-近邻算法优缺点
优点: 简单,易于理解,易于实现,无需估计参数,无需训练
缺点: 懒惰算法,对测试样本分类时的计算量大,内存开销大 必须指定K值,K值选择不当则分类精度不能保证
1.7 使用场景
小数据场景,几千~几万样本,具体场景具体业务 去测试
二、 分类模型的评估
2.1 estimator.score() 一般最常见使用的是准确率,即预测结果正确的百分比
2.2 混淆矩阵
在分类任务下,预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合,构成混淆矩阵(适用于多分类)
2.3 Api
sklearn.metrics.classification_report
sklearn.metrics.classification_report(y_true, y_pred, target_names=None)
y_true:真实目标值
y_pred:估计器预测目标值
target_names:目标类别名称
return:每个类别精确率与召回率
三、 朴素贝叶斯模型
优点:朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。
对缺失数据不太敏感,算法也比较简单,常用于文本分类。
分类准确度高,速度快
缺点:需要知道先验概率P(F1,F2,…|C),因此在某些时候会由于假设的先验模型的原因导致预测效果不理想。
四、模型的选择与调优
4.1、交叉验证
4.1.1 目的:为了让被评估的模型更加准确可信
4.1.2 过程:交叉验证:将拿到的数据,分为训练和验证集。将数据分成5份,其中一份作为验证集。然后经过5次(组)的测试,每次都更换不同 的验证集。即得到5组模型的结果,取平均值作为最终结果。又称5折交叉 验证。
4.2、网格搜索
4.2.1 定义:通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值), 这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组 合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建 立模型。
4.2.2 API
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_:每次交
from sklearn.datasets import load_iris, fetch_20newsgroups, load_boston from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier from sklearn.feature_extraction.text import TfidfVectorizer import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.naive_bayes import MultinomialNB def knncls(): """ k-近邻 :return: None """ # 读取数据 data = pd.read_csv("./data/train.csv") # print(data.head()) # 处理数据 # 1、缩小数据(根据条件缩小范围) data = data.query("x > 1.0 & x < 1.25 & y > 2.5 & y < 2.75") # 2、处理时间数据 time_value = pd.to_datetime(data['time'], unit='s') # print(time_values.head()) # 把日期格式转化为字典格式 time_values = pd.DatetimeIndex(time_value) # 3、构造特征 data['day'] = time_values.day data['hour'] = time_values.hour data['weekday'] = time_values.weekday # 删除时间戳特征 data = data.drop(['time'], axis=1) # sklearn中列为0,pandas中列为1 # data = data.drop(['row_id'], axis=1) print(data.head()) # 把签到数量小于n个目标位置删除 place_count = data.groupby('place_id').count() tf = place_count[place_count.row_id > 3].reset_index() 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, test_size=0.25) # 特征工程(标准化) std = StandardScaler() # 对测试集和训练集的特征值进行标准化 x_train = std.fit_transform(x_train) x_test = std.transform(x_test) # 算法 knn = KNeighborsClassifier(n_neighbors=5) # fit, predict, score knn.fit(x_train, y_train) # 得出预测结果 x_predict = knn.predict(x_test) print(x_predict) # 得出准确率 print("预测的准确率:", knn.score(x_test, y_test)) return None def naviebayes(): """ 朴素贝叶斯进行文本分类 :return:None """ 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) print(mlt.score(x_test, y_test)) if __name__ == "__main__": naviebayes()
叉验证后的测试集准确率结果和训练集准确率结果