数据集+源码+远程部署(+v:sybh0117):python机器学习 鸢尾花分类预测 详细教程 数据集+源码+远程部署

目录
介绍
鸢尾花分类预测是一个典型的机器学习问题,旨在通过鸢尾花的几个特征,比如花瓣和萼片的长度和宽度,来预测鸢尾花属于哪个种类。鸢尾花数据集通常被用作统计分类技术的测试案例,是模式识别领域的一个经典问题。
鸢尾花数据集主要包括三个类别:Setosa、Versicolour和Virginica,每个类别包括50个样本,因此总共有150个样本数据。每个样本的数据包含了四个特征(萼片长度、萼片宽度、花瓣长度、花瓣宽度),这些特征都是以厘米为单位的测量值。
进行鸢尾花分类预测的步骤通常包括以下几个方面:
- 数据预处理:包括清洗数据、处理缺失值、特征选择等步骤。
- 选择一个模型:根据问题的特点选择一个合适的机器学习模型,比如逻辑回归、K最近邻(KNN)、支持向量机(SVM)或决策树等。
- 训练模型:使用训练数据(通常是数据集的一部分)来训练选定的机器学习模型。
- 模型评估和验证:用测试数据(数据集的另一部分)来评估模型的性能,并调整模型参数直至获得满意的预测结果。
- 应用模型进行预测:使用训练好的模型对新的鸢尾花样本进行分类预测。
鸢尾花分类预测是入门机器学习和数据科学的绝佳案例,因为它的数据集规模适中,而且只涉及到少量的特征,使得新手也能够比较容易地理解问题和处理过程。
data = pd.read_csv('data.csv')
# 假设最后一列是目标变量
X = data.iloc[:, 1:-1] # 所有行,除了最后一列的所有列
y = data.iloc[:, -1] # 所有行,只有最后一列
# 把 X 和 y 转换为 DataFrame
X = pd.DataFrame(X)
y = pd.DataFrame(y)
# 打印信息查看
print(X)
print(y)
编辑
data = pd.read_csv('data.csv')
:这行代码读取一个名为'data.csv'的CSV文件,将其内容加载到data
这个DataFrame对象中。这个CSV文件包含了鸢尾花数据集,这个数据集可能包含多个特征列,用于描述鸢尾花(如萼片长度、宽度等),最后一列是目标变量,即鸢尾花的品种。X = data.iloc[:, 1:-1]
:这行代码用于选择特征变量。.iloc[:, 1:-1]
这部分是基于位置的索引,:
表示选择所有行,1:-1
则表示选择第二列到倒数第二列的所有列。这里假设数据集的第一列(索引为0的列)不是特征列,可能是数据的编号或者别的非特征信息,因此从第二列开始选择到最后一列之前为特征集X。换言之,这里忽略了第一列和最后一列,仅选择中间的列作为特征变量。y = data.iloc[:, -1]
:这行代码用于选择目标变量。iloc[:, -1]
基于位置的索引,:
表示选择所有行,-1
表示选择最后一列。这里的目标变量是指鸢尾花的品种,存储于最后一列。X = pd.DataFrame(X)
:尽管X已经是一个DataFrame对象,这行代码显式地再次将X转换为DataFrame。这可能是为了确保X确实是DataFrame类型,或者是出于清晰表达的目的,但从实际操作的角度来看,这行代码可能是多余的。y = pd.DataFrame(y)
:同样的,这行代码将y(目标变量)再次转换为DataFrame类型。和上一行代码类似,这也可能是出于确保数据类型或清晰表达的目的,虽然在大多数情况下可能是不必要的。
之前鸢尾花的特征为0,1,2,3,为了更加清晰了解数据,我们将鸢尾花的真实特征作为映射
X.columns = list(map(lambda x: 'feature' + str(x), X.columns))
编辑
数据处理
cate_cols = [] # 离散特征
num_cols = [] # 数值型特征
# 获取各个特征的数据类型
dtypes = X.dtypes
for col, dtype in dtypes.items():
if dtype == 'object':
cate_cols.append(col)
else:
num_cols.append(col)
数值型特征
class Num_Encoder(BaseEstimator, TransformerMixin):
def __init__(self, cols=[], fillna=False, addna=False):
self.fillna = fillna
self.cols = cols
self.addna = addna
self.na_cols = []
self.imputers = {}
def fit(self, X, y=None):
for col in self.cols:
if self.fillna:
self.imputers[col] = X[col].median()
if self.addna and X[col].isnull().sum():
self.na_cols.append(col)
print(self.na_cols, self.imputers)
return self
def transform(self, X, y=None):
df = X.loc[:, self.cols]
for col in self.imputers:
df[col].fillna(self.imputers[col], inplace=True)
for col in self.na_cols:
df[col + '_na'] = pd.isnull(df[col])
return df
离散型特征
class Cat_Encoder(BaseEstimator, TransformerMixin):
def __init__(self, cols, max_n_cat=7, onehot_cols=[], orders={}):
self.cols = cols
self.onehot_cols = onehot_cols
self.cats = {}
self.max_n_cat = max_n_cat
self.orders = orders
def fit(self, X, y=None):
df_cat = X.loc[:, self.cols]
for n, c in df_cat.items():
df_cat[n].fillna('NAN', inplace=True)
df_cat[n] = c.astype('category').cat.as_ordered()
if n in self.orders:
df_cat[n].cat.set_categories(self.orders[n], ordered=True, inplace=True)
cats_count = len(df_cat[n].cat.categories)
if cats_count <= 2 or cats_count > self.max_n_cat:
self.cats[n] = df_cat[n].cat.categories
if n in self.onehot_cols:
self.onehot_cols.remove(n)
elif n not in self.onehot_cols:
self.onehot_cols.append(n)
print(self.onehot_cols)
return self
def transform(self, df, y=None):
X = df.loc[:, self.cols]
for col in self.cats:
X[col].fillna('NAN', inplace=True)
X.loc[:, col] = pd.Categorical(X[col], categories=self.cats[col], ordered=True)
X.loc[:, col] = X[col].cat.codes
if len(self.onehot_cols):
df_1h = pd.get_dummies(X[self.onehot_cols], dummy_na=True)
df_drop = X.drop(self.onehot_cols, axis=1)
return pd.concat([df_drop, df_1h], axis=1)
return X
配置流水线
num_pipeline = Pipeline([
('num_encoder', Num_Encoder(cols=num_cols, fillna='median', addna=True)),
])
X_num = num_pipeline.fit_transform(X)
cat_pipeline = Pipeline([
('cat_encoder', Cat_Encoder(cols=cate_cols))
])
X_cate = cat_pipeline.fit_transform(X)
编辑
分割数据
将训练集和预测集按照2:8的比例分割
X = pd.concat([X_num, X_cate], axis=1)
print(X.shape, y.shape)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2022)
print('【训练集】', X_train.shape, y_train.shape)
print('【测试集】', X_test.shape, y_test.shape)
编辑
随机森林模型
rfc = RandomForestClassifier(n_estimators=100,
criterion='gini',
random_state=2022)
模型训练
rfc.fit(X_train, y_train)
编辑
验证训练集预测集
y_train_pred = rfc.predict(X_train)
y_test_pred = rfc.predict(X_test)
accuracy_train = metrics.accuracy_score(y_train, y_train_pred)
accuracy_test = metrics.accuracy_score(y_test, y_test_pred)
print('训练集的accuracy: ', accuracy_train)
print('测试集的accuracy: ', accuracy_test)
编辑
特征重要性
feature_importance = pd.DataFrame(rfc.feature_importances_.reshape(X.shape[1], 1), index=list(X.columns),
columns=['特征重要性'])
print(feature_importance)
编辑
混淆矩阵
confusion_matrix = metrics.confusion_matrix(y_train, y_train_pred)
df_matrix = pd.DataFrame(confusion_matrix, index=['setosa', 'versicolor', 'virginica'], columns=['setosa', 'versicolor', 'virginica'])
print(df_matrix)
编辑
AUC模型
y_train_proba = rfc.predict_proba(X_train)
y_test_proba = rfc.predict_proba(X_test)
auc_train = metrics.roc_auc_score(y_train, y_train_proba, multi_class ='ovr')
auc_test = metrics.roc_auc_score(y_test, y_test_proba, multi_class ='ovr')
print('训练集的AUC: ', auc_train)
print('测试集的AUC: ', auc_test)
编辑
AUC曲线
fpr, tpr, thres = metrics.roc_curve(y_test==1, y_test_proba[:, 1])
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.plot(fpr, tpr)
plt.title('ROC曲线')
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.show()
编辑
网格搜索
rfcmodel = RandomForestClassifier()
param_grid_rfr = {
"n_estimators": np.arange(50, 300, 50),
"min_samples_leaf": np.arange(1, 101, 30),
"max_depth": np.arange(2, 8, 2),
"max_leaf_nodes": np.arange(5, 20, 5)
}
rfcmodel_grid = GridSearchCV(estimator=rfcmodel,
param_grid=param_grid_rfr,
verbose=1,
n_jobs=-1,
cv=2)
rfcmodel_grid.fit(X_train, y_train)
print('【RFR】', rfcmodel_grid.best_score_)
编辑
best_modelrfc = RandomForestClassifier(n_estimators=rfcmodel_grid.best_estimator_.get_params()['n_estimators'],
min_samples_leaf=rfcmodel_grid.best_estimator_.get_params()['min_samples_leaf'],
max_depth=rfcmodel_grid.best_estimator_.get_params()['max_depth'],
max_leaf_nodes=rfcmodel_grid.best_estimator_.get_params()['max_leaf_nodes'])
best_modelrfc.fit(X_train, y_train)
编辑
y_train_pred = best_modelrfc.predict(X_train)
y_test_pred = best_modelrfc.predict(X_test)
accuracy_train = metrics.accuracy_score(y_train, y_train_pred)
accuracy_test = metrics.accuracy_score(y_test, y_test_pred)
print('训练集的accuracy: ', accuracy_train)
print('测试集的accuracy: ', accuracy_test)
编辑