https://www.kaggle.com/c/costa-rican-household-poverty-prediction:哥斯达黎加家庭平困水平预测
这是一个在kaggle上的入门级的项目实战,实际数据需要比标准数据集更多的预处理,已有的数据不是直接处理好的数据,还需要自己处理好数据,然后在看适合的算法和比较好的参数来匹配数据,提高准确率,做出更好的分类。
介绍
了解数据集
加载数据集
数据预处理
通过SMOTE处理数据不平衡
数据扩充
训练模型
做出预测
评估模型性能
介绍:
许多社交项目很难确保为合适的人提供足够的援助。当一个项目关注最贫困的人群时,这一点尤其棘手。世界上最贫穷的人通常无法提供必要的收入和支出记录来证明他们符合条件。在拉丁美洲,一种流行的方法使用算法来验证收入资格。它被称为代理手段测试(或PMT)。通过PMT,代理商使用一种模型,该模型考虑家庭的可观察家庭属性,如墙壁和天花板的材料,或家中发现的资产,以对其进行分类并预测其需求水平。虽然这是一种改进,但随着该地区人口的增长和贫困的减少,准确性仍然是一个问题。为了改善PMT,IDB(拉丁美洲和加勒比地区最大的发展融资来源)转向了Kaggle社区。他们认为,基于哥斯达黎加家庭特征数据集的传统计量经济学之外的新方法可能有助于提高PMT的绩效。
了解数据集:
将使用的数据集可以在这里下载。向下滚动到页面的“数据集描述”部分,然后下载几兆的zip文件
https://www.kaggle.com/c/costa-rican-household-poverty-prediction/data
该数据集有142个特征(我就不一一列举了,显示太多了,想了解进kaggle看吧) ,分成四类,1 =极端贫困,2 =中度贫困, 3 =弱势家庭,4 =非脆弱家庭,但是很多数据有缺失遗漏不完整,还有很多特征是差不多的。
加载数据集:
# 用 pandas读取 csv文件 data_train = pd.read_csv('data/train.csv',dtype={'duration': int}) data_test = pd.read_csv('data/test.csv',dtype={'duration': int}) subs = pd.read_csv('data/sample_submission.csv',dtype={'duration': int})
data_train 训练数据是 9558*143 data_test 测试数据 23.9K*142 subs 是预测提交的文件
数据预处理:
发现数据中很多 空值,还有字符的值,这时候我需要把字符的值 变成 数值,并且把 空值填充
# 把对应的 字符型的值 变成 数值型
data_train.loc[data_train['dependency'] == 'yes', 'dependency'] = 1 data_train.loc[data_train['dependency'] == 'no', 'dependency'] = 0 data_train.loc[data_train['edjefe'] == 'yes', 'edjefe'] = 1 data_train.loc[data_train['edjefe'] == 'no', 'edjefe'] = 0 data_train.loc[data_train['edjefa'] == 'yes', 'edjefa'] = 1 data_train.loc[data_train['edjefa'] == 'no', 'edjefa'] = 0
# # 在填充 均值 data_train = data_train.fillna(0)
发现 标签的每个分类不均等,这样对模型的训练会偏向于小训练数据多的一类,要把每类的数据集相差不大这样会是模型更 好的分类,提高模型预测的准确率。
Counter({4: 5996, 2: 1597, 3: 1209, 1: 755})
数据不均衡问题可以使用的方法 就推荐几篇博客看吧
https://blog.csdn.net/sunflower_sara/article/details/81055033
https://blog.csdn.net/yaphat/article/details/60348946
https://www.jianshu.com/p/be343414dd24
发现很多数据的特征的值都是 0 或 1 ,应该是 读热编码变来的,可以还原用一个特征来表示,就会减少特征计算和提高准 确 率,还有其他这样的特征都可以这样操作,来提高特征的显示。例如:
['pisomoscer','pisocemento','pisoother','pisonatur','pisonotiene','pisomadera']
pisocemento, 如果地板上的主要材料是水泥
pisoother, 如果地板上的主要材料是其他材料
pisonatur, 如果地板上的主要材料是天然材料
pisonotiene, 如果家里没有地板
pisomadera ,如果地板上的主要材料是木材
那么这些特征可以用一个特征来体现, 这样就提升精准度又减少计算,可以把些相关的特征都提取变成一个特征。
训练模型:
模型的话,我试过很多种,开始是想传统的想法解决,
获得一批数据 ----》预处理数据 -----》特征多的话用 PCA 降维 ---》 再用分类算法,得出准确率
貌似这样搞效果不太好了,得到的效果比较差
models = [] models.append(("KNN",KNeighborsClassifier(n_neighbors=2))) # 普通的k-近邻算法 models.append(("KNN with weights",KNeighborsClassifier(n_neighbors=2,weights='distance'))) # 带权值的K-近邻算法 models.append(("Radius Neighbors",RadiusNeighborsClassifier(n_neighbors=2,radius=500.0))) # RadiusNeighborsClassifier的半径 #分别训练3个模型,并计算评分 results = [] for name,model in models: model.fit(data_x,data_y) results.append((name,model.score(data_x,data_y))) # 评估模型 for i in range(len(results)): print('name: {}; score: {}'.format(results[i][0],results[i][1]))
后面还是感觉集成算法 好一些吧,可能适合这些数据, sklearn.ensemble.GradientBoostingClassifier
model = GradientBoostingClassifier(learning_rate=0.1, min_samples_split=500,min_samples_leaf=50,max_depth=7,max_features='sqrt',subsample=0.8)
数据增加:
通常,拥有的数据越多,模型训练的就越好,也可以用 SMOTE 人工 产生数据, 或采集更多的数据吧
做出预测:
model = GradientBoostingClassifier(learning_rate=0.1, min_samples_split=500,min_samples_leaf=50,max_depth=7,max_features='sqrt',subsample=0.8)
model.fit(data_x, data_y)
res_y = model.predict(data_x)
scores = accuracy_score(res_y, data_y)print("Accuracy: [%s]" % (scores))
评估模型的性能:
最后附上完整的代码在 https://github.com/VarWolf/Varwolf