1. 首页
  2. 令爷课程

Python数据分析7步(Iris数据集)

数据:iris.csv

Python数据分析7步

graph LR
    A[1导入库] --> B[2导入数据]
    B --> C[3数据探索与处理]
    C --> D[4数据可视化]
    D --> E[5特征工程]
    E --> F[6模型训练与评估]
    F --> G[7预测新数据]

1 导入库

import pandas as pd  # 数据处理和分析库
import numpy          # 科学计算库
import matplotlib.pyplot as plt  # 绘图库
import seaborn as sns  # 基于matplotlib的数据可视化库

from sklearn.model_selection import train_test_split  # 用于数据集分割的模块
from sklearn import preprocessing  # 数据预处理模块,如标准化、归一化等
from sklearn.metrics import accuracy_score  # 用于计算模型准确率的函数
from sklearn.datasets import load_iris  # 用于加载内置数据集的模块
from sklearn.neighbors import KNeighborsClassifier  # K近邻分类器

2 导入数据

# 从CSV文件中读取Iris数据集
data = pd.read_csv('Iris数据集/iris.csv')

# 其他方法:用于从Excel文件读取数据和从sklearn加载内置的Iris数据集
# data = pd.read_excel('data.xlsx')  # 从Excel文件读取数据,需要安装openpyxl库
# data = load_iris()  # 从sklearn.datasets模块加载内置的Iris数据集

Iris数据集是一个经典的多变量数据集,由英国统计学家和生物学家罗纳德·费舍尔(Ronald Fisher)在1936年引入,用于展示他的线性判别分析方法。这个数据集包含了三种不同鸢尾花(Iris)的测量数据,具体是:

  1. 山鸢尾(Iris Setosa)
  2. 变色鸢尾(Iris Versicolour)
  3. 维吉尼亚鸢尾(Iris Virginica)

每种鸢尾花有50个样本,总共150个样本。每个样本包含以下四个特征:

  • 花萼长度(单位:厘米)
  • 花萼宽度(单位:厘米)
  • 花瓣长度(单位:厘米)
  • 花瓣宽度(单位:厘米)

这些特征被用来预测或分类鸢尾花的种类。数据集的第五列是类别标签,用于指示每个样本属于上述三种鸢尾花中的哪一种。

Iris数据集因其简单性和易于理解的特点,常被用作机器学习和统计分类算法的教学和测试数据集。它可以帮助初学者快速上手,理解分类问题和模型的基本构建过程。此外,由于数据集中的样本数量适中,它也适合用来演示各种机器学习算法的效果,如决策树、支持向量机、随机森林等。

花萼长度(cm) 花萼宽度(cm) 花瓣长度(cm) 花瓣宽度(cm) 品种
Sepal Length Sepal Width Petal Length Petal Width Species
5.1 3.5 1.4 0.2 Setosa
4.9 3.0 1.4 0.2 Setosa
4.7 3.2 1.3 0.2 Setosa
4.6 3.1 1.5 0.2 Setosa
5.0 3.6 1.4 0.2 Setosa

三种鸢尾花的特征主要体现在它们的花萼和花瓣的尺寸上。以下是每种鸢尾花的特征概述:

  1. 山鸢尾(Iris Setosa)
    • 花萼长度:通常较短,一般在2.0到3.5厘米之间。
    • 花萼宽度:相对较窄,宽度大约在0.2到0.5厘米。
    • 花瓣长度:较短,通常在1.0到1.8厘米。
    • 花瓣宽度:非常窄,宽度在0.1到0.3厘米。
  2. 变色鸢尾(Iris Versicolour)
    • 花萼长度:中等长度,大约在3.0到5.0厘米。
    • 花萼宽度:比山鸢尾宽,宽度在0.6到1.0厘米。
    • 花瓣长度:中等长度,通常在1.0到2.5厘米。
    • 花瓣宽度:比山鸢尾宽,宽度在0.3到1.0厘米。
  3. 维吉尼亚鸢尾(Iris Virginica)
    • 花萼长度:较长,一般在4.0到7.0厘米。
    • 花萼宽度:较宽,宽度在1.0到1.8厘米。
    • 花瓣长度:较长,通常在1.5到3.5厘米。
    • 花瓣宽度:较宽,宽度在0.5到1.5厘米。

