KNN算法的思想: 如果一个吸烟者70岁得了肺癌 ,另一个吸烟者69岁得了肺癌,且大多吸烟者这个时间段可能有肺癌风险。那么有个样本 68岁的吸烟者也很有可能近期会得肺癌。KNN就是找身边最相似的东西,进而进行预测。
1.首先获取IBM员工数据集:
首先登录天池大数据平台,里面有一个 天池实验室--数据集--公共数据中 有一个 IBM员工离职数据集
具体 链接为 : https://tianchi.aliyun.com/dataset/dataDetail?dataId=77180
2.对字段(特征)进行分析:
这里的字段实在太多,因为初学KNN,我们使用其中的几个字段(特征)就好了
这里我们使用
age:年龄字段
bussinessTravel : 是否经常出差
DistanceFromHome: 距离
Education:教育程度
gender: 性别
joblevel: 工作等级
MonthlyIncome : 员工月收入
numcompanies: 曾经工作过公司数量
这8个字段来进行预测 是否离职 attrition字段表示 是否离职
(也就是说,我们用这8个字段来预测 attrition字段)
并且我们统一 Department字段 为 Research & Development ( Research & Development表示研发部门)
在这个数据集中,一共有 1400多条数据集
我们在 Department字段为Research & Development 中 选取90 条为 训练集,选取10条作为数据集
因为这里选取了8个字段 ,一般数据集为 k的平方比较好 (一些大佬说的,我也不太明白)
3.进行数据清洗
这里有1400多条数据的30多个特征 ,我们只需要100条数据 8-9个特征就好了
所以需要删除多余的行和列
代码如下:
import pandas as pd
xdate=pd.read_csv('WA_Fn-UseC_-HR-Employee-Attrition.csv') # i
# xdate.sort_values(by='Department') # 按列排序,没啥用
df=xdate
df = df.drop(df[df.Department!= 'Research & Development'].index)# 首先删除部门不是 研究部 的行
need_list=[ # 需要保留的字段合集
'Age',
'Attrition',
'BusinessTravel',
'DistanceFromHome',
'Education',
'JobLevel',
'NumCompaniesWorked',
'MonthlyIncome',
'Gender']
delete_list=[] # 需要删除的列表
for i in df:
if i not in need_list:
delete_list.append(i)
df.drop(labels=delete_list,axis=1,inplace=True) # 删除没用的列
print(len(df))
df = df.head(100) # 取前100行
alldate=df # 所有数据集
alldate.to_csv('alldate.csv') # 保存成csv 文件
4.将 文本数据 转成 数学数据
for index in alldate['BusinessTravel'].index:
value=alldate['BusinessTravel'].get(index)
if value =='Travel_Frequently':
alldate['BusinessTravel'][index]=2
elif value == 'Travel_Rarely':
alldate['BusinessTravel'][index]=1
else:
alldate['BusinessTravel'][index]=0 # 把BussinessTravel字段的 频繁出差转成 2 很少转1,不出差转 0
for index in alldate['Gender'].index:
value=alldate['Gender'].get(index)
if value=='Male':
alldate['Gender'][index]=1
else:
alldate['Gender'][index]=0 # 把gender字段 male转成0, female转0
alldate.to_csv('alldate_1.csv')
5.先保存一部分数据
train = alldate.head(90) # 前90行为训练集
train_y = train['Attrition'] # train_y 为我们需要预测的字段 (该字段表示是否离职)
train_x = train.drop('Attrition',axis=1) # train_x 为预存Attrition 所需要的特征
train_y.to_csv('train_y.csv')
train_x.to_csv('train_x.csv')
test = alldate.tail(10) # 后10行为测试集
test_y = test['Attrition'] # test_y 为 我们通过 test_x 和 train_x 预测是否离职 和实际数据对比
test_x = test.drop('Attrition',axis=1)
test_y.to_csv('test_y.csv')
test_x.to_csv('test_x.csv')
6.数据标准化
如果不标准化,会发生什么 ?
首先,我们得 知道 KNN的算法究竟是 什么 样子 的
如果一个人的特征有这些 (身高,体重,收入)
第一个特征的取值为(150-190)CM
第二个特征取值为(40-80) KG
第三个为 (5000-20000)
假如两个人的指标为 (160,50,8000) (180,60,10000)
我们需要算出距离最近,也就是找 最相似的东西 比如距离可以表示 为 sqrt((160-180)^2+(50-60)^2+(8000-10000)^2)
那么,第三个指标,对结果的影响,会显著性的大 ,所以 要进行标准化
这里需要用到 sklearn.preprocessing 库
代码如下:
from sklearn.preprocessing import MinMaxScaler, StandardScaler
std = StandardScaler()
normal_test_x = std.fit_transform(test_x)
normal_train_x = std.fit_transform(train_x)
7.使用knn对结果进行预测
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
knn.fit(normal_train_x,train_y)
y_predict = knn.predict(normal_test_x)
print(knn.score(normal_test_x,test_y))
# 这里得出的结果为 0.8,其实把数据扩大,训练集为800条,测试集为100条时,准确率会提升到 0.88
全部代码如下:
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
xdate = pd.read_csv('WA_Fn-UseC_-HR-Employee-Attrition.csv') # i
df = xdate
df = df.drop(df[df.Department != 'Research & Development'].index)# 首先删除部门不是 研究部 的行
need_list = [ # 需要保留的字段合集
'Age',
'Attrition',
'BusinessTravel',
'DistanceFromHome',
'Education',
'JobLevel',
'NumCompaniesWorked',
'MonthlyIncome',
'Gender']
delete_list = [] # 需要删除的列表
for i in df:
if i not in need_list:
delete_list.append(i)
df.drop(labels=delete_list, axis=1, inplace=True) # 删除没用的列
df = df.head(100) # 取前100行
alldate = df # 所有数据集
alldate.to_csv('alldate.csv')
for index in alldate['BusinessTravel'].index:
value = alldate['BusinessTravel'].get(index)
if value == 'Travel_Frequently':
alldate['BusinessTravel'][index] = 2
elif value == 'Travel_Rarely':
alldate['BusinessTravel'][index] = 1
else:
alldate['BusinessTravel'][index] = 0 # 把BussinessTravel字段的 频繁出差转成 2 很少转1,不出差转 0
for index in alldate['Gender'].index:
value = alldate['Gender'].get(index)
if value == 'Male':
alldate['Gender'][index] = 1
else:
alldate['Gender'][index] = 0 # 把gender字段 male转成0, female转0
alldate.to_csv('alldate_1.csv')
train = alldate.head(90) # 前90行为训练集
train_y = train['Attrition'] # train_y 为我们需要预测的字段 (该字段表示是否离职)
train_x = train.drop('Attrition', axis=1) # train_x 为预存Attrition 所需要的特征
train_y.to_csv('train_y.csv')
train_x.to_csv('train_x.csv')
test = alldate.tail(10) # 后10行为测试集
test_y = test['Attrition'] # test_y 为 我们通过 test_x 和 train_x 预测是否离职 和实际数据对比
test_x = test.drop('Attrition', axis=1)
test_y.to_csv('test_y.csv')
test_x.to_csv('test_x.csv')
std = StandardScaler()
normal_test_x = std.fit_transform(test_x)
normal_train_x = std.fit_transform(train_x)
knn = KNeighborsClassifier()
knn.fit(normal_train_x, train_y)
y_predict = knn.predict(normal_test_x)
print(knn.score(normal_test_x, test_y))
# 这里得出的结果为 0.8,其实把数据扩大,训练集为800条,测试集为100条时,准确率会提升到 0.88
注:向量标准化的语法格式 可以尝试尝试
from sklearn.preprocessing import MinMaxScaler, StandardScaler
std = StandardScaler()
date = std.fit_transform([[22],[49],[43],[36],[51],[32],[45],[38],[30],[30]])
print(date)