京东手机项目:手机受欢迎的影响因素分析

一、实验背景与目的

在当今高度数字化的消费市场中,在线用户评论已成为影响消费者购买决策和衡量产品市场表现的关键指标。对于智能手机这类高度竞争的商品而言,其电商平台上的评论数量不仅能直观反映产品的市场热度与用户参与度,也是厂商进行市场分析、制定营销策略的重要依据。

然而,评论数的多少并非由单一因素决定,而是受到价格、品牌、硬件配置(如CPU、内存、摄像头)以及一系列特色功能(如AI大模型、防水防尘、无线充电等)共同作用的复杂结果。理解这些特征与评论数之间的内在关联,并构建一个能够准确预测产品受欢迎程度(以评论数为代理变量)的模型,对于制造商、营销人员和分析师都具有重要的商业价值。

本实验旨在利用数据挖掘和机器学习技术,对智能手机的多元特征数据进行系统性分析,并构建一个分类预测模型。具体步骤如下:

  1. 数据探索与预处理:对包含价格、品牌、硬件配置、功能特性等22个特征的智能手机数据集进行清洗、缺失值处理和数据转换,为建模准备质量较高的数据集。

  2. 目标变量构建:将连续的评论数转换为"高"、"中"、"低"三个类别,将回归问题转化为一个更直观的多分类问题,便于理解和应用。

  3. 构建并比较分类模型 :训练并评估包括决策树、逻辑回归、随机森林和XGBoost在内的四种经典机器学习分类模型。

  4. 模型性能评估与优选:使用准确率、混淆矩阵、精确率、召回率等指标全面评估各模型的性能,从中选出预测效果最佳的模型,为后续的预测分析提供可靠工具。

  5. 特征在模型中重要性:对准确度较高的模型进行特征重要性分析,找出影响手机受欢迎程度的主要特征,为后续制定手机营销策略提供支持与建议。

二、数据来源

本实验所使用数据均来自京东官网,通过爬虫获取的手机数据。且所使用的数据均已在excel中进行初步的预处理,使其便于以datafreme形式运用于模型之中。

三、实验过程

1、数据读取与相关库声明

python 复制代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from collections import Counter
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import xgboost as xgb

#1. 数据读取
train_df = pd.read_csv('最终数据源(csv).csv')
train_df.head()

输出结果如下(部分):

可以看出,部分特征(如内存,电池容量)存在缺失值,需要进行预处理提高数据质量。

2、数据预处理

本实验的预处理步骤主要包含:

(1)缺失值处理;

(2)对分类特征变量进行独热编码;

(3)对因变量(评论数)转化为分类变量。

本实验不进行异常值处理,原因为初始样本量较少(133个),且手机之间参数差距各异,难以有效的进行合理的异常值处理。

python 复制代码
#2. 数据预处理
from sklearn.preprocessing import LabelEncoder
X = train_df.loc[:, ['价格','品牌','CPU型号','机身颜色','后摄像素','前摄像素','屏幕尺寸','系统','内存','储存','充电功率','电池容量','轻薄','ai大模型','红外遥控','NFC','防水防尘','高频PWM调光','无线充电','大底主摄']]
y = train_df.loc[:, '评论数']
#print(X.head())
#print(y.head())

# 复制特征和目标变量
X_processed = X.copy()
y_processed = y.copy()

# 分离数值型和分类型特征
numeric_columns = ['价格', '后摄像素', '前摄像素', '屏幕尺寸', '内存', '储存', '充电功率', '电池容量']
categorical_columns = ['品牌', 'CPU型号', '机身颜色', '系统']

# 对数值型特征使用均值填充缺失值
for col in numeric_columns:
    if col in X_processed.columns:
        mean_value = X_processed[col].mean()
        X_processed[col] = X_processed[col].fillna(mean_value)

# 对分类型特征使用众数填充缺失值(或用"未知"填充)
for col in categorical_columns:
    if col in X_processed.columns:
        mode_value = X_processed[col].mode()
        if len(mode_value) > 0:
            X_processed[col] = X_processed[col].fillna(mode_value[0])
        else:
            X_processed[col] = X_processed[col].fillna("未知")

# 对分类变量进行编码
label_encoders = {}
for col in categorical_columns:
    if col in X_processed.columns:
        le = LabelEncoder()
        X_processed[col] = le.fit_transform(X_processed[col].astype(str))
        label_encoders[col] = le

