数据科学导引——AdaBoost对红酒品质预测

2024-03-13 11:30

本文主要是介绍数据科学导引——AdaBoost对红酒品质预测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

数据科学导引——红酒品质预测

这个由于当时时间仓促,写的不好,看看就行,现在快考试了,也没时间在完善了,有空再说吧。

一、看看老师给的例题案例

二、检查数据

最近在弄的很多东西都有一个共同点,就是数据要先分析一波!不分析上来就做题,那么很大概率就是瞎弄,为什么?你要处理的东西你自己内心都不太清楚你就按照例题的方法去做你自己的问题,那么很容易出现问题的,例题虽然和题目很像,基本操作给人感觉都一样,但是他们终究只能是一个类型的两道题,之间一定会有差异性。所以拿到数据先观察一波。
在这里插入图片描述
在这里插入图片描述
可以看到一共12个属性,我们要做的事就是用AdaBoost对前11个数据进行分析然后给出第12个数据的预测结果。非常完美,思路清晰,再打开数据集看一看
在这里插入图片描述
……怎么说呢,我可能需要自己进行一下数据处理了,问题不大。我记得我之前写过一个txt转换为excel的,应该能用,实在不行在那个的基础上修改一下。

from openpyxl import Workbook, load_workbook
book_name_xlsx = r'D:\学习\数据科学导引\第五次作业\红酒品质数据集\data.xlsx'  # 文件路径,把文档路径复制过来即可
wb = Workbook()
wb.save(book_name_xlsx)
# 打开Excel
wb = load_workbook(book_name_xlsx)
# 创建工作簿,导入的新数据会存在当前excel文件下新建一个‘s’的sheet里
sheet = wb.create_sheet('Sheet')
aa = []
f = open(r'D:\学习\数据科学导引\第五次作业\红酒品质数据集\winequality-red.csv', encoding='utf-8')  # 将从文献上的表格数据贴到txt文档中,将txt文档路径复制到此,encoding='utf-8'——编码格式
for line in f.readlines():data = line.split('\n\t')for str in data:sub_str = str.split(';')  # 每个数据间是按什么划分的,我的是两个空格符aa.append(sub_str)
for i in range(len(aa)):sheet.append(aa[i])# 保存文件wb.save(book_name_xlsx)
print("题目写入数据成功!")

事实证明这串代码还是能跑的,只需要稍加修改便可以用到这个新的数据上了。虽然效率有点低,以后有空了写一个通用型的,顺带把效率提高一下,不然每次都要等那么久受不了。当然那都是后话了。

搞定了数据的问题,咱们就把数据读出来

red_wine = pd.read_excel('D:\学习\数据科学导引\第五次作业\红酒品质数据集\data.xlsx')#读取目标数据
print(red_wine.head())

在这里插入图片描述
检查数据中是否有空值

print(np.any(red_wine.isnull()))

结果:False

进行不平衡分析和异常值检测

在这里插入图片描述
可以看到各个品质的葡萄酒的数量是非常不平衡的,这以为这我们需要对其进行不平衡处理,关于不平衡样本的处理方法我是根据下面那个文章来的
https://blog.csdn.net/huangguohui_123/article/details/105706846

样本不均衡从数据规模的角度分为:

大数据分布不均衡:例如1000万条数据集中,50万条的小类别。

小数据分布不均衡:例如1000条数据集中,10条的小类别。此情况属于严重的数据样本分布不均衡。

可以清楚的看到这个是后者

不平衡的解决方法

1、抽样

1)过抽样

通过增加分类中少数类样本的数量来实现样本均衡,缺点在于:如果样本特征少则可能导致过拟合的问题。可通过在少数类中加入随机噪声、干扰数据或通过一定规则产生新的合成样本

#使用RandomUnderSampler进行欠抽样处理
from imblearn.under_sampling import RandomUnderSampler #欠抽样处理库RandomUnderSamplermodel_RandomUnderSampler=RandomUnderSampler()   #实例化
x_RandomUnderSampler_resampled,y_RandomUnderSampler_resampled=model_RandomUnderSampler.fit_sample(x,y)  #输入数据进行欠抽样处理
y_RandomUnderSampler_resampled=pd.DataFrame(y_RandomUnderSampler_resampled,columns=['label'])RandomUnderSampler_resampled=pd.concat([x_RandomUnderSampler_resampled,y_RandomUnderSampler_resampled],axis=1)  #将特征和标签重新拼接
group_data_RandomUnderSampler=RandomUnderSampler_resampled.groupby(['label'])['label'].count()   #查看标签类别个数
group_data_RandomUnderSampler

2)欠抽样

