解读Glassdoor:基于NLP驱动的洞察力,为明智决策提供支持

介绍

在今天具有挑战性的就业市场中,个人必须收集可靠的信息以做出明智的职业决策。Glassdoor 是一个流行的平台,员工可以匿名分享他们的体验。然而,评论的丰富性可能会使求职者倍感压力。为了解决这个问题,我们将尝试构建一个自动将 Glassdoor 评论压缩成有见地的摘要的 NLP 驱动系统。我们的项目探索了从使用 Selenium 进行评论收集到利用 NLTK 进行摘要的逐步过程。这些简明的摘要提供了有关公司文化和发展机会的有价值的见解,帮助个人将他们的职业愿望与合适的组织对齐。我们还讨论了限制因素,例如解释差异和数据收集错误,以确保全面理解摘要过程。

学习目标

本项目的学习目标包括开发一个强大的文本摘要系统,将体积庞大的 Glassdoor 评论有效地压缩成简洁而信息丰富的摘要。通过进行这个项目,您将:

  • 了解如何总结公共平台上的评论,在这种情况下是 Glassdoor,以及它如何极大地有益于在接受工作机会之前寻求评估组织的个人。认识到大量文本数据可用性所带来的挑战以及自动化摘要技术的需要。
  • 学习网络爬虫的基础知识,利用 Python 中的 Selenium 库提取 Glassdoor 评论。探索网页导航,与元素交互以及检索文本数据以进行进一步分析的方法。
  • 开发清洁和准备从 Glassdoor 评论中提取的文本数据的技能。实施处理噪声、删除不相关信息以及确保输入数据质量以进行有效摘要的方法。
  • 利用 Python 中的 NLTK(自然语言工具包)库,利用广泛的 NLP 功能进行文本处理、标记化、句子分割等。获得使用这些工具促进文本摘要过程的实践经验。

本文章是数据科学博客马拉松的一部分。

项目描述

通过开发自动文本摘要系统来最小化 Glassdoor 评论反馈的大量复查。通过利用自然语言处理(NLP)技术和机器学习算法,该系统从评论中提取最相关的信息,并生成简洁而信息丰富的摘要。该项目将涉及使用 Selenium 从 Glassdoor 收集数据,数据预处理和尖端文本摘要技术,以使个人能够迅速掌握有关组织文化和工作环境的显著见解。

问题陈述

本项目旨在帮助人们根据众多 Glassdoor 评论解读组织文化和工作环境。Glassdoor 是一个高度使用的平台,已成为个人收集有关潜在雇主见解的主要资源。然而,Glassdoor 上大量的评论可能会令人望而生畏,使个人很难有效地概括有用的见解。

了解组织文化、领导风格、工作与生活的平衡、晋升前景和整体员工幸福感是可以极大地影响一个人职业决策的关键考虑因素。但是,浏览众多评论的任务,每个评论的长度、风格和重点领域均不同,确实具有挑战性。此外,缺乏简明易懂的摘要只会加剧这一问题。

因此,我们的任务是设计一种摘要文本的系统,能够高效处理 Glassdoor 的大量评论并提供简洁而信息丰富的摘要。通过自动化这个过程,我们旨在以用户友好的方式提供公司特点的详尽概述。该系统将使求职者能够快速了解评论中的主题和情感,从而促进就业机会的决策过程更加顺畅。

通过解决这个问题,我们旨在缓解求职者面临的信息饱和问题,并使他们能够做出符合他们职业目标的明智决策。通过本项目开发的文本摘要系统将是寻求了解组织工作氛围和文化的个人的宝贵资源,为他们提供信心来导航就业领域。

方法

我们旨在通过 Glassdoor 评论简化对公司的工作文化和环境的了解。我们的策略涵盖数据收集、准备和文本摘要的系统过程。

  1. 数据收集:我们将利用Selenium库来爬取Glassdoor的评论。这将使我们能够累积大量的目标公司评论。自动化这个过程可以确保收集到多样化的评论,提供全面的经验和观点。
  2. 数据准备:一旦评论被收集,我们将进行数据预处理,以确保提取的文本质量和相关性。这包括删除无关数据,处理异常字符或格式不一致性,并将文本分割成像句子或单词这样的较小组件。
  3. 文本摘要:在文本摘要阶段,我们将采用自然语言处理(NLP)技术和机器学习算法,从预处理的评论数据中生成简要摘要。