# 检查处理后的数据
print("处理后的特征数据前5行:")
print(X_processed.head())
print("\n缺失值检查:")
print(X_processed.isnull().sum())

# 将评论数转换为分类变量(高、中、低)
def categorize_comments(comment_count):
    if comment_count > 100000:
        return 2  # 高评论数
    elif comment_count > 10000:
        return 1  # 中等评论数
    else:
        return 0  # 低评论数

y_categorical = y_processed.apply(categorize_comments)

输出结果如下:

可以看出,经过数据预处理步骤后,各个特征变量值趋于标准、稳定,可以为模型所使用。

3、数据探索

主要检查编码后的因变量(评论数)的分布与各个特征之间的相关性,分别采用柱状图和热力图表示。

python 复制代码
#3. 数据探索(可视化)
# 查看训练集目标变量的分布
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False 
plt.figure(figsize=(10, 6))
category_counts = y_categorical.value_counts().sort_index()
categories = ['低评论数(<1万)', '中评论数(1万-10万)', '高评论数(>10万)']
bars = plt.bar(range(len(categories)), category_counts.values, color=['lightcoral', 'lightskyblue', 'lightgreen'])
plt.xlabel('评论数类别')
plt.ylabel('数量')
plt.title('训练集中各类别分布')
plt.xticks(range(len(categories)), categories, rotation=45)

# 查看训练集特征之间的相关性热力图
plt.figure(figsize=(10, 8))
sns.heatmap(X_processed.corr(), annot=True, fmt=".2f", cmap='coolwarm', linewidths=0.5)
plt.title('特征相关热力图')
plt.show()

输出结果如下:

通过类别分布图可以看出,样本的因变量类别分布不均,后续需采用SMOTE过采样进行处理;而特征相关性热力图则反映了特征之间相关性较低,无需进行特殊处理。

4、数据集划分与SMOTE过采样

因为样本的因变量类别分布不均,这里先进行训练测试集的划分,后对训练集进行SMOTE过采样,确保有足够的样本输入进模型,减少模型欠拟合概率。

python 复制代码
#4、 划分训练集和测试集(80% 训练,20% 测试)
X_train, X_test, y_train, y_test = train_test_split(X_processed, y_categorical, test_size=0.2, random_state=7)

#5、 使用SMOTE进行过采样
from imblearn.over_sampling import SMOTE
smote = SMOTE(random_state=7)
X_train_smote, y_train_smote = smote.fit_resample(X_train, y_train)
original_counts = Counter(y_train)
smote_counts = Counter(y_train_smote)

# 原始分布
plt.subplot(1, 2, 1)
categories = ['低评论数(<1万)', '中评论数(1万-10万)', '高评论数(>10万)']
original_values = [original_counts[i] if i in original_counts else 0 for i in range(3)]
plt.bar(categories, original_values, color=['lightcoral', 'lightskyblue', 'lightgreen'])
plt.title('原始训练集类别分布')
plt.ylabel('样本数量')
plt.xticks(rotation=45)

# SMOTE后分布
plt.subplot(1, 2, 2)
smote_values = [smote_counts[i] if i in smote_counts else 0 for i in range(3)]
plt.bar(categories, smote_values, color=['lightcoral', 'lightskyblue', 'lightgreen'])
plt.title('SMOTE过采样后类别分布')
plt.ylabel('样本数量')
plt.xticks(rotation=45)

plt.tight_layout()
plt.show()

输出结果如下:

可以看出,经过SMOTE过采样后的各个类别数量趋于一致,有利于模型的构建。

5、初始模型构建

本实验采用决策树、逻辑回归、随机森林和 XGBoost 4中方法进行模型的构建,将训练集输入给各个模型后,选择表现最好的模型作为最终模型。

python 复制代码
#5. 模型训练
# 5.1 决策树模型
dt_model = DecisionTreeClassifier(random_state=7)
dt_model.fit(X_train_smote, y_train_smote)
#模型预测
dt_pred = dt_model.predict(X_test)
dt_confusion = confusion_matrix(y_test, dt_pred)
dt_report = classification_report(y_test, dt_pred)
dt_accuracy = accuracy_score(y_test, dt_pred)
print("决策树模型报告")
print(dt_report)