这些特征的数值范围可以帮助我们区分不同种类的鸢尾花。在实际的数据分析和机器学习应用中,这些特征被用来构建模型,以预测未知样本的类别。通过训练模型识别这些特征,可以对新的鸢尾花样本进行分类,判断它们属于哪一种鸢尾花。这种类型的数据集对于理解特征选择、模型构建和评估分类算法的性能非常有帮助。

3 数据探索与处理

# 数据预览
data.info()

# 数据前5行
data.head()

# 统计信息
data. describe()

# 删除重复
data.drop_duplicates (inplace=True)

# 查看空值所在列
data.isnull().sum()

# 删除为空的行或将空值填充为0
data = data.dropna ( )
#data = data. fillna (0)

4 数据可视化

# 折线图
data['列名'].plot()
# 直方图
data['列名'].hist(bins=10)
# 散点图
data.plot(kind='scatter',X='列名',Y='列名')
# 热力图
sns.heatmap(data.corr())
# 折线图:展示不同种类鸢尾花的花瓣长度平均值
plt.figure(figsize=(10, 6))
# 根据种类分组并计算每个种类的花瓣长度平均值
data.groupby('Species')['Petal.Length'].mean().plot()

# 直方图:展示花萼长度的分布
plt.figure(figsize=(10, 6))
#data['Species'].hist(bins=5)
data['Sepal.Length'].hist()

# 散点图:展示两个特征之间的关系,例如花萼长度和花萼宽度
# 需要替换'列名1'和'列名2'为您数据集中相应的列名
plt.figure(figsize=(10, 6))
data.plot(kind='scatter', x='Sepal.Length', y='Sepal.Width')

# 热力图:展示不同特征之间的相关性
# 使用data.corr()计算相关系数矩阵,并用sns.heatmap()绘制热力图
plt.figure(figsize=(10, 6))
numerical_data = data.select_dtypes(include=[float])
sns.heatmap(numerical_data.corr())

# 箱线图
plt.figure(figsize=(10, 6))
sns.boxplot(x='Species', y='Petal.Length', data=data)

5 特征工程

# 类别数据编码
data['编码后的列名'] = pd.get_dummies(df['类别列名'])

# 新增特征
data['新特征列名'] = data['某列'] * data['某列']

# 筛选特征
features = ['某列','某列','某列']
data = data[features]

# 数据标准化
scaler = preprocessing.StandardScaler()
data['需要标准化的列名'] = scaler.fit_transform(data[['需要标准化的列名']])
# 类别数据编码
# 对'Species'进行独热编码
data = pd.get_dummies(data, columns=['Species'])

# 新增特征
# 计算花萼长度和宽度的乘积
data['Sepal_Area'] = data['Sepal.Length'] * data['Sepal.Width']

# 选择特征
features = ['Sepal.Length', 'Sepal.Width', 'Petal.Length', 'Petal.Width', 'Sepal_Area']

# 数据标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
data[features] = scaler.fit_transform(data[features])

# 显示处理后的数据集的前几行
print(data.head())

6 模型训练与评估

x, y = data[features], data[' reslut ']

# 分割数据
train_x, test_x, train_y,test_y = train_test_split(x,y,
                                                   test_size = 0.25, random_state = 33)

# 构造模型
knn = KNeighborsClassifier()

# 模型训练
knn. fit (train_x, train_y)

# 模型预测和评估
predict_y = knn.predict (test_x)
print ('KNN准确率: {}'.format(accuracy_score(test_y, predict_y)))
# 选择特征和目标变量
X = data[features]
y = data['Species_setosa']  # 或者选择 'Species_versicolor' 或 'Species_virginica'