情境

想象一下Alex的情况,他是一名熟练的软件工程师,在一家知名的科技公司Salesforce获得了一份职位。作为决策过程的一部分,Alex希望深入了解Salesforce的工作文化、环境和员工满意度。

通过我们压缩Glassdoor评论的方法,Alex可以迅速访问许多Salesforce特定员工的评论中的主要观点。通过利用我们创建的自动文本摘要系统,Alex可以获得简洁的摘要,突出重点元素,如公司的团队合作文化、晋升机会和整体员工满意度。

通过审查这些摘要,Alex可以充分了解Salesforce的企业特点,而不必花费太多时间阅读评论。这些摘要提供了简洁而深入的视角,使Alex能够做出符合其职业目标的决策。

数据收集和准备

我们将使用Python中的Selenium库从Glassdoor获取评论。提供的代码片段详细阐述了这个过程。以下是保持透明度和遵守伦理标准所涉及的步骤:

导入库

我们首先导入必要的库,包括Selenium、Pandas和其他必要的模块,确保收集数据的综合环境。

# 导入必要的库
import selenium
from selenium import webdriver as wb
import pandas as pd
import time
from time import sleep
from selenium.webdriver.support.ui 
import WebDriverWait
from selenium.webdriver.common.by 
import By
from selenium.webdriver.support 
import expected_conditions as EC
from selenium.webdriver.common.keys 
import Keys
import itertools

设置Chrome Driver

我们通过指定适当的路径来建立ChromeDriver的设置,从而允许与Selenium框架的无缝集成。

# 将工作目录更改为保存chromedriver的路径
# 并设置chrome driver

%cd "保存chromedriver的路径"
driver = wb.Chrome(r"YOUR PATH\chromedriver.exe")

