shivanshu1512/Quora_question_pair_project

GitHub: shivanshu1512/Quora_question_pair_project

基于 Quora 数据集构建的 NLP 重复问题检测系统,通过词袋模型与多层级手工特征工程训练机器学习分类器,并部署为 Streamlit 交互式 Web 应用。

Stars: 0 | Forks: 0

# 🔍 Quora 问题重复检测器 [![在线演示](https://img.shields.io/badge/🚀%20Live%20Demo-Streamlit-FF4B4B?style=for-the-badge&logo=streamlit)](https://quora-question-pair-project.streamlit.app/) [![Python](https://img.shields.io/badge/Python-3.8+-3776AB?style=for-the-badge&logo=python&logoColor=white)](https://python.org) [![Sklearn](https://img.shields.io/badge/scikit--learn-ML-F7931E?style=for-the-badge&logo=scikit-learn&logoColor=white)](https://scikit-learn.org) ## 📌 这个项目是关于什么的? Quora 是一个供人们提问的平台。在 Quora 上一个非常普遍的问题是,**同一个问题会被多次询问**,只是表述方式不同。例如: - *"学习 Python 的最好方法是什么?"* - *"我该如何开始学习 Python 编程?"* 这两个问题问的是**同一件事**——它们是**重复的**! 在这个项目中,我构建了一个 **Machine Learning 系统**,它可以自动检测给定的两个问题是否重复。这正是 Quora 发布为 [Kaggle 比赛](https://www.kaggle.com/c/quora-question-pairs) 的同一个问题。 ## 🌐 在线演示 👉 **在这里亲自尝试:** [quora-question-pair-project.streamlit.app](https://quora-question-pair-project.streamlit.app/) 只需输入两个问题,点击按钮,模型就会告诉你它们是否是重复的! ## 🗂️ 项目结构 ``` Quora_question_pair_project/ │ ├── 📓 initial_EDA.ipynb # Step 1: Exploring the dataset ├── 📓 only-bow.ipynb # Step 2: Baseline model (Bag of Words only) ├── 📓 bow-with-basic-features.ipynb # Step 3: Adding basic NLP features ├── 📓 bow-with-preprocessing-and-advanced-features.ipynb # Step 4: Final best model │ └── 📁 streamlit-app/ # Step 5: Live web app ├── app.py # Main Streamlit app code ├── helper.py # Feature engineering functions ├── requirements.txt # Python dependencies ├── setup.sh # Heroku setup script └── Procfile # Heroku deployment config ``` ## 🚀 我是如何构建它的 —— 逐步解析 ### 第一步:探索性数据分析 (EDA) 📊 **文件:** `initial_EDA.ipynb` 在构建任何模型之前,我首先**探索并理解了数据集**。 - **数据集:** 来自 Kaggle 的 Quora Question Pairs 数据集(约 404,000 个问题对) - 每一行包含:`question1`、`question2` 和一个标签(`1` = 重复,`0` = 不重复) - 我分析了: - 存在多少重复与非重复问题(约 37% 是重复的) - 问题长度的分布 - 重复与非重复问题对中最常见的词 - 词云图,用于直观地理解数据 - 同一个问题出现的频率(问题频率分析) 这一步帮助我理解了**模型应该寻找哪些模式**。 ### 第二步:基线模型 —— 仅使用词袋模型 📦 **文件:** `only-bow.ipynb` 我的第一种方法很简单——只需使用**词袋模型**将问题转换为数字,然后训练一个分类器。 **什么是词袋模型?** 词汇表中的每个单词都会获得一个数字。每个问题都变成一个向量,计算每个单词出现的次数。然后我将两个问题向量拼接在一起,并将其输入到模型中。 **我所做的:** - 使用 `CountVectorizer` 将文本转换为 BoW 向量(前 3000 个特征) - 训练了 **Random Forest** 和 **XGBoost** 分类器 - 使用了 30,000 个样本的子集(为了提高速度),并进行分层 80/20 训练-测试集划分 **结果:** | 模型 | 准确率 | |-------|----------| | Random Forest (仅 BoW) | **74.20%** | | XGBoost (仅 BoW) | 73.28% | ### 第三步:添加基础 NLP 特征 🛠️ **文件:** `bow-with-basic-features.ipynb` 仅有 BoW 是不够的。我添加了**手工设计的特征**,直接捕捉两个问题之间的关系。 **我创建的基础特征:** | 特征 | 含义 | |---------|--------------| | `q1_len` | 问题 1 的字符数 | | `q2_len` | 问题 2 的字符数 | | `q1_num_words` | 问题 1 的词数 | | `q2_num_words` | 问题 2 的词数 | | `word_common` | 两个问题中共同包含的词数 | | `word_total` | 两个问题中独特词汇的总数 | | `word_share` | 共同词数与总词数的比率 | **添加基础特征后的结果:** | 模型 | 准确率 | |-------|----------| | Random Forest | **76.83%** | | XGBoost | 76.45% | ### 第四步:高级特征工程 + 预处理(最佳模型) 🏆 **文件:** `bow-with-preprocessing-and-advanced-features.ipynb` 这是模型变得非常聪明的地方。我添加了三个类别的**高级 NLP 特征**: #### 🔤 Token 特征(8 个特征) 这些特征不仅限于计算单词数量,还捕捉了两个问题内容的相似程度: | 特征 | 描述 | |---------|-------------| | `cwc_min` | 共同的非停用词 / 较小的非停用词集合 | | `cwc_max` | 共同的非停用词 / 较大的非停用词集合 | | `csc_min` | 共同的停用词 / 较小的停用词集合 | | `csc_max` | 共同的停用词 / 较大的停用词集合 | | `ctc_min` | 共同的 token / 较小的总 token 数 | | `ctc_max` | 共同的 token / 较大的总 token 数 | | `last_word_eq` | 两个问题是否以同一个词结尾?(1 或 0) | | `first_word_eq` | 两个问题是否以同一个词开头?(1 或 0) | #### 📏 长度特征(3 个特征) | 特征 | 描述 | |---------|-------------| | `mean_len` | 两个问题的平均字符长度 | | `abs_len_diff` | 两个问题长度之间的绝对差值 | | `longest_substr_ratio` | 最长公共子串与较短问题长度的比率 | #### 🤝 模糊匹配特征(4 个特征) 我使用了 **FuzzyWuzzy** 库,它能像人类一样衡量字符串的相似度: | 特征 | 描述 | |---------|-------------| | `fuzz_ratio` | 总体相似度评分 (0–100) | | `fuzz_partial_ratio` | 最佳部分匹配的相似度 | | `token_sort_ratio` | 按字母顺序排序单词后的相似度 | | `token_set_ratio` | 取单词集合交集后的相似度 | #### 📦 文本特征 - 来自两个问题上 `CountVectorizer` 的 **BoW 向量**(3000 个特征) **最终结果:** | 模型 | 准确率 | |-------|----------| | Random Forest | **78.47%** | | **XGBoost** | **79.27% ✅ (最佳)** | ### 第五步:在线 Web 应用 🌐 **文件:** `streamlit-app/app.py` 和 `streamlit-app/helper.py` 我使用 **Streamlit** 将模型部署为一个交互式的 Web 应用。 **应用的工作原理:** 1. 用户输入 **Question 1** 和 **Question 2** 2. 应用提取所有的 NLP 特征(token、长度和模糊特征) 3. 经过训练的 **Random Forest 分类器** 进行预测 4. 应用显示:**"DUPLICATE"** 或 **"NOT DUPLICATE"**,并附带置信度分数 **关键文件:** - `app.py` — 带有自定义 CSS 样式(浅色/白色主题)的 Streamlit 主 UI - `helper.py` — 复用了 notebook 中所有的特征工程函数 ## 📊 模型性能总结 | 阶段 | 添加的内容 | Random Forest | XGBoost | |-------|-------------|--------------|---------| | 基线 (仅 BoW) | 仅词频统计 | 74.20% | 73.28% | | + 基础特征 | 词汇重叠统计 | 76.83% | 76.45% | | + 高级特征 | Token + 长度 + 模糊匹配 | 78.47% | **79.27% 🏆** | **最佳模型:包含所有特征的 XGBoost → 约 79.3% 准确率** ## 🧠 从这个项目中获得的关键心得 作为一名 BTech 学生,这个项目教会了我很多: 1. **文本无法直接输入到 ML 模型中** —— 你需要先将其转换为数字(BoW, TF-IDF 等) 2. **特征工程非常重要** —— 相比于原始 BoW,手工设计的特征使准确率提高了约 5% 3. **模糊匹配非常强大**,即使单词被重新排列,也能用于比较两个字符串的相似程度 4. **XGBoost 在处理结构化/表格特征数据时** 始终优于 Random Forest 5. **部署模型** 与构建模型一样重要 —— Streamlit 让这一切变得非常简单! 6. **EDA 优先** —— 在进入建模阶段之前,务必先探索和可视化你的数据 ## 🛠️ 使用的技术 | 类别 | 工具 | |----------|-------| | **语言** | Python 3 | | **数据分析** | Pandas, NumPy, Matplotlib, Seaborn | | **NLP** | NLTK, BeautifulSoup, FuzzyWuzzy, distance | | **ML 模型** | Scikit-learn (Random Forest), XGBoost | | **文本向量化** | CountVectorizer (词袋模型), TF-IDF | | **Web 应用** | Streamlit | | **部署** | Streamlit Cloud / Heroku | ## ⚙️ 如何在本地运行 ### 1. 克隆仓库 ``` git clone https://github.com/shivanshu1512/Quora_question_pair_project.git cd Quora_question_pair_project ``` ### 2. 安装依赖 ``` pip install -r streamlit-app/requirements.txt ``` ### 3. 运行 Streamlit 应用 ``` cd streamlit-app streamlit run app.py ``` ### 4. 在浏览器中打开 `http://localhost:8501` ## 📁 数据集 - **来源:** [Kaggle — Quora Question Pairs](https://www.kaggle.com/c/quora-question-pairs/data) - **大小:** 约 404,000 个问题对 - **用于训练:** 30,000 个问题对(分层抽样) - **标签:** `1` = 重复,`0` = 不重复 - **类别划分:** 约 37% 重复,约 63% 不重复 ## 👨‍💻 关于我 你好!我是 **Shivanshu Shukla**,一名对 Machine Learning 和 NLP 充满热情的 BTech 学生。 这个项目是我在应用机器学习学习之旅中构建的。 - 📧 电子邮件:meshivanshu1512@gmail.com - 🐙 GitHub:[@shivanshu1512](https://github.com/shivanshu1512) ## ⭐ 如果这个项目对你有帮助,请给它点个 Star! 这会激励我构建更多酷炫的项目。🙏 *使用 Python、Scikit-learn、XGBoost 和 Streamlit 充满 ❤️ 构建*
标签:Apex, Kubernetes, NLP, scikit-learn, Streamlit, 文本分类, 文本相似度, 机器学习, 访问控制, 逆向工具