import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler,StandardScaler
from sklearn.preprocessing import LabelEncoder,OneHotEncoder
from sklearn.preprocessing import Normalizer
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.decomposition import PCA
#sl:satisfaction_level——False表示MinMaxScaler归一化,True表示StandardScaler标准化
#le:last_evaluation——False表示MinMaxScaler归一化,True表示StandardScaler标准化
#npr:number_project——False表示MinMaxScaler归一化,True表示StandardScaler标准化
#amh:average_monthly_hours——False表示MinMaxScaler归一化,True表示StandardScaler标准化
#tsc:time_spend_company——False表示MinMaxScaler归一化,True表示StandardScaler标准化
#wa:Work_accident——False表示MinMaxScaler归一化,True表示StandardScaler标准化
#pl5:promotion_last_5years——False表示MinMaxScaler归一化,True表示StandardScaler标准化
#dp:department——False:LabelEncoding,True:OneHotEncoding
#slr:salary——False:LabelEncoding,True:OneHotEncoding
#lower_d:是否降维——False:不降维,True降维
#ld_n:指定降为几维
def hr_preprocessing(sl=False,le=False,npr=False,amh=False,tsc=False,wa=False,pl5=False,dp=False,slr=False,lower_d=False,ld_n=1):
df=pd.read_csv("HR.csv") #读入数据
#1.清洗数据
df=df.dropna(subset=["satisfaction_level","last_evaluation"])
df=df[df["satisfaction_level"]<=1][df["salary"]!="nme"]
#2.得到标注
label=df["left"]
df=df.drop("left",axis=1) #axis=1以列删除
#3.特征选择
#4.特征处理:标准化,归一化
scaler_lst=[sl,le,npr,amh,tsc,wa,pl5]
column_lst=["satisfaction_level","last_evaluation","number_project",\
"average_monthly_hours","time_spend_company","Work_accident",\
"promotion_last_5years"]
for i in range(len(scaler_lst)):
if not scaler_lst[i]:
df[column_lst[i]]=\
MinMaxScaler().fit_transform(df[column_lst[i]].values.reshape(-1,1)).reshape(1,-1)[0]
#reshape(-1,1)列,reshape(1,-1)[0]二维向量取第零个
else:
df[column_lst[i]]=\
StandardScaler().fit_transform(df[column_lst[i]].values.reshape(-1,1)).reshape(1,-1)[0]
scaler_lst=[slr,dp]
column_lst=["salary","department"]
for i in range(len(scaler_lst)):
if not scaler_lst[i]:
if column_lst[i]=="salary":
df[column_lst[i]]=[map_salary(s) for s in df["salary"].values]
else:
df[column_lst[i]]=LabelEncoder().fit_transform(df[column_lst[i]])
df[column_lst[i]]=MinMaxScaler().fit_transform(df[column_lst[i]].values.reshape(-1,1)).reshape(1,-1)[0]#再归一化或标准化也可不进行
else:
df=pd.get_dummies(df,columns=[column_lst[i]]) #pandas提供的独热
if lower_d:
#return LinearDiscriminantAnalysis(n_components=ld_n)
#LDA这里的n_components不能大于标注的类的个数,有限值,改用无限制的PCA方法
return PCA(n_components=ld_n).fit_transform(df.values),label
return df,label
#由于LabelEncoder会默认按英文字母排序,为了让low为0,medium为1,high为2,需自定义
d=dict([("low",0),("medium",1),("high",2)])
def map_salary(s):
return d.get(s,0) #如果没有找到就返回0,默认是低收入人群
def hr_modeling(features,label):
#切分训练集和验证集(测试集)
from sklearn.model_selection import train_test_split
f_v=features.values #原先的数据是DataFrame,装换为数值
l_v=label.values
x_tt,x_validation,y_tt,y_validation=train_test_split(f_v,l_v,test_size=0.2)
#将训练集再切分为训练集和测试集
x_train,x_test,y_train,y_test=train_test_split(x_tt,y_tt,test_size=0.25)
###KNN NearestNeighbors可以直接获得一个点附近最近的几个点
from sklearn.neighbors import NearestNeighbors,KNeighborsClassifier
knn_clf=KNeighborsClassifier(n_neighbors=3)
#knn_clf_n5=KNeighborsClassifier(n_neighbors=5) #n_neighbors等于3和等于5对比,确定3
knn_clf.fit(x_train,y_train)
#knn_clf_n5.fit(x_train,y_train)
#引入评价指标
from sklearn.metrics import accuracy_score,recall_score,f1_score
y_pred=knn_clf.predict(x_train)
print("Train:")
print("ACC:",accuracy_score(y_train,y_pred))
print("REC:",recall_score(y_train,y_pred))
print("F-score:",f1_score(y_train,y_pred))
y_pred=knn_clf.predict(x_validation)
print("Validation:")
print("ACC:",accuracy_score(y_validation,y_pred))
print("REC:",recall_score(y_validation,y_pred))
print("F-score:",f1_score(y_validation,y_pred))
#y_pred_n5=knn_clf_n5.predict(x_validation)
#print("ACC:",accuracy_score(y_validation,y_pred_n5))
#print("REC:",recall_score(y_validation,y_pred_n5))
#print("F-score:",f1_score(y_validation,y_pred_n5))
y_pred=knn_clf.predict(x_test)
print("Test:")
print("ACC:",accuracy_score(y_test,y_pred))
print("REC:",recall_score(y_test,y_pred))
print("F-score:",f1_score(y_test,y_pred))
#保存模型
from sklearn.externals import joblib
joblib.dump(knn_clf,"knn_clf") #会生成一个knn_clf模型
knn_clf=joblib.load("knn_clf") #使用模型
print("Test2:")
print("ACC:",accuracy_score(y_test,y_pred))
print("REC:",recall_score(y_test,y_pred))
print("F-score:",f1_score(y_test,y_pred))
#调用
def main():
features,label=hr_preprocessing() #默认是False,也可以改为True
hr_modeling(features,label)
if __name__=="__main__":
main()