# 分割数据
train_x, test_x, train_y, test_y = train_test_split(X, y, test_size=0.25, random_state=33)

# 构造模型
knn = KNeighborsClassifier()

# 模型训练
knn.fit(train_x, train_y)

# 模型预测和评估
predict_y = knn.predict(test_x)
print('KNN准确率: {}'.format(accuracy_score(test_y, predict_y)))

#交叉验证来更好地评估模型性能
from sklearn.model_selection import cross_val_score
cv_scores = cross_val_score(knn, X, y, cv=5)
print("交叉验证平均准确率: {:.2f} (+/- {:.2f})".format(cv_scores.mean(), cv_scores.std() * 2))

#决策树或随机森林,来比较不同模型的性能
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
dt = DecisionTreeClassifier(random_state=33)
rf = RandomForestClassifier(random_state=33)
dt.fit(train_x, train_y)
rf.fit(train_x, train_y)
print('决策树准确率: {}'.format(accuracy_score(test_y, dt.predict(test_x))))
print('随机森林准确率: {}'.format(accuracy_score(test_y, rf.predict(test_x))))

7 预测新数据

# 创建新的鸢尾花数据用于预测
new_data = pd.DataFrame({
    'Sepal.Length': [5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9],
    'Sepal.Width':  [3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1],
    'Petal.Length': [1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5],
    'Petal.Width':  [0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1]
})

# 对新数据进行特征工程
new_data['Sepal_Area'] = new_data['Sepal.Length'] * new_data['Sepal.Width']

# 确保新数据的列顺序与训练数据相同
new_data = new_data[features]

# 对新数据进行标准化,使用与训练数据相同的 scaler
new_data_scaled = pd.DataFrame(scaler.transform(new_data), columns=features)

# 使用训练好的模型进行预测
predictions = knn.predict(new_data_scaled)

# 将预测结果添加到新数据中
new_data['Predicted_Species'] = predictions

# 将预测结果转换回原始的种类名称
species_mapping = {0: '非山鸢尾', 1: '山鸢尾(Setosa)'}
new_data['Predicted_Species'] = new_data['Predicted_Species'].map(species_mapping)

print("预测结果:")
print(new_data)

# 结果解读
print("\n结果解读:")
for i, row in new_data.iterrows():
    print(f"\n样本 {i+1}:")
    print(f"  特征: 花萼长度 = {row['Sepal.Length']}cm, 花萼宽度 = {row['Sepal.Width']}cm, "
          f"花瓣长度 = {row['Petal.Length']}cm, 花瓣宽度 = {row['Petal.Width']}cm")
    print(f"  预测结果: {row['Predicted_Species']}")

    if row['Predicted_Species'] == 'setosa':
        if row['Petal.Length'] < 2.0 and row['Petal.Width'] < 0.5:
            print("  解读: 这是一个典型的山鸢尾(Setosa)样本。山鸢尾通常有较短的花瓣。")
        else:
            print("  解读: 模型将其分类为山鸢尾(Setosa),但其特征不太典型。这可能是一个有趣的案例,需要进一步调查。")
    else:
        if row['Petal.Length'] > 3.0 and row['Petal.Width'] > 1.0:
            print("  解读: 这是一个典型的非山鸢尾样本,可能是变色鸢尾(Versicolor)或维吉尼亚鸢尾(Virginica)。")
        else:
            print("  解读: 模型认为这不是山鸢尾(Setosa),但其特征不太典型。这可能是一个边界案例或异常样本。")

8 完整示例

import pandas as pd
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler

# 创建一个包含所有三种鸢尾花品种的示例数据集
data = pd.DataFrame({
    'Sepal.Length': [5.1, 6.3, 7.0, 4.9, 5.0, 6.5, 5.5, 5.2, 5.4, 6.7],
    'Sepal.Width':  [3.5, 2.9, 3.2, 2.4, 3.3, 3.8, 2.3, 3.4, 3.9, 3.1],
    'Petal.Length': [1.4, 4.9, 5.5, 3.3, 1.5, 2.8, 4.0, 1.4, 1.3, 5.6],
    'Petal.Width':  [0.2, 1.5, 2.1, 1.0, 0.3, 0.7, 1.3, 0.2, 0.4, 2.4],
    'Species':      ['setosa', 'versicolor', 'virginica', 'versicolor', 'setosa', 
                     'versicolor', 'versicolor', 'setosa', 'setosa', 'virginica']
})

# 特征选择
features = ['Sepal.Length', 'Sepal.Width', 'Petal.Length', 'Petal.Width', 'Sepal_Area']

# 数据预处理函数
def preprocess_data(data, features, scaler=None):
    data['Sepal_Area'] = data['Sepal.Length'] * data['Sepal.Width']
    data_selected = data[features]

    if scaler is None:
        scaler = StandardScaler()
        data_scaled = pd.DataFrame(scaler.fit_transform(data_selected), columns=features)
    else:
        data_scaled = pd.DataFrame(scaler.transform(data_selected), columns=features)

    return data_scaled, scaler

# 对训练数据进行预处理
data_scaled, scaler = preprocess_data(data, features)

# 选择特征和目标变量
X = data_scaled
y = data['Species']

# 分割数据
train_x, test_x, train_y, test_y = train_test_split(X, y, test_size=0.2, random_state=42)

# 构造模型
knn = KNeighborsClassifier(n_neighbors=3)

# 模型训练
knn.fit(train_x, train_y)

# 模型预测和评估
predict_y = knn.predict(test_x)
print('KNN准确率: {}'.format(accuracy_score(test_y, predict_y)))

# 创建新的鸢尾花数据用于预测
new_data = pd.DataFrame({
    'Sepal.Length': [5.1, 6.3, 7.0, 4.9, 5.0, 6.5, 5.5],
    'Sepal.Width':  [3.5, 2.9, 3.2, 2.4, 3.3, 3.8, 2.3],
    'Petal.Length': [1.4, 4.9, 5.5, 3.3, 1.5, 2.8, 4.0],
    'Petal.Width':  [0.2, 1.5, 2.1, 1.0, 0.3, 0.7, 1.3]
})

# 对新数据进行预处理
new_data_scaled, _ = preprocess_data(new_data, features, scaler)

# 使用训练好的模型进行预测
predictions = knn.predict(new_data_scaled)

# 将预测结果添加到新数据中
new_data['Predicted_Species'] = predictions

print("最终预测结果:")
print(new_data)

# 结果解读
print("\n结果解读:")
for i, row in new_data.iterrows():
    print(f"\n样本 {i+1}:")
    print(f"  特征: 花萼长度 = {row['Sepal.Length']}cm, 花萼宽度 = {row['Sepal.Width']}cm, "
          f"花瓣长度 = {row['Petal.Length']}cm, 花瓣宽度 = {row['Petal.Width']}cm")
    print(f"  预测结果: {row['Predicted_Species']}")

    if row['Predicted_Species'] == 'setosa':
        if row['Petal.Length'] < 2.0 and row['Petal.Width'] < 0.5:
            print("  解读: 这是一个典型的山鸢尾(Setosa)样本。山鸢尾通常有较短的花瓣。")
        else:
            print("  解读: 模型将其分类为山鸢尾(Setosa),但其特征不太典型。这可能是一个有趣的案例,需要进一步调查。")
    else:
        if row['Petal.Length'] > 3.0 and row['Petal.Width'] > 1.0:
            print(f"  解读: 这是一个典型的非山鸢尾样本,被预测为{row['Predicted_Species']}。")
        else:
            print(f"  解读: 模型预测这是{row['Predicted_Species']},但其特征不太典型。这可能是一个边界案例或异常样本。")

原创文章,作者:曾确令,如若转载,请注明出处:https://www.zengqueling.com/psjfxb/

联系我们

15602395067

在线咨询:点击这里给我发消息

邮件:eden7@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code