通过减少分类中多数类样本的数量来实现样本均衡,例如随机去掉一些多数类中的样本,缺点是会丢失多数类样本中的一些重要信息。

#使用RandomUnderSampler进行欠抽样处理
from imblearn.under_sampling import RandomUnderSampler #欠抽样处理库RandomUnderSamplermodel_RandomUnderSampler=RandomUnderSampler()   #实例化
x_RandomUnderSampler_resampled,y_RandomUnderSampler_resampled=model_RandomUnderSampler.fit_sample(x,y)  #输入数据进行欠抽样处理
y_RandomUnderSampler_resampled=pd.DataFrame(y_RandomUnderSampler_resampled,columns=['label'])RandomUnderSampler_resampled=pd.concat([x_RandomUnderSampler_resampled,y_RandomUnderSampler_resampled],axis=1)  #将特征和标签重新拼接
group_data_RandomUnderSampler=RandomUnderSampler_resampled.groupby(['label'])['label'].count()   #查看标签类别个数
group_data_RandomUnderSampler

经过RandomUnderSampler处理后的数据集,减少label=0的样本量,使得label=0的样本量和label=1的样本量相同,从而使分类样本得到平衡。

2、通过正负样本的惩罚权重

核心思想在于:不同样本数量的类别分别赋予不同的权重,小样本量类别权重高,大样本量类别权重低。

使用这种方法无需对样本本身做额外处理,只需在算法模型的参数中进行相应设置即可。如scikit-learn中的SVM为例,通过设置参数class_weight,针对不同类别来手动指定权重。该参数可设置为字典、None或字符串balanced三种模式:

字典:手动指定不同类别的权重,例如{1:10,0:1}

None:代表类别的

如果使用默认的balanced,SVM会将权重设置为与不同类别样本数量呈反比的权重来进行自动均衡处理,公式为:n_samples/n_classes*np.bincount(y)。例如本例:

import numpy as np1000/(2*np.bincount(y))
#使用SVM的权重调节处理不均衡样本
from sklearn.svm import SVC model_svm=SVC(class_weight='balanced')  #创建SVC对象并指定类别权重
model_svm.fit(x,y)

经过设置后,算法自动处理样本分类权重,无须用户做其他处理。要对新数据集做预测,只要调用model_svm模型对象的predict方法即可。

然后我们利用盒图对数据集中的数值型变量进行异常值检测,盒图示意如下:boxplot
在这里插入图片描述

我们先提取出数据集中的数值型变量,然后对所有的数值型变量按不同的目标变量值画出其盒图,如下所示:
在这里插入图片描述

f,axarr = plt.subplots(3,4,figsize=(20,15))
sns.set_context("notebook", font_scale=1.8) # 放大横纵坐标标记,更容易看清
sns.stripplot(x='"quality"',y='"fixed acidity"',data=red_wine,jitter=True,ax=axarr[0,0])
sns.boxplot(x='"quality"',y='"fixed acidity"',data=red_wine,ax=axarr[0,0])
sns.stripplot(x='"quality"',y='"volatile acidity"',data=red_wine,jitter=True,ax=axarr[0,1])
sns.boxplot(x='"quality"',y='"volatile acidity"',data=red_wine,ax=axarr[0,1])
sns.stripplot(x='"quality"',y='"citric acid"',data=red_wine,jitter=True,ax=axarr[0,2])
sns.boxplot(x='"quality"',y='"citric acid"',data=red_wine,ax=axarr[0,2])
sns.stripplot(x='"quality"',y='"residual sugar"',data=red_wine,jitter=True,ax=axarr[0,3])
sns.boxplot(x='"quality"',y='"residual sugar"',data=red_wine,ax=axarr[0,3])
sns.stripplot(x='"quality"',y='"chlorides"',data=red_wine,jitter=True,ax=axarr[1,0])
sns.boxplot(x='"quality"',y='"chlorides"',data=red_wine,ax=axarr[1,0])
sns.stripplot(x='"quality"',y='"free sulfur dioxide"',data=red_wine,jitter=True,ax=axarr[1,1])
sns.boxplot(x='"quality"',y='"free sulfur dioxide"',data=red_wine,ax=axarr[1,1])
sns.stripplot(x='"quality"',y='"total sulfur dioxide"',data=red_wine,jitter=True,ax=axarr[1,2])
sns.boxplot(x='"quality"',y='"total sulfur dioxide"',data=red_wine,ax=axarr[1,2])
sns.stripplot(x='"quality"',y='"density"',data=red_wine,jitter=True,ax=axarr[1,3])
sns.boxplot(x='"quality"',y='"density"',data=red_wine,ax=axarr[1,3])
sns.stripplot(x='"quality"',y='"pH"',data=red_wine,jitter=True,ax=axarr[2,0])
sns.boxplot(x='"quality"',y='"pH"',data=red_wine,ax=axarr[2,0])
sns.stripplot(x='"quality"',y='"sulphates"',data=red_wine,jitter=True,ax=axarr[2,1])
sns.boxplot(x='"quality"',y='"sulphates"',data=red_wine,ax=axarr[2,1])
sns.stripplot(x='"quality"',y='"alcohol"',data=red_wine,jitter=True,ax=axarr[2,2])
sns.boxplot(x='"quality"',y='"alcohol"',data=red_wine,ax=axarr[2,2])
plt.tight_layout()