# 5.2 逻辑回归模型
lr_model = LogisticRegression(max_iter=1000, random_state=7)
lr_model.fit(X_train_smote, y_train_smote)
#模型预测
lr_pred = lr_model.predict(X_test)
lr_confusion_matrix = confusion_matrix(y_test, lr_pred)
lr_report = classification_report(y_test, lr_pred)
lr_accuracy = lr_model.score(X_test, y_test)
print("逻辑回归模型报告")
print(lr_report)

# 5.3 随机森林模型
rf_model = RandomForestClassifier()
rf_model.fit(X_train_smote, y_train_smote)
#模型预测
rf_pred = rf_model.predict(X_test)
rf_confusion = confusion_matrix(y_test, rf_pred)
rf_report = classification_report(y_test, rf_pred)
rf_accuracy = rf_model.score(X_test, y_test)
print("随机森林模型报告:")
print(rf_report)

# 5.4 xgboost模型
xgb_model = xgb.XGBClassifier(n_estimators=100, learning_rate=0.1, max_depth=5, subsample=0.8, colsample_bytree=0.8)
xgb_model.fit(X_train_smote, y_train_smote)
#模型评估
xgb_pred = xgb_model.predict(X_test)
xgb_confusion = confusion_matrix(y_test, xgb_pred)
xgb_report = classification_report(y_test, xgb_pred)
xgb_accuracy = accuracy_score(y_test, xgb_pred)
print("xgboost模型报告:")
print(xgb_report)

输出结果如下:

可以看出,在初始无调参的情况下,xgboost模型效果最佳,准确率为0.81,决策树和支持向量机模型效果其次,逻辑回归模型效果较差。

6、模型参数调优

使用网格搜索对4个模型进行参数调优,获取各个模型的最优参数并应用。

python 复制代码
from sklearn.model_selection import GridSearchCV

# 决策树参数调优
dt_param_grid = {
    'max_depth': [1, 3, 5, 7, 10, None],
    'min_samples_split': [2, 5, 10],
    'min_samples_leaf': [1, 2, 4],
    'criterion': ['gini', 'entropy']
}

dt_grid_search = GridSearchCV(
    estimator=DecisionTreeClassifier(random_state=7),
    param_grid=dt_param_grid,
    cv=5,
    scoring='accuracy',
    n_jobs=-1
)

dt_grid_search.fit(X_train_smote, y_train_smote)
#print("决策树最佳参数:", dt_grid_search.best_params_)
#print("决策树最佳得分:", dt_grid_search.best_score_)

# 使用最佳参数构建模型
dt_best_model = dt_grid_search.best_estimator_
dt_best_model.fit(X_train_smote, y_train_smote)
dt_best_pred = dt_best_model.predict(X_test)
dt_best_accuracy = accuracy_score(y_test, dt_best_pred)
dt_best_confusion = confusion_matrix(y_test, dt_best_pred)
#print("最优决策树准确率:", accuracy_score(y_test, dt_best_pred))

# 逻辑回归参数调优
lr_param_grid = {
    'C': [0.01, 0.1, 1, 10, 100],
    'penalty': ['l1', 'l2'],
    'solver': ['liblinear', 'saga'],
    'max_iter': [1000, 2000, 5000]
}

lr_grid_search = GridSearchCV(
    estimator=LogisticRegression(random_state=7),
    param_grid=lr_param_grid,
    cv=5,
    scoring='accuracy',
    n_jobs=-1
)

lr_grid_search.fit(X_train_smote, y_train_smote)
#print("逻辑回归最佳参数:", lr_grid_search.best_params_)
#print("逻辑回归最佳得分:", lr_grid_search.best_score_)

# 使用最佳参数构建模型
lr_best_model = lr_grid_search.best_estimator_
lr_best_model.fit(X_train_smote, y_train_smote)
lr_best_pred = lr_best_model.predict(X_test)
lr_best_accuracy = accuracy_score(y_test, lr_best_pred)
lr_best_confusion = confusion_matrix(y_test, lr_best_pred)
#print("逻辑回归准确率:", accuracy_score(y_test, lr_best_pred))

# 随机森林参数调优
rf_param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [3, 5, 7, None],
    'min_samples_split': [2, 5, 10],
    'min_samples_leaf': [1, 2, 4],
    'max_features': ['sqrt', 'log2']
}

rf_grid_search = GridSearchCV(
    estimator=RandomForestClassifier(random_state=7),
    param_grid=rf_param_grid,
    cv=5,
    scoring='accuracy',
    n_jobs=-1
)

