应用统计课上的数据集,觉得挺有意思,就玩了一下。
在之后的数据处理中,我要将职业类型这个列拆解,所以这里先分析职业类型。
#将不同职业类型现在的工资情况作成一个列表
#便于plt绘图
list1 = []
list2 = []
list3 = []
for i in range(len(df)):
if df['genre'][i]==1:
list1.append(df['salary_now'][i])
elif df['genre'][i]==2:
list2.append(df['salary_now'][i])
else:
list3.append(df['salary_now'][i])
list_all = []
list_all.append(list1)
list_all.append(list2)
list_all.append(list3)
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(13, 4))
# plot violin plot
axes[0].violinplot(list_all,
showmeans=False,
showmedians=True)
axes[0].set_title('violin plot')
# plot box plot
axes[1].boxplot(list_all)
axes[1].set_title('box plot')
# adding horizontal grid lines
for ax in axes:
# ax.yaxis.set_major_locator(ymajorLocator)
ax.yaxis.grid(True)
ax.set_xticks([y+1 for y in range(len(list_all))])
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
# ax.axis([0,4,0,10000])
# add x-tick labels
plt.setp(axes, xticks=[y+1 for y in range(len(list_all))],xticklabels=['administrator','worker','tech'])
# plt.axis([0,13,0,10000])
plt.savefig('violin_box4.png',dpi =600)
可以看出来,在这间公司里工人类的员工薪资待遇较稳定,且稳定在较低水平;行政类员工平均水平甚至比工人类还低,但是有一定加薪空间(是不是行政高管都不怎么拿工资,但是会有很多股权?);而技术类平均薪水最高且最低工资的那个技术工甚至相当于工人类的最高水平。
df.rename(columns = {'d':'birthday','x1':'education','x2':'genre','x3':'salary_now','x4':'salary_begin','x5':'hiretime','x6':'experience','x7':'minority'},inplace = True)
genre_mapping = {
1: 'administrator',
2: 'worker',
3:'tech'
}
df['genre'] = df['genre'].map(genre_mapping)
genre_dummies = pd.get_dummies(df['genre'])
df = df.join(pd.get_dummies(df.genre))
将salary_now分成三个等级,并确保每一等级的人数相等,并删除被处理后的列
df['income'] = pd.qcut(df.salary_now, 3,labels=['1','2','3'])
df.drop(['birthday'],axis=1,inplace =True)
df.drop(['genre'],axis=1,inplace =True)
以salary_now为数据源将income(也就是预测的对象)分成三种,分别为high income、middle income、low income
df = pd.read_csv('corp3.csv')
train = df.drop(['income'],axis = 1)
train = train.drop(['salary_now'],axis = 1)
label = df['income']
from sklearn import datasets
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier
clfe = tree.DecisionTreeClassifier(max_depth=8,max_leaf_nodes=25)
#max_leaf_nodes=25限制树的宽度
clf = clfe.fit(train,label)
from sklearn.tree import export_graphviz
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(train,label,test_size=0.2,random_state=24)
tree2 = DecisionTreeClassifier(max_depth=6,random_state=0)
tree2.fit(X_train,y_train)
print('Train score:{:.3f}'.format(tree2.score(X_train,y_train)))
print('Test score:{:.3f}'.format(tree2.score(X_test,y_test)))
with open("iris.dot", 'w') as f:
f = tree.export_graphviz(clf, out_file=f)
Train score:0.852
Test score:0.747
import pydotplus
feature_name=['gender', 'education', 'salary_begin', 'hiretime',
'experience', 'minority', 'administrator', 'tech', 'worker']
target_name = ['low income','middle income','high income']
dot_data = tree.export_graphviz(clf,out_file = None,feature_names=feature_name,
class_names=target_name,filled=True,rounded=True,special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_pdf("WineTree2.pdf")
在这决策树中,紫色代表高薪、绿色代表中薪、橙色代表高薪
通过决策树可以发现,员工初始工资深刻影响着现在的工资(赢在起跑线的重要性),其次是工作经历、性别、工作时间等。
在分析工种对薪水的影响的时候,明明工种的影响很大,但是在这决策树看来为什么就影响没这么大呢?个人猜测是由于salary_begin很大程度反映了工种,这猜测与第一张图相吻合。
想运用sns绘图时,觉得工种分别按1、2、3表示便于图表观察(之前dummy为了决策树分类的结果更精确,这是因为如果1表示行政、2表示工人、3表示技术人员的话,分类器会默认为相较于行政和技术人员的情况,行政与工人的情况更相似,所以要将行政表示为100、工人表示为010、技术人员表示为001),在好奇心的驱使下,尝试了一下不dummy化时的决策树精确度,却惊奇的发现竟然是一样的。
接着我以为是salary_begin影响权重大的缘故使得因为dummy化引起的细微变化不能改变模型精确值,所以我把salary_begin剔除之后,在比较dummy化前后的变化。
预料中的是,训练模型得到的分类精确度果然低了不少。而意外的是,dummy化并不改变这精确度。
sns特别好用的地方在于几行代码就能反映所有列的相对关系,从seaborn官网找到的代码如下:
import seaborn as sns
sns.set(style="white")
g = sns.PairGrid(df, diag_sharey=False)
g.map_lower(sns.kdeplot)
g.map_upper(sns.scatterplot)
g.map_diag(sns.kdeplot, lw=3)
g.savefig("output3.png",dpi=400)
运行结果如下
在这公司里,男职员工资范围广,而女职员工资趋于相似且工资较低。
员工受教育大都在10-18年间,且15年以上的受教育时间竞争力大
在这里可以看到,现在的薪水与起薪有着明显的线性相关性,且现在薪水大都集中在25000。
与聘用时间无明显关系。
最让我震惊的是,薪水居然与之前的工作经历有类似于负相关的关系,百思不得其解。
train = df.drop(['income'],axis = 1)
label = df['income']
column_headers = list(train.columns.values)
import scipy
from scipy.stats import pearsonr
r = []
p = []
for feature in column_headers:
r_row, p_value = pearsonr(df[feature], label)
r.append(r_row)
# p.append(p_value)
a3 = pd.DataFrame({'r':r}, index =['gender',
'education',
'genre',
'salary_now',
'salary_begin',
'hiretime',
'experience',
'minority'])
#r: 相关系数 [-1,1]之间