我们可以从盒图中看出 fixed acidity、chiorides、residual sugar、free sulfur dioxide、density 这几个属性异常值较多我们在之后的训练中会将这些异常值去除掉,并讨论去除异常值与不去除异常值对模型训练的影响。

我们画出点对图来分析变量之间的相关关系:

sns.pairplot(red_wine,vars = ['"fixed acidity"','"citric acid"','"free sulfur dioxide"','"total sulfur dioxide"','"density"','"pH"'],hue='"quality"',diag_kind='kde',diag_kws=dict(shade=True),size=6)
plt.savefig("./1.jpg")
plt.show()

在这里插入图片描述
这里本来应该是一个11*11的图,但是我提前观察了一下,将一下没有太明显相关性的变量删除了,这张图上可以看出有几个变量之间存在着明显的线性相关性

由于这里没有名义型变量,所以不对其进行处理,如果有需要这边又一串代码可以拿去用于处理名义型变量

f, axarr = plt.subplots(11, figsize=(20, 35))
plt.xticks(fontsize=0.01)
sns.countplot(x='"fixed acidity"', hue='"quality"', data=red_wine, ax=axarr[0])
sns.countplot(x='"volatile acidity"', hue='"quality"', data=red_wine, ax=axarr[1])
sns.countplot(x='"citric acid"', hue='"quality"', data=red_wine, ax=axarr[2])
sns.countplot(x='"residual sugar"', hue='"quality"', data=red_wine, ax=axarr[3])
sns.countplot(x='"chlorides"', hue='"quality"', data=red_wine, ax=axarr[4])
sns.countplot(x='"free sulfur dioxide"', hue='"quality"', data=red_wine, ax=axarr[5])
sns.countplot(x='"total sulfur dioxide"', hue='"quality"', data=red_wine, ax=axarr[6])
sns.countplot(x='"density"', hue='"quality"', data=red_wine, ax=axarr[7])
sns.countplot(x='"pH"', hue='"quality"', data=red_wine, ax=axarr[8])
sns.countplot(x='"sulphates"', hue='"quality"', data=red_wine, ax=axarr[9])
sns.countplot(x='"alcohol"', hue='"quality"', data=red_wine, ax=axarr[10])
plt.tight_layout()
plt.savefig("./2.jpg")
plt.show()

数据清洗
1、检查是否有空数据

print(red_wine.any().isnull())

在这里插入图片描述
可以看到不存在缺失值。
这里做出这些数据的相关系数矩阵

pMatric =np.corrcoef(red_wine,rowvar=False)在这里插入图片描述
可以直观的看出不同变量之间的相关性。
通过观察可以看到,3,5,8,与红酒最后的评分没有太大的相关性
(0,1),(0,7),(0,8)之间有着比较强的相关性。
因此我决定删除0,3,5,8这几个变量

red_wine_cl = red_wine.copy()   #创建一份拷贝
target = red_wine_cl['"quality"'].copy()
# #去掉一些列
red_wine_cl.drop('"fixed acidity"',axis=1,inplace=True)
red_wine_cl.drop('"residual sugar"',axis=1,inplace=True)
red_wine_cl.drop('"free sulfur dioxide"',axis=1,inplace=True)
red_wine_cl.drop('"pH"',axis=1,inplace=True)

下面我们将定义用于异常值检测的函数,用于模型训练前去除异常值:

#定义异常值检测函数
def detect_outliers(series,whis=1.5):q75,q25 = np.percentile(series,[75,25])iqr = q75 - q25return ~((series - series.median()).abs() <= (whis * iqr))

数据集的划分
这里可以看到我按照三七分划分了数据集

x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3)

利用随机森林选出最重要的特征-Top 3
由于本样本属性较少就选三个特征属性

model = RandomForestClassifier()
model.fit(X, Y)feature_imp = pd.DataFrame(model.feature_importances_, index=X.columns, columns=["importance"])
feat_rf_3 = feature_imp.sort_values("importance", ascending=False).head(3).index
print(list(feat_rf_3))