rf_grid_search.fit(X_train_smote, y_train_smote)
#print("随机森林最佳参数:", rf_grid_search.best_params_)
#print("随机森林最佳得分:", rf_grid_search.best_score_)

# 使用最佳参数构建模型
rf_best_model = rf_grid_search.best_estimator_
rf_best_model.fit(X_train_smote, y_train_smote)
rf_best_pred = rf_best_model.predict(X_test)
rf_best_accuracy = accuracy_score(y_test, rf_best_pred)
rf_best_confusion = confusion_matrix(y_test, rf_best_pred)
#print("随机森林准确率:", accuracy_score(y_test, rf_best_pred))

# XGBoost参数调优
xgb_param_grid = {
    'n_estimators': [50, 100, 200],
    'learning_rate': [0.01, 0.1, 0.2],
    'max_depth': [3, 5, 7],
    'subsample': [0.6, 0.8, 1.0],
    'colsample_bytree': [0.6, 0.8, 1.0]
}

xgb_grid_search = GridSearchCV(
    estimator=xgb.XGBClassifier(random_state=7),
    param_grid=xgb_param_grid,
    cv=5,
    scoring='accuracy',
    n_jobs=-1
)

xgb_grid_search.fit(X_train_smote, y_train_smote)
#print("XGBoost最佳参数:", xgb_grid_search.best_params_)
#print("XGBoost最佳得分:", xgb_grid_search.best_score_)

# 使用最佳参数构建模型
xgb_best_model = xgb_grid_search.best_estimator_
xgb_best_model.fit(X_train_smote, y_train_smote)
xgb_best_pred = xgb_best_model.predict(X_test)
xgb_best_accuracy = accuracy_score(y_test, xgb_best_pred)
xgb_best_confusion = confusion_matrix(y_test, xgb_best_pred)
#print("XGBoost准确率:", accuracy_score(y_test, xgb_best_pred))

7、模型评价

本实验采用各个模型的混淆矩阵可视化与准确率作为评价指标,对调优后的各个模型进行评估。

python 复制代码
# 创建混淆矩阵热力图
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
fig.suptitle('调优后各模型混淆矩阵对比', fontsize=16)

# 标签名称
labels = ['低评论数(<1万)', '中评论数(1万-10万)', '高评论数(>10万)']

# 决策树混淆矩阵
sns.heatmap(dt_best_confusion, annot=True, fmt='d', cmap='Blues', 
            xticklabels=labels, yticklabels=labels, ax=axes[0,0])
axes[0,0].set_title(f'决策树 (准确率: {dt_best_accuracy:.4f})')
axes[0,0].set_xlabel('预测标签')
axes[0,0].set_ylabel('真实标签')

# 逻辑回归混淆矩阵
sns.heatmap(lr_best_confusion, annot=True, fmt='d', cmap='Greens', 
            xticklabels=labels, yticklabels=labels, ax=axes[0,1])
axes[0,1].set_title(f'逻辑回归 (准确率: {lr_best_accuracy:.4f})')
axes[0,1].set_xlabel('预测标签')
axes[0,1].set_ylabel('真实标签')

# 随机森林混淆矩阵
sns.heatmap(rf_best_confusion, annot=True, fmt='d', cmap='Oranges', 
            xticklabels=labels, yticklabels=labels, ax=axes[1,0])
axes[1,0].set_title(f'随机森林 (准确率: {rf_best_accuracy:.4f})')
axes[1,0].set_xlabel('预测标签')
axes[1,0].set_ylabel('真实标签')

# XGBoost混淆矩阵
sns.heatmap(xgb_best_confusion, annot=True, fmt='d', cmap='Reds', 
            xticklabels=labels, yticklabels=labels, ax=axes[1,1])
axes[1,1].set_title(f'XGBoost (准确率: {xgb_best_accuracy:.4f})')
axes[1,1].set_xlabel('预测标签')
axes[1,1].set_ylabel('真实标签')

plt.tight_layout()
plt.show()

输出结果如下:

可以看出,调优后xgboost模型表现最好,随机森林模型和逻辑回归模型表现效果其次。以此为基础,对xgboost模型进行特征重要性可视化分析。

8、特征重要性分析

python 复制代码
# 获取特征名称
feature_names = ['价格', '品牌', 'CPU型号', '机身颜色', '后摄像素', '前摄像素', '屏幕尺寸', '系统', 
                '内存', '储存', '充电功率', '电池容量', '轻薄', 'ai大模型', '红外遥控', 'NFC', 
                '防水防尘', '高频PWM调光', '无线充电', '大底主摄']

