第1章绪论
题目来源:http://suo.im/S2beL
数据来源:https://github.com/ajschumacher/gadsdata/tree/master/lemons
1.1研究背景
一个汽车经销商在汽车拍卖平台采购一个二手车所面临的一个巨大的挑战是可能购买到有一系列问题的汽车,从而不能卖给顾客。汽车论坛称这种不幸的购买为“kicks”
坏车原因可能是里程计别篡改,也可能是经销商也无法处理的机械问题,也可能是汽车名称问题或其它难以预测的问题。坏车对于经销商是一个巨大的花费,包括在运输费,修理费,和二手车市场损失费等
1.2研究问题
预测在拍卖平台购买的汽车是否是一个坏车?
1.3研究目标
模型可以得到哪个车更可能为坏车并为经销商提供一个真实的值,为客户提供一个最佳库存选择。
第2章数据分析
2.1特征清单
RefID | 赋予每辆汽车独一无二的名字 | |
IsBadBuy | 购买是否为坏车的标识 | |
PurchDate | 在拍卖平台的购买日期 | |
Auction | 所购汽车的拍卖平台 | |
VehYear | 汽车制造年限 | |
VehicleAge | 汽车使用年限 | |
Make | 汽车制造商 | |
Model | 汽车模型 | |
Trim | 汽车配置水平 | |
SubModel | 汽车子模型 | |
Color | 汽车颜色 | |
Transmission | 汽车变速器形式(自动、手动) | |
WheelTypeID | 汽车轮胎类型ID | |
WheelType | 轮胎类型 | |
VehOdo | 汽车里程表读数 | |
Nationality | 制造商所属国家 | |
Size | 汽车尺寸类别(紧凑型、SUV) | |
TopThreeAmericanName | 确定制造商是否是美国三大制造商之一 | |
PRIMEUNIT | 确定该汽车需求比普通车型要高 | |
AcquisitionType | 汽车如何获得(拍卖平台购买、交易) | |
AUCGUART | 汽车拍卖所提供的等级保护(绿灯保证/可仲裁、黄色警示/问题、红灯出售) | |
KickDate | 汽车是坏的返回拍卖平台的日期 | |
BYRNO | 购买者购买汽车分配的标识 | |
VNZIP | 汽车购买的邮政编码 | |
VNST | 汽车购买状态 | |
VehBCost | 汽车购置成本 | |
IsOnlineSale | 汽车是否初次在网上售卖标识 | |
WarrantyCost | 保修价格(期限=36个月,保险费=36K) | |
MMRAcquisitionAuctionAveragePrice | 平均条件该汽车购置价格 | |
MMRAcquisitionAuctionCleanPrice | 在平均条件该汽车的平均购置价格 | |
MMRAcquisitionRetailAveragePrice | 平均条件该汽车在零售市场购置价格 | |
MMRAcquisitonRetailCleanPrice | 在平均条件该汽车在零售市场的平均购置价格 | |
MMRCurrentAuctionAveragePrice | 当前条件该汽车平均购置价格 | |
MMRCurrentAuctionCleanPrice | 该汽车在上述条件下当前购置价格 | |
MMRCurrentRetailAveragePrice | 当前条件该汽车在零售市场平均购置价格 | |
MMRCurrentRetailCleanPrice | 该汽车在上述条件下当前在零售市场购置价格 |
2.2分析过程
2.2.1数据预处理
1、读取训练数据:
通过pandas库读取CSV文件,并将读取文件转化为表格存储形式。
1、import pandas as pd
2、train_data=pd.read_csv('E:/Scikit-Learn/data/automotive_lemons/training.csv',
na_values=['NA'])
第一行导入pandas库,第二行使用库中read_csv导入训练数据,na_values表示对空数据填充NA
2、去除标签特征:
本例中IsBadBuy为判断标签,因此需要从原始数据类中剔除。
1、deltrain_data['IsBadBuy']
del为删除指定类的数据
3、字符标签转化为数字标签:
字符数值转化是处理中常用到的,因为一些算法中无法对字符型数据进行分类训练,参考网址:
python数据预处理之将类别数据转换为数值的方法:https://edu.aliyun.com/a/2854
LabelEncoder和OneHotEncoder在特征工程中的应用:
https://blog.csdn.net/accumulate_zhang/article/details/78510571
1、from sklearn.preprocessing import LabelEncoder
2、for key in train_data:
3、 if(str(train_data[key][1]).isdigit()):
4、 continue
5、 else:
6、 train_data[key]=train_data[key].fillna('NaN')
7、 test_data[key]=test_data[key].fillna('NaN')
8、le_train=LabelEncoder()
9、le_test=LabelEncoder()
10、train=le_train.fit(train_data[key])
11、test=le_test.fit(test_data[key])
12、train_data[key]=train.transform(train_data[key])
13、test_data[key]=test.transform(test_data[key])
转换可以使用映射的方法,即自己编写每个类别所要映射的对应值,通过map来对字典变量进行映射,但当所要映射类别过多,特征很大时这种方法就不再适用。sklearn内部preprocessing库中有LabelEncoder()和OneHotEncoder()函数。LabelEncoder()将无序离散特征转换为整型,但转换后的数据其前后顺序关系会丢失。常见的就是颜色,转换后会用不同的整数值来替代不同的颜色,但颜色之间会有大小吗?OneHotEncoder()创建哑特征,对每一种颜色单独设为1其它设为0,打个比方红绿蓝,由一组颜色变量拓展为3组变量分别对应红绿蓝,红色对应为100蓝色对应为001。
Python机器学习:4.5 处理分类数据:http://www.aibbt.com/a/21100.html
4、数据归一化去均值
特征工程中「归一化」有什么作用:https://www.zhihu.com/question/20455227
1、from sklearn.preprocessing import StandardScaler
2、scale_train=StandardScaler()
3、scale_test=StandardScaler()
4、classes=train_data.columns
5、scaled_train=scale_train.fit(train_data.values)
6、scaled_test=scale_test.fit(test_data.values)
7、new_train=pd.DataFrame(scaled_train.transform(train_data),columns=classes)
8、new_test=pd.DataFrame(scaled_test.transform(test_data),columns=classes)
preprocessing含有StandardScaler()函数去均值和方差归一化。且是针对每一个特征维度来做的,而不是针对样本。即只针对列做变换。7、8行作用是将数据重新存储为一个表格,因为变换过程中是对数值进行变化。变换后会丢失标签。因此将标签预先提取后再重新加入。
5、数据降维
如何通俗易懂地解释「协方差」与「相关系数」的概念?:
https://www.zhihu.com/question/20852004
1、from sklearn.decomposition import PCA
2、pca_train=PCA(n_components=5)
3、model_train=pca_train.fit(new_train)
4、#pca_test=PCA(n_components=4)
5、#model_test=pca_test.fit(new_test)
6、PCA_train=pd.DataFrame(model_train.transform(new_train))
7、PCA_test=pd.DataFrame(model_train.transform(new_test))
第一行导入PCA函数,第二行n_components是指降维后的特征数,原先数据是33个特征降维后为5个,降维数的不同对后续结果有着影响。
机器学习(七):主成分分析PCA降维_Python:https://blog.csdn.net/u013082989/article/details/53792010
2.2.2数据分析
1、数据集的划分
推荐系统为什么要分测试集和训练集?https://www.zhihu.com/question/22872584
1、from sklearn.model_selection import train_test_split
2、(train_input,test_input,train_class,test_class)\
3、=train_test_split(PCA_train,Bad_train,train_size=0.75,random_state=1)
train_test_split是用来划分数据集的函数第一项为输入数据,第二项为输入数判断标签,数据划分百分比为3/4
2、逻辑回归模型训练
逻辑回归:https://blog.csdn.net/pakko/article/details/37878837
1、from sklearn.linear_model.logistic import LogisticRegression
2、from sklearn.model_selection import cross_val_score
3、classifier=LogisticRegression()
4、classifier.fit(train_input,train_class)
使用模型为逻辑回归模型,fit为训练的意思
3、ROC曲线绘制
深度探讨机器学习中的ROC和PR曲线:https://blog.csdn.net/taoyanqi8932/article/details/54409314
1、from sklearn.metrics import roc_curve,auc
2、probas=classifier.predict_proba(train_input)
3、fpr,tpr,thresholds=roc_curve(train_class,probas[:,1])
4、roc_auc=auc(fpr,tpr)
5、plt.plot(fpr,tpr,label='ROCfold 1(area=%0.2f)'%(roc_auc))
ROC曲线是用于评估分类器性能好坏的曲线,第一项为判断输出,第二项为判断阀值predict_proba结果输出第一列为0的可能性,第二列为1的可能性,取第二列,auc是用于求面积,面积越大则性能越好。
4、交叉验证
1、from sklearn.model_selection import cross_val_score
2、scores=cross_val_score(classifier,train_input,train_class,cv=5)
为什么要用交叉验证:https://blog.csdn.net/aliceyangxi1987/article/details/73532651
5、测试集测试
2.3结果分析
对模型的验证结果如下模型正确率还是很高,但测试过程遇到一个问题PCA降维设置为1-4正确率是100%,5向上正确率就变低开始出现预测错误的情况,但实际不是特征越多的预测效果应该越准确吗?对后续模型评估还有待学习。
ROC曲线如上图,可以看到曲线在开始有一个陡峭上升,这种波形是一个良好趋势,但实际面积为0.69,如果面积更大那性能会更好。但实际测试过程中发现一个问题面积变小,正确率反而高了?
第3章总结
第一次从头到尾完整的完成一次数据分析的过程,有几点不足:
1、在数据处理过程中,该如何处理数据,对于数据的点数特征该如何做出限制,已获得符合特征的数据。
2、数据处理过程中,所应用的方法局限性太大,对每种处理本质的探讨还不够深入,使用目前只是照搬照用。
3、模型测试,使用模型过程中本质原理理解不够深入,发现使用自带函数虽然方便,但太具有局限性,出现错误排查困难。
4、后续模型评估工作无从下手,模型正确性仅通过测试集测试,没有一个标准的评估流程,无法证明是否正确。
5、学习过程中遇到的问题未能详细记录,查阅资料未能及时保存。
以后的改进:
1、做到有用的资料及时保存,准备问题记录表
2、继续深入学习。
3、得到自己的模型评估标准流程
附录
完整代码
#!/usr/bin/env python
# coding:utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
##############
##数据预处理##
##############
##################################################
################读取训练数据######################
import pandas as pd
import numpy as np
train_data=pd.read_csv('E:/Scikit-Learn/data/automotive_lemons/training.csv',na_values=['NA'])
test_data=pd.read_csv('E:/Scikit-Learn/data/automotive_lemons/test.csv',na_values=['NA'])
##################################################
################去除无效特征######################
Bad_train=train_data['IsBadBuy']
del train_data['IsBadBuy']
#bad_car_data=car_data.loc[car_data['IsBadBuy']==1]
#good_car_data=car_data.loc[car_data['IsBadBuy']==0]
# print car_data.head()
#print bad_car_data.describe()
##################################################
###############字符数据转换为数值型###############
from sklearn.preprocessing importLabelEncoder
for key in train_data:
if(str(train_data[key][1]).isdigit()):
continue
else:
train_data[key]=train_data[key].fillna('NaN')
test_data[key]=test_data[key].fillna('NaN')
le_train=LabelEncoder()
le_test=LabelEncoder()
train=le_train.fit(train_data[key])
test=le_test.fit(test_data[key])
train_data[key]=train.transform(train_data[key])
test_data[key]=test.transform(test_data[key])
##################################################
################数据归一化去均值##################
from sklearn.preprocessing importStandardScaler
scale_train=StandardScaler()
scale_test=StandardScaler()
classes=train_data.columns
scaled_train=scale_train.fit(train_data.values)
scaled_test=scale_test.fit(test_data.values)
new_train=pd.DataFrame(scaled_train.transform(train_data),columns=classes)
new_test=pd.DataFrame(scaled_test.transform(test_data),columns=classes)
##################################################
###################数据降维#######################
from sklearn.decomposition import PCA
pca_train=PCA(n_components=5)
model_train=pca_train.fit(new_train)
# pca_test=PCA(n_components=4)
# model_test=pca_test.fit(new_test)
PCA_train=pd.DataFrame(model_train.transform(new_train))
PCA_test=pd.DataFrame(model_train.transform(new_test))
##################################################
##################分类标签添加####################
##################################################
##################处理数据绘图####################
import seaborn as sb
import matplotlib.pyplot as plt
# sb.pairplot(new_car,hue='IsBadBuy')
# plt.show()
##############
###数据分析###
##############
###################################################
###################数据集划分######################
from sklearn.model_selection importtrain_test_split
(train_input,test_input,train_class,test_class)\
=train_test_split(PCA_train,Bad_train,train_size=0.75,random_state=1)
###################################################
##################逻辑回归训练#####################
from sklearn.linear_model.logisticimport LogisticRegression
from sklearn.model_selection importcross_val_score
classifier=LogisticRegression()
classifier.fit(train_input,train_class)
print"==============================================="
print "=================模型训练结果=================="
print ("逻辑回归模型系数值如下:")
print classifier.coef_
print ("逻辑回归模型标准差如下:")
print np.std(classifier.coef_,ddof=1)
print ("逻辑回归模型残差和如下:")
print np.mean((classifier.predict(train_input)-train_class)**2)
###################################################
##################绘制ROC曲线######################
from sklearn.metrics importroc_curve,auc
probas=classifier.predict_proba(train_input)
fpr,tpr,thresholds=roc_curve(train_class,probas[:,1])
roc_auc=auc(fpr,tpr)
plt.plot(fpr,tpr,label='ROC fold1(area=%0.2f)'%(roc_auc))
plt.xlim([-0.05,1.05])
plt.ylim([-0.05,1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.legend(loc="lower right")
###################################################
####################交叉验证#######################
from sklearn.model_selection importcross_val_score
scores=cross_val_score(classifier,train_input,train_class,cv=5)
print"==============================================="
print ("交叉验证得分如下:")
print scores
###################################################
#################测试集测试#######################
test_classes=pd.read_csv('E:/Scikit-Learn/data/automotive_lemons/example_entry.csv',na_values=['NA'])
classes=test_classes['IsBadBuy']
predic=classifier.predict(PCA_test)
error_count=0
right_count=0
for i in range(1,len(classes)):
ifpredic[i]!=classes[i]:
error_count=error_count+1
else:
right_count=right_count+1
print"==============================================="
print "================测试集测试结果================="
print ("the right number is%d",right_count)
print ("the error number is%d",error_count)
printclassifier.score(PCA_test,classes)
print"==============================================="
plt.show()