[‘“alcohol”’, ‘“total sulfur dioxide”’, ‘“sulphates”’]
可以看到红酒的品质由以上三个变量主要决定

利用 χ2 检验进行单变量的特征选择-Top 20

#首先对变量进行0-1标准化
X_minmax = MinMaxScaler(feature_range=(0,1)).fit_transform(X)
X_scored = SelectKBest(score_func=chi2, k='all').fit(X_minmax, Y)
feature_scoring = pd.DataFrame({'feature': X.columns,'score': X_scored.scores_})
feat_chi2_20 = feature_scoring.sort_values('score', ascending=False).head(20)['feature'].values
list(feat_chi2_20)

[‘“alcohol”’, ‘“volatile acidity”’, ‘“citric acid”’]
容易看出 χ2 检验得到的变量重要程度排序与随机森林得到的重要程度排序不同,下面我们再试试RFE方法。

利用RFE方法选择特征-Top 3
RFE叫做递归特征排除法,是Recursive Feature Elimination的简写,也是一种常用的特征选择方法。

rfe = RFE(LogisticRegression(), 20)
rfe.fit(X, Y)
feature_rfe_scoring = pd.DataFrame({'feature': X.columns,'score': rfe.ranking_})
feat_rfe_20 = feature_rfe_scoring[feature_rfe_scoring['score'] == 1]['feature'].values
list(feat_rfe_20)

[‘“volatile acidity”’, ‘“chlorides”’, ‘“sulphates”’]
也不一样
我们将以上三种方式得到的Top 3小结一下:

feature_scoring = pd.DataFrame({'feat_rf_20': feat_rf_20,'feat_chi2_20': feat_chi2_20,'feat_rfe_20': feat_rfe_20})
feature_scoring

[‘“volatile acidity”’, ‘“chlorides”’, ‘“sulphates”’]
feat_rf_20 feat_chi2_20 feat_rfe_20
0 “alcohol” “alcohol” “volatile acidity”
1 “total sulfur dioxide” “volatile acidity” “chlorides”
2 “sulphates” “citric acid” “sulphates”

我们将以上几种方式联合起来进行特征选择:

features = np.hstack([feat_var_threshold, feat_rf_3,feat_chi2_3,feat_rfe_3])
features = np.unique(features)
print('Final features set:\n')
for f in features:print("-{}".format(f))

结果如下
Final features set:

-“alcohol”
-“chlorides”
-“citric acid”
-“sulphates”
-“total sulfur dioxide”
-“volatile acidity”

4.PCA降维
由于本人的维数不是很高,所以不要需要再降维了,再将就没了。这里把方法粘贴一下
根据第三部分特征选择得到的变量重新整理数据框训练集kobe_cl和测试集kobe_submit:

kobe_cl = kobe_cl.ix[:, features]
kobe_submit = kobe_submit.ix[:, features]
X = X.ix[:, features]

print(‘完整数据集shape: {}’.format(kobe_cl.shape))
print(‘测试集shape: {}’.format(kobe_submit.shape))
print(‘训练集shape: {}’.format(X.shape))
print(‘目标标签shape: {}’.format(Y.shape))
完整数据集shape: (30697, 63)
测试集shape: (5000, 63)
训练集shape: (25697, 63)
目标标签shape: (25697,)
62个变量过多,我们需要在模型训练前进行降维,使得维度减为8:

components = 8
pca = PCA(n_components = components).fit(X)
我们来看一下每个变量对目标变量方差的解释程度:

pca_variance_explained_df = pd.DataFrame({
“component”: np.arange(1, components+1),
“variance_explained”: pca.explained_variance_ratio_
})
ax = sns.barplot(x=‘component’,
y=‘variance_explained’,
data=pca_variance_explained_df,
palette=“Set1”, )
ax.set_title(“PCA - Variance explained”)
<matplotlib.text.Text at 0x11ff0acf8>
在这里插入图片描述

我们只取前两个主成分,命名为x1和x2,并在二维特征空间中画出散点图:

X_pca = pd.DataFrame(pca.transform(X)[:,:2])
X_pca[‘target’] = Y.values
X_pca.columns = [“x1”, “x2”, “target”]
sns.lmplot(‘x1’,‘x2’,
data=X_pca,
hue=“target”,
fit_reg=False,
markers=[“o”, “x”],
palette=“Set1”,
size=6,
)
<seaborn.axisgrid.FacetGrid at 0x1228e6550>
在这里插入图片描述

