目录
1 . 结构化数据挖掘
1 . 1 依赖库导入和数据读取
导入必要的依赖库,读取 csv 格式数据集转化为 Dataframe 格式,命名为 data,使用 pandas 必要接口,并打印数据集的前五个样本。
#` `数据导入和观察`
`import pandas as pd`
`data = pd.read_csv('cleaned_all_phones.csv')`
`data.head()`
`
说明:
import pandas as pd
导入Pandas库,并将其简称为pd。Pandas是一个强大的数据分析和处理库,广泛用于数据清洗、转换、分析和可视化。
data = pd.read_csv('cleaned_all_phones.csv')
使用Pandas的read_csv()函数加载一个名为cleaned_all_phones.csv的CSV文件。这个文件可能包含手机相关的数据,例如品牌、价格、性能指标等。read_csv()函数会将CSV文件读取为一个DataFrame对象,这是Pandas中用于存储表格数据的主要数据结构。
data.head()
调用head()方法显示DataFrame的前五行数据。这是数据探索的常用操作,用于快速查看数据的结构和内容。

1.2 各品牌机型及售价统计
统计各品牌发布的机型数量,并绘制机型数量关于品牌的柱形图,统计个品牌发布的机型的价格均值,并绘制机型价格均值关于品牌的柱形图。
#` `可视化数据分布`
`import matplotlib.pyplot as plt`
`import seaborn as sns`
`fig, ax = plt.subplots(1,2,figsize=(20,6))`
`brand_counts = data['brand'].value_counts()`
`sns.barplot(x=brand_counts.index, y=brand_counts.values, ax=ax[0],color='red')`
`ax[0].set_xlabel('Brand')`
`ax[0].set_ylabel('Count')`
`ax[0].set_title('Brand Distribution')`
`ax[0].tick_params(axis='x',rotation=90)`
`brand_price_mean = data.groupby('brand')['price(USD)'].mean()`
`sns.barplot(x=brand_price_mean.index, y=brand_price_mean.values, ax=ax[1],color='red')`
`ax[1].set_xlabel('Brand')`
`ax[1].set_ylabel('Averge Price')`
`ax[1].set_title('Brand X Price Distribution')`
`ax[1].tick_params(axis='x',rotation=90)`
`plt.tight_layout()`
`plt.show()`
`
说明:
seaborn :基于matplotlib的高级绘图库,提供了更简洁的API和更美观的默认样式,特别适合用于统计图表的绘制。
fig,ax` `=` `plt.subplots(1,2,figsize=(20,6))`
`
使用plt.subplots()创建一个包含1行2列的图形布局,总尺寸为20×6英寸。
fig表示整个图形对象,ax是一个包含两个子图的数组,分别用于绘制不同的图表。
brand_counts` `=` `data['brand'].values_counts()`
`brand_counts_mean` `=` `data.groupby('brand')['price(USD)'].mean()`
`
brand_counts :使用value_counts()方法统计brand列中每个品牌出现的次数。
brand_price_mean :使用groupby()方法按品牌分组,并计算每个品牌的平均价格。
sns.barplot(x=brand_counts.index,y=brand_counts.values,ax=ax[0],color='red')`
`ax[0].set_xlabel('Brand')`
`ax[0].set_ylabel('Count')`
`ax[0].set_title('Brand Distribution')`
`ax[0].tick_params(axis='x',rotation=90)`
`
使用seaborn的barplot()方法绘制柱状图:
x=brand_counts.index:品牌名称作为横轴
y=brand_counts.values:品牌出现的次数作为纵轴
ax=ax[0]:指定将图表绘制在第一个子图上
color='red':将柱子的颜色设置为红色
使用ax[0].set_xlabel()、ax[0].set_ylabel()和ax[0].set_title()设置横轴标签、纵轴标签和标题。
使用ax[0].tick_params(axis='x', rotation=90)将横轴标签旋转90度,避免标签重叠。
sns.barplot(x=brand_price_mean.index,y=brand_price_mean.values,ax[1],color='red')`
`ax[1].set_xlabel('Brand')`
`ax[1].set_ylabel('Average Price')`
`ax[1].set_title('Brand X Price Distribution')`
`ax[1].tick_params(axis='x',rotation=90)`
`
绘制第二个子图,参数同上

库的应用拓展
Matplotlib的更多功能
自定义图表样式:
plt.style.use('ggplot')` `# 使用ggplot风格`
`
添加网格线:
ax[0].grid(axis='y', linestyle='--', alpha=0.7)`
`
添加注释:
ax[0].annotate('Highest Count', xy=('Brand A',` `100), xytext=(10,` `10),`
` arrowprops=dict(facecolor='black', shrink=0.05))`
`
Seaborn的更多功能
绘制箱线图:
sns.boxplot(x='brand', y='price(USD)', data=data)`
`
绘制热力图:
sns.heatmap(data.corr(), annot=True, cmap='coolwarm')`
`
绘制散点图矩阵:
sns.pairplot(data, hue='brand')`
`
结合Pandas进行更复杂的数据分析
分组统计:
brand_stats = data.groupby('brand').agg({'price(USD)':` `['mean',` `'median',` `'std']})`
`
条件筛选与可视化:
high_price_brands = data[data['price(USD)']` `>` `1000]`
`sns.scatterplot(x='brand', y='price(USD)', data=high_price_brands)`
`
1.3 视频录制规格与价格关联性分析
以 10 种不同的视频录制规格作为特征,分别绘制价格有关这 10 种特征的 10 张箱线图,将 10 张箱线图打印在一个同画布上。
#` `分析某个(某些)特征与标签(1:1)的关系可以用到箱线图sns.boxplot()`
`video_feature =` `[col for col in data.columns if col.startswith('video')]`
`plt.subplots(4,3,figsize=(30,30))`
`for idx,feature in` `enumerate(video_feature,start=1):`
` plt.subplot(4,3,idx)`
` sns.boxplot(x=feature, y='price(USD)', data=data, hue=feature, palette={False:'red',True:'blue'})` `# `
` plt.xlabel('feature')`
` plt.ylabel('price(USD)')`
` plt.title('price box plot')`
`
说明:
video_feature` `=` `[col` `for` `col` `in` `data.columns` `if` `col.startswith('vedio_')]`
`
使用列表推导式从data的列名中筛选出以"video"开头的特征列
这些特征可能与视频功能相关,例如video_resolution(视频分辨率)、video_fps(视频帧率)等
for idx,feature` `in` `enumerate(vedio_feature,start=1):`
`plt.subplot(4,3,idx)`
`sns.boxplot(x=feature,y='price(USD)',data=data,hue=feature,palette={False:'red',True:'blue'})`
` plt.xlabel('feature')`
` plt.ylabel('price(USD)')`
` plt.title('price box plot')`
`
enumerate(video_feature, start=1):遍历video_feature列表,并为每个特征分配一个索引(从1开始)。
plt.subplot(4, 3, idx) :根据索引将每个箱线图绘制在对应的子图位置。
sns.boxplot():使用Seaborn的boxplot()方法绘制箱线图
x=feature:将特征列作为横轴。
y='price(USD)':将价格作为纵轴。
data=data:指定数据源。
hue=feature:根据特征的值对箱线图进行分组(假设特征是布尔类型,如True或False)。
palette={False: 'red', True: 'blue'}:为分组设置颜色,False为红色,True为蓝色。
plt.xlabel('feature') **、**plt.ylabel('price(USD)') **、**plt.title('price box plot') :设置横轴标签、纵轴标签和标题
补充:
箱线图的作用
为什么可以用箱线图分析特征与标签的关系?
箱线图是一种用于展示一组数据的五数概括(最小值、第一四分位数、中位数、第三四分位数和最大值)的图表。通过箱体和须线直观地展示了数据的分布情况,包括中位数、分布范围、异常值等。
分析特征与标签的关系:
在机器学习和数据分析中,箱线图可以用来分析特征与标签之间的关系,尤其是当特征是分类变量(如布尔值、类别标签)时:
分布差异:通过比较不同特征值对应的标签分布,可以直观地看出特征值对标签的影响。例如,某些特征值可能导致标签值的分布更集中或更分散。
异常值检测:箱线图可以清晰地展示异常值,帮助分析特征与异常标签值之间的关系。
适用场景:
特征是分类变量:当特征是布尔值(如True/False)或类别标签时,箱线图可以很好地展示不同类别对应的标签分布差异。例如,video_feature可能是布尔值(如是否支持高清视频录制),箱线图可以直观地展示支持与不支持高清视频的手机价格分布差异。
标签是连续变量:箱线图适用于分析连续标签(如价格)的分布情况。通过箱线图,可以快速判断特征对标签分布的影响。
限制:
特征是连续变量时的局限性:如果特征是连续变量,箱线图可能不太适用。因为箱线图主要用于分类变量的分布比较。对于连续特征,需要先将其离散化(如分桶),或者使用其他图表(如散点图、回归线图)来分析与标签的关系。
复杂关系的局限性:箱线图主要用于展示分布差异,但对于复杂的因果关系或非线性关系,可能需要结合其他分析方法(如相关性分析、回归分析)来进一步验证。
精简总结:
箱线图通过展示数据的五数概括和分布情况,可以帮助分析分类特征与连续标签之间的关系。它特别适合用于比较不同特征值对应的标签分布差异和检测异常值。对于连续特征,可能需要先进行离散化处理,或者使用其他图表进行分析。

从箱线图可以看出vedio_特征为True的手机价格分布在大体上是比False的要高的,即vedio特征的有无会影响price
2. 结构化数据预处理
2.1 筛选特征
使用 pandas 拷贝一份数据集,命名为 df,取 'price (USD)' 为标签 y, 其他为特征集合 X,删除 X 中无关特征,只保留:'inches', 'battery', 'ram (GB)', 'weight (g)', 'storage (GB) 等特征,统计 name 特征中包含 'pro' 或 'max' 的样本,新建布尔特征 'has_pro_or_max'。
#` `拷贝一份数据来做为模型训练前的预处理,不破坏原数据`
`df = data.copy()`
`X = df[['inches',` `'battery',` `'ram(GB)',` `'weight(g)',` `'storage(GB)']]` `#, *video_feature]`
`y = df['price(USD)']`
`X['has_pro_or_max']` `= data['phone_name'].map(lambda x:1` `if` `'Pro'` `in x or` `'Max'` `in x else` `0)`
`# X['has_pro_or_max'] = df['phone_name'].str.contains('pro|max',case=False,regex=True).astype(int)`
`X `
`
说明:
X['has_pro_or_max']` `=` `data['phone_name'].map(lambda` `x:1` `if` `'Pro'` `in` `x or` `'Max'` `in` `x` `else` `0)`
`
通过map()方法和lambda函数,为每个手机名称检查是否包含"Pro"或"Max"字样
如果包含,则返回1,表示该手机名称中包含"Pro"或"Max";如果不包含,则返回0
这个新特征has_pro_or_max被添加到特征集X中,用于捕捉品牌型号中可能影响价格的关键词
# X['has_pro_or_max'] = df['phone_name'].str.contains('pro|max', case=False, regex=True).astype(int)`
`
使用str.contains()方法检查phone_name列中是否包含"pro"或"max"(不区分大小写)
case=False:忽略大小写
regex=True:允许使用正则表达式
astype(int):将布尔值(True/False)转换为整数(1/0)
这种方法与map()和lambda函数的效果相同,但更简洁

2.2 特征标签归一化及编码
编写数据预处理函数 preprocessing,对标签和特征用 sklearn 中的 StandardScaler 进行归一化。
并且在该函数中,调用接口进行划分 80% 数据为训练集,20% 数据为测试集,函数的返回值为训练集和测试集的特征和标签。
调用该函数进行数据预处理和数据集划分,并打印出训练集和测试集的数组形状。
#` `对标签和特征归一化,切分数据集`
`from sklearn.model_selection import train_test_split`
`from sklearn.preprocessing import StandardScaler`
`import numpy as np`
`def` `df_preprocessing(X,y):`
` std = StandardScaler()`
` X = std.fit_transform(X)`
` y = std.fit_transform(y.values.reshape(-1,1))`
` X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=42)`
`return X_train,X_test,y_train,y_test`
`X_train,X_test,y_train,y_test = df_preprocessing(X,y)`
`#X_train.shape,X_test.shape,y_train.shape,y_test.shape`
`print('Number transactions X_train dataset:',X_train.shape)`
`print('Number transactions y_train dataset:',y_train.shape)`
`print('Number transactions X_test dataset:',X_test.shape)`
`print('Number transactions y_test dataset:',y_test.shape)`
`

说明:
def` `df_preprocessing(X, y):`
`std` `=` `StandardScaler()`
`X` `=` `std.fit_transform(X)`
`y` `=` `std.fit_transform(y.values.reshape(-1,1))`
`
StandardScaler 的使用:
对特征 X 进行标准化:X = std.fit_transform(X)。
对标签 y 进行标准化:y = std.fit_transform(y.values.reshape(-1, 1))。
y.values.reshape(-1, 1):将 y 从一维数组转换为二维数组,因为 StandardScaler 需要二维输入。
改进建议
标签是否需要标准化?
在许多回归任务中,标签不需要标准化,因为模型的输出可以直接与原始标签进行比较;如果对标签进行标准化,后续需要将预测结果反向转换为原始尺度
如果确实需要标准化标签,建议在预测后进行反标准化:
y_pred = std.inverse_transform(y_pred)`
`
保存标准化器的状态
在实际应用中,标准化器(StandardScaler)的状态(均值和标准差)需要保存,以便在模型部署时对新数据进行相同的标准化处理
可以通过 joblib 或 pickle 保存标准化器:
from joblib import dump`
`dump(std,` `'scaler.joblib')`
`
处理异常值
在标准化之前,建议检查数据中是否存在异常值,因为异常值会对标准化产生较大影响