driver.get('https://www.glassdoor.co.in
/Reviews/Salesforce-Reviews-E11159.
htm?sort.sortType=RD&sort.ascending=false&filter.
iso3Language=eng&filter.
employmentStatus=PART_TIME&filter.employmentStatus=REGULAR')

访问Glassdoor页面

我们使用driver.get()函数访问包含所需评论的Glassdoor页面。对于本例,我们特别针对Salesforce评论页面。

遍历评论

在一个结构良好的循环中,我们遍历预定数量的页面,实现系统化和广泛的评论提取。这个计数可以根据个人要求进行调整。

扩展评论详情

我们通过与“继续阅读”元素交互,主动扩展每次迭代的评论详情,促进相关信息的全面收集。

提取评论信息

我们系统地定位和提取许多评论详情,包括评论标题、工作细节(日期、角色、地点)、评级、雇员任期、优点和缺点。这些详情被分隔并存储在单独的列表中,确保准确的表示。

创建DataFrame

通过利用Pandas的功能,我们建立一个临时DataFrame(df_temp),以容纳来自每次迭代的提取信息。这个迭代的DataFrame然后被附加到主DataFrame(df)中,允许评论数据的合并。

分页

为了管理分页过程,我们会高效地定位“下一页”按钮并触发点击事件,从而导航至下一页的评论。这个系统性的进程会一直进行,直到所有可用的评论都被成功获取。

数据清洗和排序

最后,我们进行必要的数据清洗操作,例如将“日期”列转换为日期时间格式、重置索引以提高组织性,并根据评论日期按降序对DataFrame进行排序。

这种细致的方法确保了许多Glassdoor评论的全面和合法收集,从而使进一步的分析和随后的文本摘要任务变得可能。

# 导入必要的库
import selenium
from selenium import webdriver as wb
import pandas as pd
import time
from time import sleep
from selenium.webdriver.support.ui 
import WebDriverWait
from selenium.webdriver.common.by 
import By
from selenium.webdriver.support 
import expected_conditions as EC
from selenium.webdriver.common.keys 
import Keys
import itertools

# 更改工作目录为保存chromedriver的路径
# 设置chrome driver
%cd "C:\Users\akshi\OneDrive\Desktop"
driver = wb.Chrome(r"C:\Users\akshi\OneDrive\Desktop\chromedriver.exe")

# 使用特定过滤器访问Glassdoor页面
driver.get('https://www.glassdoor.co.in/Reviews/
Salesforce-Reviews-E11159.htm?sort.sortType=RD&sort.
ascending=false&filter.iso3Language=eng&filter.
employmentStatus=PART_TIME&filter.employmentStatus=REGULAR')

df = pd.DataFrame()

num = 20
for _ in itertools.repeat(None, num):
    continue_reading = driver.find_elements_by_xpath(
        "//div[contains(@class,'v2__EIReviewDetailsV2__
        continueReading v2__EIReviewDetailsV2__clickable v2__
        EIReviewDetailsV2__newUiCta mb')]"
    )
    

    time.sleep(5)
    
    review_heading = driver.find_elements_by_xpath("//a[contains
    (@class,'reviewLink')]")
    review_heading = pd.Series([i.text for i in review_heading])

    dets = driver.find_elements_by_xpath("//span[contains(@class,
    'common__EiReviewDetailsStyle__newUiJobLine')]")
    dets = [i.text for i in dets]
    dates = [i.split(' - ')[0] for i in dets]
    role = [i.split(' - ')[1].split(' in ')[0] for i in dets]
    try:
        loc = [i.split(' - ')[1].split(' in ')[1] if 
        i.find(' in ')!=-1 else '-' for i in dets]
    except:
        loc = [i.split(' - ')[2].split(' in ')[1] if 
        i.find(' in ')!=-1 else '-' for i in dets]

    rating = driver.find_elements_by_xpath("//span[contains
    (@class,'ratingNumber mr-xsm')]")
    rating = [i.text for i in rating]

    emp = driver.find_elements_by_xpath("//span[contains
    (@class,'pt-xsm pt-md-0 css-1qxtz39 eg4psks0')]")
    emp = [i.text for i in emp]

    pros = driver.find_elements_by_xpath("//span[contains
    (@data-test,'pros')]")
    pros = [i.text for i in pros]

    cons = driver.find_elements_by_xpath("//span[contains
    (@data-test,'cons')]")
    cons = [i.text for i in cons]
    
    df_temp = pd.DataFrame(
        {
            '日期': pd.Series(dates),
            '职位': pd.Series(role),
            '任职时间': pd.Series(emp),
            '地点': pd.Series(loc),
            '评分': pd.Series(rating),
            '优点': pd.Series(pros),
            '缺点': pd.Series(cons)
        }
    )
    
    df = df.append(df_temp)
    
    try:
        driver.find_element_by_xpath("//button[contains
        (@class,'nextButton css-1hq9k8 e13qs2071')]").click()
    except:
        print('没有更多评论')


df['日期'] = pd.to_datetime(df['日期'])
df = df.reset_index()
del df['index']
df = df.sort_values('日期', ascending=False)
df

我们得到如下输出。

文本摘要

为了从提取的评论中生成摘要,我们使用NLTK库,并应用各种文本处理和分析技术。代码片段演示了这一过程,确保符合伦理标准,并避免AI文本检测平台可能存在的问题。

导入库

我们从collections模块中导入必要的库,包括pandas、string、nltk和Counter。这些库提供了强大的数据操作、字符串处理和文本分析功能,确保了全面的文本摘要工作流程。

import string
import nltk
from nltk.corpus import stopwords
from collections import Counter
nltk.download('stopwords')
stop_words = set(stopwords.words('english'))

数据准备

我们根据所需的角色(在我们的情况下是软件工程师)过滤获取的评论,确保相关性和上下文特定的分析。删除空值,并清理数据以便于准确处理。

role = input('输入角色')

df = df.dropna()
df = df[df['Role'].str.contains(role)]

文本预处理

每个评论的优点和缺点都分别进行处理。我们确保小写一致性,并使用translate()函数消除标点符号。然后将文本分割成单词,删除停用词和与上下文相关的特定词语。得到的单词列表,pro_words和con_words,捕捉了进一步分析所需的相关信息。

pros = [i for i in df['Pros']]
cons = [i for i in df['Cons']]
    
# 将pro分割成单词列表
all_words = []
pro_words = ' '.join(pros)
pro_words = pro_words.translate(str.maketrans
('', '', string.punctuation))
pro_words = pro_words.split()
specific_words = ['great','work','get','good','company',
'lot','it’s','much','really','NAME','dont','every',
'high','big','many','like']
pro_words = [word for word in pro_words if word.lower() 
not in stop_words and word.lower() not in specific_words]
all_words += pro_words

con_words = ' '.join(cons)
con_words = con_words.translate(str.maketrans
('', '', string.punctuation))
con_words = con_words.split()
con_words = [word for word in con_words if 
word.lower() not in stop_words and word.lower() 
not in specific_words]
all_words += con_words

词频分析

利用collections模块中的Counter类,我们获得了pros和cons的单词频率计数。这种分析允许我们识别评论中最常出现的单词,便于进一步关键词提取。

# 计算每个单词的频率
pro_word_counts = Counter(pro_words)
con_word_counts = Counter(con_words)

关键词提取

为了识别关键主题和情感,我们分别从pros和cons中提取前10个最常见的单词,使用most_common()方法。我们还处理了两个集合之间存在的常见关键词,确保摘要的全面和公正。

# 从pros和cons中获取前10个最常见的单词
keyword_count = 10
top_pro_keywords = pro_word_counts.most_common(keyword_count)
top_con_keywords = con_word_counts.most_common(keyword_count)

# 检查pros和cons之间是否有任何共同的关键词
common_keywords = list(set([keyword for keyword, frequency in 
top_pro_keywords]).intersection([keyword for keyword, 
frequency in top_con_keywords]))

# 根据需要处理共同的关键词
for common_keyword in common_keywords:
  pro_frequency = pro_word_counts[common_keyword]
  con_frequency = con_word_counts[common_keyword]
  if pro_frequency > con_frequency:
      top_con_keywords = [(keyword, frequency) for keyword, 
      frequency in top_con_keywords if keyword != common_keyword]
      top_con_keywords = top_con_keywords[0:6]
  else:
      top_pro_keywords = [(keyword, frequency) for keyword, 
      frequency in top_pro_keywords if keyword != common_keyword]
      top_pro_keywords = top_pro_keywords[0:6]
  top_pro_keywords = top_pro_keywords[0:5]

情感分析

我们通过定义正面和负面词语列表来对pros和cons进行情感分析。通过对单词计数进行迭代,我们计算出总体情感得分,提供了对评论中表达的总体情感的洞察。

情感分数计算

为了量化情感分数,我们将总情感分数除以评论中单词的总数。将其乘以100可以得到情感分数百分比,提供数据中情感分布的全面视图。

# 通过计算正负词汇出现频率的和来计算总情感分数

positive_words = ["惊人的", "优秀的", "伟大的", "好的", 
"积极的", "愉快的", "满意的", "快乐的", "高兴的", 
"满意的", "愉悦的", "满意的", "满足的", "快乐的", "幸运的", 
"幸运的", "高兴的", "激动的", "兴高采烈的", 
"欣喜若狂的", "狂喜的", "满意的", "宽慰的", "高兴的", 
"印象深刻的", "满意的", "愉快的", "令人钦佩的", "珍视",
"鼓舞人心的"]
negative_words = ["糟糕的", "缓慢的", "可怕的", "恐怖的", 
"坏的", "可怕的", "不愉快的", "不满意的", "不高兴的", 
"不满意的", "悲惨的", "失望的", "沮丧的", 
"生气的", "不安的", "冒犯的", "恶心的", "厌恶的", 
"震惊的", "害怕的", "恐惧的", "惊恐万状的", "惊慌失措的", 
"惊恐的", "吃惊的", "困惑的", "迷惑的"]

positive_score = 0
negative_score = 0
for word, frequency in pro_word_counts.items():
    if word in positive_words:
        positive_score += frequency
for word, frequency in con_word_counts.items():
    if word in negative_words:
        negative_score += frequency

overall_sentiment_score = positive_score - negative_score

# 计算情感分数的百分比
total_words = sum(pro_word_counts.values()) + sum(con_word_counts.values())
sentiment_score_percent = (overall_sentiment_score / total_words) * 100

输出结果

我们提供正面和负面的前5个关键词,总情感分数,情感分数百分比以及评论中的平均评分。这些指标为组织的主流情感和用户体验提供了有价值的见解。

# 输出结果
print("正面前5个关键词:", top_pro_keywords)
print("负面前5个关键词:", top_con_keywords)
print("总情感分数:", overall_sentiment_score)
print("情感分数百分比:", sentiment_score_percent)
print('平均给分',df['Rating'].mean())

句子评分

为了捕捉最相关的信息,我们根据句子的优点和缺点创建了一个词袋模型。我们实现了一个评分函数,根据特定单词或单词组合的出现情况为每个句子分配分数,确保有效的摘要提取过程。

# 将优点和缺点合并为一个句子列表
sentences = pros + cons

# 为句子创建一个词袋模型
bow = {}
for sentence in sentences:
  words = ' '.join(sentences)
  words = words.translate(str.maketrans
  ('', '', string.punctuation))
  words = words.split()
  for word in words:
      if word not in bow:
          bow[word] = 0
      bow[word] += 1

# 定义一个启发式评分函数,根据某些单词或单词组合的出现情况为每个句子分配分数
def score(sentence):
    words = sentence.split()
    score = 0
    for word in words:
        if word in ["好的", "伟大的", "优秀的"]:
            score += 2
        elif word in ["糟糕的", "坏的", "可怕的"]:
            score -= 2
        elif word in ["文化", "福利", "机会"]:
            score += 1
        elif word in ["平衡", "晋升", "领土"]:
            score -= 1
    return score

# 对句子进行评分并按分数排序
scored_sentences = [(score(sentence), sentence) for sentence in sentences]
scored_sentences.sort(reverse=True)

摘要提取

我们提取了分数最高的10个句子,并使用join()函数将它们聚合成一个连贯的摘要。这个摘要概括了评论中表达的最重要的观点和情感,为决策提供了简洁的概述。

# 提取分数最高的前10个句子
top_sentences = [sentence for score, sentence in scored_sentences[:10]]

# 将分数最高的句子连接成一个摘要
summary = " ".join(top_sentences)

最后,我们打印生成的摘要,这是一个对寻求了解组织文化和工作环境的个人非常有价值的资源。

# 打印摘要
print("摘要:")
print(summary)
  • 好的人才、良好的文化、良好的福利、关注精神健康、基本上全面远程。
  • 良好的工作生活平衡和伦理关心员工。
  • 同事真的很棒,非毒性和良好的文化
  • 良好的工作生活平衡、良好的薪酬、良好的文化
  • 1. 良好的薪酬 2. 有趣的工作 3. 良好的工作生活平衡 4. 绝大部分的紧急事项都有保障
  • 良好的工作生活平衡,良好的薪酬,良好的文化,惊人的同事,高薪水
  • 非常好的工作文化和福利
  • 良好的工作生活平衡,良好的福利,支持家庭价值观,良好的职业发展机会。
  • 合作,支持,强大的文化(ohana),成长机会,向异步迈进,技术上声音,良好的导师和队友

如上所述,我们得到了一个简洁的摘要和对软件工程职位特定的公司文化、福利和利益的良好理解。通过利用NLTK的能力并采用强大的文本处理技术,这种方法使得从提取的Glassdoor评论中提取关键词、情感分析和生成信息摘要成为可能。

用例

正在开发的文本摘要系统在各种实际场景中都有很大的潜力。它的多功能应用可以使利益相关者受益,包括求职者、人力资源专业人员和招聘人员。以下是一些值得注意的用例:

  1. 求职者: 求职者可以从文本摘要系统中获益,该系统提供了一个简洁而信息丰富的组织文化和工作环境概述。通过压缩Glassdoor评论,求职者可以快速评估总体情感,识别重复的主题,并就组织是否符合他们的职业愿望和价值观做出明智的决策。
  2. 人力资源专业人员: 人力资源专业人员可以利用文本摘要系统高效地分析大量的Glassdoor评论。通过总结评论,他们可以获得有价值的见解,了解不同组织的优势和劣势。这些知识可以指导雇主品牌策略,帮助识别改进领域,并支持基准的倡议。
  3. 招聘人员: 招聘人员可以通过利用文本摘要系统来评估组织的声誉和工作文化,从而优化他们的时间和精力。总结的Glassdoor评论使招聘人员能够迅速识别关键情感和重要方面与候选人沟通。这有助于更有针对性和有效的招聘过程,增强候选人的参与和选择结果。
  4. 管理和决策者: 文本摘要系统为组织管理和决策者提供了有价值的见解。通过总结内部Glassdoor评论,他们可以更好地了解员工的看法、满意度和潜在的关注领域。这些信息可以指导战略决策、支持员工参与倡议,并促进积极的工作环境。

局限性

我们总结Glassdoor评论的方法涉及几个局限性和潜在挑战,必须加以考虑。这些包括:

  1. 数据质量:生成的摘要的准确性和可靠性严重依赖于输入数据的质量。确保用于总结的Glassdoor评论的真实性和可信度是至关重要的。必须采取数据验证技术和针对虚假或有偏见的评论的措施,以减轻这种局限性。
  2. 主观性和偏见: Glassdoor评论本质上反映了主观的意见和经验。总结过程可能会无意中放大或减弱某些情感,导致有偏见的摘要。考虑潜在的偏见并开发无偏见的摘要技术对于确保公正和准确的表述至关重要。
  3. 上下文理解: 理解评论的上下文和细微差别可能是具有挑战性的。总结算法可能难以完全理解特定短语或表达的全部含义和影响,可能会丢失重要信息。结合高级的上下文理解技术,如情感分析和上下文感知模型,可以帮助解决这个局限性。
  4. 概括性: 必须认识到生成的摘要提供的是一个总体概述,而不是每篇评论的详尽分析。该系统可能无法捕捉评论中提到的每个细节或独特的经验,需要用户考虑更广泛的信息范围才能做出结论或判断。
  5. 及时性: Glassdoor评论是动态的,随着时间的推移而变化。总结系统可能无法提供实时更新,生成的摘要可能会过时。实现定期重新总结的机制或集成实时评论监控可以帮助解决这个局限性,并确保摘要的相关性。

承认并积极解决这些限制非常重要,以确保系统的完整性和实用性。定期评估、用户反馈的整合和持续的改进对于改善摘要系统和减轻潜在偏见或挑战至关重要。

结论

该项目的目标是通过众多的 Glassdoor 评论简化对公司文化和工作环境的理解。我们通过实施一个包括数据收集、准备和文本摘要的系统化方法,成功地构建了一个高效的文本摘要系统。该项目提供了宝贵的见解和关键学习,例如:

  1. 文本摘要系统为求职者、人力资源专业人员、招聘人员和决策者提供了对公司的重要见解。概括许多评论通过彻底理解公司的文化、工作环境和员工情感,有助于更有效地做出决策。
  2. 该项目展示了自动化方法在收集和分析 Glassdoor 评论方面的有效性,使用 Selenium 进行 Web 抓取和 NLTK 进行文本摘要。自动化节省了时间和精力,并实现了可扩展和系统化的评论分析。
  3. 该项目强调了在准确摘要评论中理解上下文的重要性。通过数据预处理、情感分析和关键词提取技术解决了数据质量、主观偏见和上下文细微差别等因素。
  4. 在该项目中创建的文本摘要系统具有求职者、人力资源专业人员、招聘人员和管理团队的实际应用。它有助于做出知情决策,支持基准测试和雇主品牌建设,实现对公司的高效评估,并为组织发展提供宝贵的见解。

从该项目中学到的经验包括数据质量的重要性、主观评论的挑战、在摘要中上下文的重要性以及系统改进的循环性质。通过使用机器学习算法和自然语言处理技术,我们的文本摘要系统提供了一种高效而全面的方式,从 Glassdoor 评论中获取信息。

常见问题解答

本文中显示的媒体不归 Analytics Vidhya 拥有,并由作者自行决定使用。