可以看出主成分x1对target的影响,在 [−70,−20] 范围内几乎全为投失的情况,在 [−20,20] 部分为投中,部分为投失,而x2对投球的决定作用要比x1小非常多。

5.AdaBoost模型训练

这里直接套用 AdaBoostClassifier训练


model = AdaBoostClassifier(n_estimators=6, algorithm='SAMME', random_state=0, learning_rate=1)# 训练模型
model.fit(x_train, y_train)
# 获得 训练集和测试集 得分
print(model.score(x_train, y_train))
print(model.score(x_test, y_test))

在这里插入图片描述
这里呢我们再用其他几个模型比较一下,看看其他的性能如何

结果如下:
LR: (0.569) +/- (0.008)
LDA: (0.587) +/- (0.019)
K-NN: (0.525) +/- (0.017)
CART: (0.583) +/- (0.011)
NB: (0.574) +/- (0.034)

可以直接的看到LR,LDA,CART ,NB比这个模型要优秀

# 模型包括逻辑回归、线性判别分析、K近邻、决策树和朴素贝叶斯
models = []
models.append(('LR', LogisticRegression()))
models.append(('LDA', LinearDiscriminantAnalysis()))
models.append(('K-NN', KNeighborsClassifier(n_neighbors=5)))
models.append(('CART', DecisionTreeClassifier()))
models.append(('NB', GaussianNB()))
# 对每个模型计算其cross_cal_score
results = []
names = []
for name, model in models:cv_results = cross_val_score(model, x_train, y_train )results.append(cv_results)names.append(name)print("{0}: ({1:.3f}) +/- ({2:.3f})".format(name, cv_results.mean(), cv_results.std()))

这篇关于数据科学导引——AdaBoost对红酒品质预测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/804719

相关文章

Redis的数据过期策略和数据淘汰策略

《Redis的数据过期策略和数据淘汰策略》本文主要介绍了Redis的数据过期策略和数据淘汰策略,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录一、数据过期策略1、惰性删除2、定期删除二、数据淘汰策略1、数据淘汰策略概念2、8种数据淘汰策略

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

Python给Excel写入数据的四种方法小结

《Python给Excel写入数据的四种方法小结》本文主要介绍了Python给Excel写入数据的四种方法小结,包含openpyxl库、xlsxwriter库、pandas库和win32com库,具有... 目录1. 使用 openpyxl 库2. 使用 xlsxwriter 库3. 使用 pandas 库

SpringBoot定制JSON响应数据的实现

《SpringBoot定制JSON响应数据的实现》本文主要介绍了SpringBoot定制JSON响应数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录前言一、如何使用@jsonView这个注解?二、应用场景三、实战案例注解方式编程方式总结 前言

使用Python在Excel中创建和取消数据分组

《使用Python在Excel中创建和取消数据分组》Excel中的分组是一种通过添加层级结构将相邻行或列组织在一起的功能,当分组完成后,用户可以通过折叠或展开数据组来简化数据视图,这篇博客将介绍如何使... 目录引言使用工具python在Excel中创建行和列分组Python在Excel中创建嵌套分组Pyt

在Rust中要用Struct和Enum组织数据的原因解析

《在Rust中要用Struct和Enum组织数据的原因解析》在Rust中,Struct和Enum是组织数据的核心工具,Struct用于将相关字段封装为单一实体,便于管理和扩展,Enum用于明确定义所有... 目录为什么在Rust中要用Struct和Enum组织数据?一、使用struct组织数据:将相关字段绑

在Mysql环境下对数据进行增删改查的操作方法

《在Mysql环境下对数据进行增删改查的操作方法》本文介绍了在MySQL环境下对数据进行增删改查的基本操作,包括插入数据、修改数据、删除数据、数据查询(基本查询、连接查询、聚合函数查询、子查询)等,并... 目录一、插入数据:二、修改数据:三、删除数据:1、delete from 表名;2、truncate

Java实现Elasticsearch查询当前索引全部数据的完整代码

《Java实现Elasticsearch查询当前索引全部数据的完整代码》:本文主要介绍如何在Java中实现查询Elasticsearch索引中指定条件下的全部数据,通过设置滚动查询参数(scrol... 目录需求背景通常情况Java 实现查询 Elasticsearch 全部数据写在最后需求背景通常情况下

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

将sqlserver数据迁移到mysql的详细步骤记录

《将sqlserver数据迁移到mysql的详细步骤记录》:本文主要介绍将SQLServer数据迁移到MySQL的步骤,包括导出数据、转换数据格式和导入数据,通过示例和工具说明,帮助大家顺利完成... 目录前言一、导出SQL Server 数据二、转换数据格式为mysql兼容格式三、导入数据到MySQL数据