# 获取特征重要性
feature_importance = xgb_best_model.feature_importances_

# 创建特征重要性DataFrame
importance_df = pd.DataFrame({
    'feature': feature_names,
    'importance': feature_importance
}).sort_values('importance', ascending=False)

# 打印特征重要性排序
#print("特征重要性排序:")
#print(importance_df)

# 绘制特征重要性条形图
plt.figure(figsize=(12, 8))
bars = plt.barh(range(len(importance_df)), importance_df['importance'], color='skyblue')
plt.yticks(range(len(importance_df)), importance_df['feature'])
plt.xlabel('特征重要性')
plt.title('XGBoost模型特征重要性排序')
plt.gca().invert_yaxis()  # 重要性从高到低排列

# 在条形图上显示数值
for i, (bar, importance) in enumerate(zip(bars, importance_df['importance'])):
    plt.text(bar.get_width() + 0.001, bar.get_y() + bar.get_height()/2, 
             f'{importance:.4f}', ha='left', va='center')

plt.tight_layout()
plt.show()

输出结果如下:

可以看出,影响手机受欢迎程度的最主要的5个因素分别是:"轻薄"、"系统"、"电池容量"、"价格"、"品牌"。

对此结果,我们分析出以下结论:

(1) "轻薄"位列第一,强烈表明消费者对手机便携性和日常使用舒适度的极度重视。厚重的"半斤机"已不再是市场主流。

(2)"系统"的重要性高居第二,说明软件体验与硬件性能同等重要。一个流畅、稳定、无广告骚扰、交互人性化的操作系统是留住用户的核心。

(3)电池容量是用户体验的基础保障。在5G、高刷屏等高功耗成为标配的今天,大电池是保证所有美好体验得以持续的前提。

(4) 价格是价值的最终体现。消费者并非一味追求低价,而是追求在特定价格段内获得最优的综合体验。

(5)品牌是消费者决策的最终过滤器。一个强大的品牌意味着信任、认同和社群归属感。

四、实验总结

本实验围绕"手机受欢迎的影响因素分析"这一主题,完成了一个从数据预处理到机器学习建模与结果解读的完整数据科学流程。通过对真实数据集的分析与建模,我们不仅成功构建了有效的预测模型,更从中挖掘出了影响智能手机市场受欢迎程度的深层逻辑。

尽管实验取得了良好效果,但仍存在可提升的空间:

  1. 数据维度:数据集中缺乏用户画像、营销投入、发布时机等外部因素,这些对评论数同样有重大影响。

  2. **样本量较少:**本实验所使用的数据集仅有133个样本,后续也采用了SMOTE过采样进行弥补,但这会导致模型丢失一部分精准度,后续可以获取更多的样本来训练。

  3. 动态变化:市场偏好是动态变化的。本模型反映的是当前数据所代表时段内的规律,需要持续用新数据来更新模型以保持其前瞻性。

最后,本实验不仅是一次技术实践,更是一次深刻的市场洞察。它为手机厂商的产品定义、市场定位与营销策略提供了数据驱动的决策依据,指明了打造受欢迎产品的核心路径。

相关推荐
kobe_OKOK_4 小时前
Django ORM 字段查询表达式(Field lookup expressions)
后端·python·django
C嘎嘎嵌入式开发4 小时前
(1)100天python从入门到拿捏
开发语言·python
过往入尘土4 小时前
服务端与客户端的简单链接
人工智能·python·算法·pycharm·大模型
软件开发技术深度爱好者4 小时前
用python制作相册浏览小工具
开发语言·python
沐曦可期4 小时前
标准编码与算法
javascript·python
我的xiaodoujiao4 小时前
从 0 到 1 搭建 Python 语言 Web UI自动化测试学习系列 8--基础知识 4--常用函数 2
前端·python·测试工具·ui
Rhys..5 小时前
Cucumber自学导航
javascript·python·bdd·cucumber
kobe_OKOK_5 小时前
Django ORM 无法通过 `ForeignKey` 自动关联,而是需要 **根据父模型中的某个字段(比如 ID)去查询子模型**。
后端·python·django
蜀中廖化5 小时前
python VSCode中报错 E501:line too long (81 > 79 characters)
开发语言·vscode·python