网络推广营销网站建设专家,flash做网站的论文,福州设计公司,广州中企动力网站制作文章目录分析目的一、数据采集1、 数据来源2、 数据说明二、数据传输三、数据处理1、查看数据2、缺失值处理3、合并数据集4、时间数据处理5、分组及One-hot编码处理四、数据分析1、描述性统计2、探索性分析1 是否与所在地是城市or农村有关2 是否与性别有关3 是否与年龄有关4 是…
文章目录分析目的一、数据采集1、 数据来源2、 数据说明二、数据传输三、数据处理1、查看数据2、缺失值处理3、合并数据集4、时间数据处理5、分组及One-hot编码处理四、数据分析1、描述性统计2、探索性分析1 是否与所在地是城市or农村有关2 是否与性别有关3 是否与年龄有关4 是否与经济收入地位有关5 是否与受教育程度有关五、数据挖掘1、构建模型2、导入算法3、评估模型4、方案实施分析目的
“你幸福吗”“我姓福”。努力的意义究其根本就是为了获取幸福感让自己愉悦。当阴雨连绵之后的太阳你会觉得幸福拿到第一份工资会觉得幸福与幸福感相关的因素成千上万、因人而异每个人对幸福感都有自己的衡量标准影响幸福感的因素主要会是什么呢什么样的人幸福感更强呢是否能预测出每个人的幸福值呢
一、数据采集
1、 数据来源
数据来自于阿里云天池下载链接一起挖掘幸福感
2、 数据说明
考虑到变量个数较多部分变量间关系复杂数据分为完整版和精简版两类。可从精简版入手熟悉赛题后使用完整版挖掘更多信息。complete文件为变量完整版数据abbr文件为变量精简版数据。 index文件中包含每个变量对应的问卷题目以及变量取值的含义。 survey文件是数据源的原版问卷作为补充以方便理解问题背景。
二、数据传输
将数据导入到PYTHON软件
train pd.read_csv(D:\A\幸福感\happiness_train_complete.csv,encodingISO-8859-1)
test pd.read_csv(D:\A\幸福感\happiness_test_complete.csv,encodingISO-8859-1)
test_subpd.read_csv(D:\A\幸福感\happiness_submit.csv,encodingISO-8859-1)
三、数据处理
1、查看数据
#查看数据有多少行多少列
print(train.shape, test.shape)
输出结果(8000, 140) (2968, 139)即训练集8000行140列测试集2968行139列。
2、缺失值处理
#查看缺失值
train.info(verboseTrue,null_countsTrue) 根据结果一共有8000行数据其中float型数据25个, int型111个, object型4个。在这些数值型数据中有很多是实际上是分类数据原数据集通过对其编码变成了数值型数据。对于分类型数据将进行One-hot编码后再分析。 family_income有1条数据缺失。 而work_status,work_type, work_manage,work_yr列的数据缺失非常大。缺失较大的进行删除操作少量缺失则用频繁出现数填充。
#列名class为Python保留字要改名不然在操作中很可能报错
train.rename(columns{class: Class}, inplaceTrue)
#列nationality为-8的值将其替换为8表示其他。
train[nationality] train.nationality.replace(-8, 8)
#列religion和religion_freq为-8的值将其替换为最频繁出现的值1。
train[religion] train.religion.replace(-8, 1)
train[religion_freq] train.religion_freq.replace(-8, 1)
#列religion和religion_freq为-8的值将其替换为最频繁出现的值1。
train[religion] train.religion.replace(-8, 1)
train[religion_freq] train.religion_freq.replace(-8, 1)
#将income列为-1-2-3的值先替换为空值再用平均值替换
train[income] train.income.replace([-1, -2, -3], np.nan)
train[income] train.income.replace(np.nan, train[income].mean())
#列nationality为-8的值将其替换为最频繁出现的值1。
train[political] train.political.replace(-8, 1)
#列healthhealth_problem为-8的值将其替换为3表示一般。
train[health] train.health.replace(-8, 3)
train[health_problem] train.health_problem.replace(-8, 3)
#列depression为-8的值将其替换为3表示一般。
train[depression] train.depression.replace(-8, 3)
#列socializerelaxlearn为-8的值将其替换为3表示有时。
train[socialize] train.socialize.replace(-8, 3)
train[relax] train.relax.replace(-8, 3)
train[learn] train.learn.replace(-8, 3)
#列equity为-8的值将其替换为3表示中间态度。
train[equity] train.equity.replace(-8, 3)
#列class为-8的值将其替换为最频繁出现的5。
train[Class] train.Class.replace(-8, 5)
#将family_income列为-1-2-3的值先替换为空值再用平均值替换
train[family_income] train.family_income.replace([-1, -2, -3], np.nan)
train[family_income] train.family_income.replace(np.nan, train[family_income].mean())
#将family_m列为-1-2-3的值替换为1
train[family_m] train.family_m.replace([-1, -2, -3], 1)
#列family_status为-8的值将其替换为3表示平均水平
train[family_status] train.family_status.replace(-8, 3)
#将house列为-1-2-3的值替换为0
train[house] train.house.replace([-1, -2, -3], 0)
#将car列为-8的值替换为最频繁出现的2
train[car] train.car.replace(-8, 2)
#将status_peerstatus_3_beforeview列为-8的值替换为差不多一般
train[status_peer] train.status_peer.replace(-8, 2)
train[status_3_before] train.status_3_before.replace(-8, 2)
train[view] train.view.replace(-8, 3)
#inc_ability缺失值过多将inc_ability列为-8的值替换为0
train[inc_ability] train.inc_ability.replace(-8, 0)
#查看happiness的label分布
y_train_train[happiness]
y_train_.value_counts()
#将happiness列为-8的值替换为3 说不上幸福不幸福
y_train_y_train_.map(lambda x:3 if x-8 else x)
traintrain.drop([work_statuswork_type,work_manage,work_yr], axis1)
3、合并数据集
合并数据集方便同时对两个数据集进行清洗
data train.append(test, ignore_index True, sortFalse)
print (data.shape)
4、时间数据处理
规范时间格式
data[survey_time] pd.to_datetime(data[survey_time],format%Y-%m-%d %H:%M:%S)
data[year]data[survey_time].dt.year
data[quarter]data[survey_time].dt.quarter
data[month]data[survey_time].dt.month
data[weekday]data[survey_time].dt.weekday
data[hour]data[survey_time].dt.hour
时间分段
#把一天的时间分段
def hour_cut(x):if 0x6:return 0elif 6x8:return 1elif 8x12:return 2elif 12x14:return 3elif 14x18:return 4elif 18x21:return 5elif 21x24:return 6
data[hour_cut]data[hour].map(hour_cut)
做问卷调查时的年龄
data[survey_age]data[year]-data[birth]
出生的年代
#出生的年代
def birth_split(x):if 1920x1930:return 0elif 1930x1940:return 1elif 1940x1950:return 2elif 1950x1960:return 3elif 1960x1970:return 4elif 1970x1980:return 5elif 1980x1990:return 6elif 1990x2000:return 7
data[birth_s]data[birth].map(birth_split)
5、分组及One-hot编码处理
分组处理
#收入分组
def income_cut(x):if x0:return 0elif 0x1200:return 1elif 1200x10000:return 2elif 10000x24000:return 3elif 24000x40000:return 4elif 40000x:return 5
data[income_cut]data[income].map(income_cut)
#对教育程度分组将分组结果放在edu_group字段
bins [0, 3, 4, 8, 12, 13, 14]
eduLabels [1, 2, 3, 4, 5, 6]
data[edu_group] pd.cut(data.edu,bins,labelseduLabels)
#分类的标签不能重复edu_group值为6的换乘1
data[edu_group] data.edu_group.replace(6, 1)
#受教育层次edu_group
edu_groupDf pd.DataFrame()
#使用get_dummies进行one-hot编码列名前缀是edu_group
edu_groupDf pd.get_dummies( data[edu_group] , prefixedu_group )
One-hot编码处理 对于分类数据用One-hot编码产生虚拟变量dummy variables都用0-1表示。 edu的选项比较多有14种要对其分组后再做比较。 分如下成几组 1.小学及其他包括原数据中的12314 2.初中对应原数据中的4 3.高中对应原数据中的5678 4.大学对应原数据中的9101112 5.研究生对应原数据中的13
#political政治面貌
politicalDf pd.DataFrame()
politicalDf pd.get_dummies(data[political] , prefixpolitical )
#health健康状况
healthDf pd.DataFrame()
healthDf pd.get_dummies( data[health] , prefixhealth )
#health_problem健康问题的影响
health_problemDf pd.DataFrame()
health_problemDf pd.get_dummies( data[health_problem] , prefixhealth_problem )
#depression心情抑郁
depressionDf pd.DataFrame()
depressionDf pd.get_dummies( data[depression] , prefixdepression )
#hukou户口
hukouDf pd.DataFrame()
hukouDf pd.get_dummies( data[hukou] , prefixhukou )
#socialize社交
socializeDf pd.DataFrame()
socializeDf pd.get_dummies( data[socialize] , prefixsocialize )
#relax放松
relaxDf pd.DataFrame()
relaxDf pd.get_dummies( data[relax] , prefixrelax )
#learn学习
learnDf pd.DataFrame()
learnDf pd.get_dummies( data[learn] , prefixlearn )
#equity公平
equityDf pd.DataFrame()
equityDf pd.get_dummies( data[equity] , prefixequity )
#Class等级
ClassDf pd.DataFrame()
ClassDf pd.get_dummies( data[Class] , prefixClass )
#work_exper工作经历
work_experDf pd.DataFrame()
work_experDf pd.get_dummies( data[work_exper] , prefixwork_exper )
#family_status家庭经济状况
family_statusDf pd.DataFrame()
family_statusDf pd.get_dummies( data[family_status] , prefixfamily_status )
#car是否拥有小汽车转变成0没有1有
data[car] data.car.replace(2, 0)
#marital婚姻状况
maritalDf pd.DataFrame()
maritalDf pd.get_dummies( data[marital] , prefixmarital )
#status_peer经济社会地位
status_peerDf pd.DataFrame()
status_peerDf pd.get_dummies( data[status_peer] , prefixstatus_peer )
#status_3_before3年来社会经济地位的变化
status_3_beforeDf pd.DataFrame()
status_3_beforeDf pd.get_dummies( data[status_3_before] , prefixstatus_3_before )
#view观点
viewDf pd.DataFrame()
viewDf pd.get_dummies( data[view] , prefixview )
#inc_ability收入合理性
inc_abilityDf pd.DataFrame()
inc_abilityDf pd.get_dummies( data[inc_ability] , prefixinc_ability )
#删除空值的列
inc_abilityDf.drop(inc_ability_0,axis1,inplaceTrue)
四、数据分析
1、描述性统计
data.happiness.describe() 幸福感的均值为3.87表明总体上幸福强。25%百分位数为4表明有超过四分之三的受访者对幸福感给出4分或5分觉得不幸福的人数不多。
happiness_count data.groupby([happiness], as_indexFalse).id.agg(count)
print(happiness_count) 国民幸福度都较高但这也只是一部分不能代表整体。给出一分两分的也有可跟踪为什么给出极值的人员找出原因。
#展示整体人群的幸福状况各选项选择的人数
happiness_count data.groupby([happiness], as_indexFalse).id.agg(count)
print(happiness_count)
#将结果绘图分别用饼图和柱状图展示。
fig plt.figure(figsize(10, 5))
font matplotlib.font_manager.FontProperties(size13)
ax1 fig.add_subplot(1, 2, 1)
plt.pie(happiness_count.id,labels[1, 2, 3, 4, 5],autopct%.1f%%,textprops{fontproperties: font},radius1.2)
plt.title(觉得比较幸福的人占6成, size13)
ax2 fig.add_subplot(1, 2, 2)
plt.bar(happiness_count[happiness], happiness_count[id],color[g, y, r, c, m])
plt.xticks(size13)
plt.yticks(size13)
plt.xlabel(1 非常不幸福; 2 比较不幸福; 3 说不上幸福不幸福; 4 比较幸福; 5 非常幸福)
plt.title(整体人群的幸福状况, size13)
plt.subplots_adjust(wspace0.5) 2、探索性分析
1 是否与所在地是城市or农村有关
#查看城乡幸福感的平均情况
survey_type_mean data.groupby([survey_type]).happiness.mean()
print(survey_type_mean)
survey_type_result data.pivot_table(valuesid,indexhappiness,columnssurvey_type,aggfunccount)
survey_type_result 总体上城市的幸福感比农村高可能是城市娱乐设施多比较热闹且城市相对富裕没什么压力。但总体上两者差距不是很大。
#用频数不容易比较相对百分比所以要将组百分比归一化为1。
survey_type_result[0] survey_type_result[0] / survey_type_result[0].sum()
survey_type_result[1] survey_type_result[1] / survey_type_result[1].sum()
print(survey_type_result)
bar_width0.4
plt.bar(xsurvey_type_result.index - 0.5 * bar_width, heightsurvey_type_result[0], label农村, widthbar_width)
plt.bar(xsurvey_type_result.index 0.5 * bar_width, heightsurvey_type_result[1], label城市, widthbar_width)
plt.title(城乡幸福感对比, size15)
plt.ylabel(比例)
plt.xlabel(1 非常不幸福; 2 比较不幸福; 3 说不上幸福不幸福; 4 比较幸福; 5 非常幸福)
plt.legend()
plt.show() 2 是否与性别有关
#查看男性、女性幸福感的平均情况
gender_mean data.groupby([gender]).happiness.mean()
print(gender_mean)
gender_result data.pivot_table(valuesid,indexhappiness,columnsgender,aggfunccount)
gender_result 在给出三分四分的人数里男性幸福度比较高而一分两分五分则是女性比较高。出现这一现象的原因可能是女性目前的社会地位造成及心理承受压力等。但总体上男性与女性幸福感的差异不明显。
#转换成百分比
gender_result[0] gender_result[0] / gender_result[0].sum()
gender_result[1] gender_result[1] / gender_result[1].sum()
print(gender_result)
bar_width0.4
plt.bar(xgender_result.index - 0.5 * bar_width, heightgender_result[0], label女, widthbar_width)
plt.bar(xgender_result.index 0.5 * bar_width, heightgender_result[1], label男, widthbar_width)
plt.title(性别幸福感对比, size15)
plt.ylabel(比例)
plt.xlabel(1 非常不幸福; 2 比较不幸福; 3 说不上幸福不幸福; 4 比较幸福; 5 非常幸福)
plt.legend()
plt.show() 3 是否与年龄有关
首先对样本的年龄进行分类分成5个年龄段。按照20%, 40%, 60%, 80%百分位数设置阈值这样使每个组的样本数大致相等。
data.survey_age.describe(percentiles[0.2, 0.4, 0.6, 0.8])
#对年龄分组将分组结果放在age_group字段
bins [17, 33, 45, 54, 65, 100]
ageLabels [33岁及以下, 34-45岁, 46-54岁, 55-65岁, 66岁及以上]
data[age_group] pd.cut(data.survey_age,bins,labelsageLabels)
#查看各年龄层次幸福感的平均情况
age_mean data.groupby([age_group]).happiness.mean()
print(age_mean)
#各年龄段对幸福感评价的分布情况
age_result data.pivot_table(valuesid,indexhappiness,columnsage_group,aggfunccount)
age_result 感觉非常幸福的比例66岁以上年龄段最多33岁以下年龄段其次46-54岁年龄段最少。感觉比较不幸福和非常不幸福46-54岁年龄段的比例最大。老年人有更多的幸福感年轻人的幸福感也相对较高中年人的幸福感低。各个年龄段幸福感呈现先降后升的态势。
data.survey_age.describe(percentiles[0.2, 0.4, 0.6, 0.8])
#对年龄分组将分组结果放在age_group字段
bins [17, 33, 45, 54, 65, 100]
ageLabels [33岁及以下, 34-45岁, 46-54岁, 55-65岁, 66岁及以上]
data[age_group] pd.cut(data.survey_age,bins,labelsageLabels)
#查看各年龄层次幸福感的平均情况
age_mean data.groupby([age_group]).happiness.mean()
print(age_mean)
#各年龄段对幸福感评价的分布情况
age_result data.pivot_table(valuesid,indexhappiness,columnsage_group,aggfunccount)
print(age_result)
bar_width0.17
plt.bar(xage_result.index - 2 * bar_width, heightage_result[33岁及以下], label33岁及以下, widthbar_width)
plt.bar(xage_result.index - 1 * bar_width, heightage_result[34-45岁], label34-45岁, widthbar_width)
plt.bar(xage_result.index, heightage_result[46-54岁], label46-54岁, widthbar_width)
plt.bar(xage_result.index 1 * bar_width, heightage_result[55-65岁], label55-65岁, widthbar_width)
plt.bar(xage_result.index 2 * bar_width, heightage_result[66岁及以上], label66岁及以上, widthbar_width)
plt.title(年龄幸福感对比, size15)
plt.ylabel(比例)
plt.xlabel(1 非常不幸福; 2 比较不幸福; 3 说不上幸福不幸福; 4 比较幸福; 5 非常幸福)
plt.legend()
plt.show() 4 是否与经济收入地位有关
#查看社会经济地位不同的群体幸福感的平均情况
status_peer_mean data.groupby([status_peer]).happiness.mean()
print(status_peer_mean)
#社会经济地位与幸福感的数据透视表
status_peer_result data.pivot_table(valuesid,indexhappiness,columnsstatus_peer,aggfunccount)
status_peer_result 与同龄人相比认为自身经济社会地位较高的人有34.2%的认为非常幸福有60.8%的认为比较幸福这一群体的幸福感也高。认为自身经济社会地位与同龄人相比较低的人更多地感到不幸福。
#转换成百分比
status_peer_result[1] status_peer_result[1] / status_peer_result[1].sum()
status_peer_result[2] status_peer_result[2] / status_peer_result[2].sum()
status_peer_result[3] status_peer_result[3] / status_peer_result[3].sum()
printstatus_peer_result
bar_width0.25
plt.bar(xstatus_peer_result.index - 1 * bar_width, heightstatus_peer_result[1], label较高, widthbar_width)
plt.bar(xstatus_peer_result.index, heightstatus_peer_result[2], label差不多, widthbar_width)
plt.bar(xstatus_peer_result.index 1 * bar_width, heightstatus_peer_result[3], label较低, widthbar_width)
plt.title(对自身经济社会地位的评价与幸福感, size15)
plt.ylabel(比例)
plt.xlabel(1 非常不幸福; 2 比较不幸福; 3 说不上幸福不幸福; 4 比较幸福; 5 非常幸福)
plt.legend()
plt.show() 5 是否与受教育程度有关
#查看各学历层次幸福感的平均情况
edu_mean data.groupby([edu_group]).happiness.mean()
print(edu_mean)
#各学历层次对幸福感评价的分布情况
edu_result data.pivot_table(valuesid,indexhappiness,columnsedu_group,aggfunccount)
edu_result 从幸福感评价的均值来看受教育程度越高幸福感越高。在评价比较幸福和非常幸福的人群中受教育程度越高的群体比例越高但存在一个例外是小学文化的人感觉非常幸福的比例比初中文化的高。而在评价“说不上幸福不幸福”、“比较不幸福”、“非常不幸福”的人群中受教育程度越低的的群体比例越高。可以看出接受更多的教育能使幸福感显著提升。或者说受教育程度高的人幸福感更强。
#转换成百分比
edu_result[1] edu_result[1] / edu_result[1].sum()
edu_result[2] edu_result[2] / edu_result[2].sum()
edu_result[3] edu_result[3] / edu_result[3].sum()
edu_result[4] edu_result[4] / edu_result[4].sum()
edu_result[5] edu_result[5] / edu_result[5].sum()
#用0填补空值
edu_result edu_result.fillna(0)
print(edu_result)
bar_width0.17
plt.bar(xedu_result.index - 2 * bar_width, heightedu_result[1], label小学及其他, widthbar_width)
plt.bar(xedu_result.index - 1 * bar_width, heightedu_result[2], label初中, widthbar_width)
plt.bar(xedu_result.index, heightedu_result[3], label高中, widthbar_width)
plt.bar(xedu_result.index 1 * bar_width, heightedu_result[4], label大学, widthbar_width)
plt.bar(xedu_result.index 2 * bar_width, heightedu_result[5], label研究生, widthbar_width)
plt.title(受教育程度幸福感对比, size15)
plt.ylabel(比例)
plt.xlabel(1 非常不幸福; 2 比较不幸福; 3 说不上幸福不幸福; 4 比较幸福; 5 非常幸福)
plt.legend()
plt.show() 五、数据挖掘
1、构建模型
用训练数据和某个机器学习算法得到机器学习模型用测试数据评估模型
2、导入算法
采用LGBOOST与XGBOOST算法预测幸福值
#自定义评价函数
def myFeval(preds, xgbtrain):label xgbtrain.get_label()score mean_squared_error(label,preds)return myFeval,score##### xgb
xgb_params {booster:gbtree,eta: 0.005, max_depth: 5, subsample: 0.7, colsample_bytree: 0.8, objective: reg:linear, eval_metric: rmse, silent: True, nthread: 8}
folds KFold(n_splits5, shuffleTrue, random_state2018)
oof_xgb np.zeros(len(train))
predictions_xgb np.zeros(len(test))
for fold_, (trn_idx, val_idx) in enumerate(folds.split(X_train, y_train)):print(fold n°{}.format(fold_1))trn_data xgb.DMatrix(X_train[trn_idx], y_train[trn_idx])val_data xgb.DMatrix(X_train[val_idx], y_train[val_idx])watchlist [(trn_data, train), (val_data, valid_data)]clf xgb.train(dtraintrn_data, num_boost_round20000, evalswatchlist, early_stopping_rounds200, verbose_eval100, paramsxgb_params,feval myFeval)oof_xgb[val_idx] clf.predict(xgb.DMatrix(X_train[val_idx]), ntree_limitclf.best_ntree_limit)predictions_xgb clf.predict(xgb.DMatrix(X_test), ntree_limitclf.best_ntree_limit) / folds.n_splits
print(CV score: {:8.8f}.format(mean_squared_error(oof_xgb, y_train_))) ##### lgb
param {boosting_type: gbdt,num_leaves: 20,min_data_in_leaf: 20, objective:regression,max_depth:6,learning_rate: 0.01,min_child_samples: 30, feature_fraction: 0.8,bagging_freq: 1,bagging_fraction: 0.8 ,bagging_seed: 11,metric: mse,lambda_l1: 0.1,verbosity: -1}
folds KFold(n_splits5, shuffleTrue, random_state2018)
oof_lgb np.zeros(len(X_train_))
predictions_lgb np.zeros(len(X_test_))
for fold_, (trn_idx, val_idx) in enumerate(folds.split(X_train, y_train)):print(fold n°{}.format(fold_1))trn_data lgb.Dataset(X_train[trn_idx], y_train[trn_idx]) val_data lgb.Dataset(X_train[val_idx], y_train[val_idx])num_round 10000clf lgb.train(param, trn_data, num_round, valid_sets [trn_data, val_data], verbose_eval200, early_stopping_rounds 100)oof_lgb[val_idx] clf.predict(X_train[val_idx], num_iterationclf.best_iteration)predictions_lgb clf.predict(X_test, num_iterationclf.best_iteration) / folds.n_splits
print(CV score: {:8.8f}.format(mean_squared_error(oof_lgb, y_train_))) 3、评估模型
from sklearn import linear_model
# 将lgb和xgb的结果进行stacking
train_stack np.vstack([oof_lgb,oof_xgb,oof_cb]).transpose()
test_stack np.vstack([predictions_lgb, predictions_xgb,predictions_cb]).transpose()
folds_stack RepeatedKFold(n_splits5, n_repeats2, random_state2018)
oof_stack np.zeros(train_stack.shape[0])
predictions np.zeros(test_stack.shape[0])
for fold_, (trn_idx, val_idx) in enumerate(folds_stack.split(train_stack,y_train)):print(fold {}.format(fold_))trn_data, trn_y train_stack[trn_idx], y_train[trn_idx]val_data, val_y train_stack[val_idx], y_train[val_idx] clf_3 linear_model.BayesianRidge()#clf_3 linear_model.Ridge()clf_3.fit(trn_data, trn_y) oof_stack[val_idx] clf_3.predict(val_data)predictions clf_3.predict(test_stack) / 10
print(CV score: {:8.8f}.format(mean_squared_error(oof_stack, y_train_))) 4、方案实施
#将结果保存为csv文件
resultlist(predictions)
resultlist(map(lambda x: x 1, result))
test_sub[happiness]result
test_sub.to_csv(happiness.csv, indexFalse)