介绍
H1B签证计划为全球技术人才提供了进入美国的机会。每年,成千上万的才华横溢的专业人士通过该计划进入美国,为各个行业做出贡献,推动创新。让我们深入H1B签证数据的世界,了解外国劳工认证办公室(OFLC)提供的有趣信息和背后的故事。本文揭示了H1B签证数据分析的结果,我们从中获得了洞见和有趣的故事。通过特征工程,我们从外部来源增强了数据集的信息。通过精细的数据整理,我们仔细组织数据,以便更好地理解和分析数据。最后,数据可视化揭示了关于2014至2016年间美国熟练工人的有趣趋势和未被告知的见解。
![]()
- 探索并分析外国劳工认证办公室(OFLC)提供的H1B签证数据,并了解其在吸引熟练外国劳工来美国方面的重要性。
- 了解数据预处理的过程,包括数据清洗、特征工程和数据转换技术。
- 检查和分析H1B签证申请的接受和拒绝率,这可能会影响这些率。
- 熟悉数据可视化技术,以有效地呈现和传达发现结果。
注:🔗 您可以在Kaggle上找到这个分析的完整代码和数据集,以探索分析背后的整个过程:H1B Analysis on Kaggle
本文是数据科学博客马拉松的一部分。
什么是H1B签证?
H1B签证计划是美国移民政策的关键组成部分,旨在吸引高技能外籍工人填补各个行业的专业职位。它解决了技能短缺问题,促进了创新,推动了经济增长。
要获得H1B签证,必须按照以下关键步骤:
- 找到一家愿意为该外籍工人赞助签证的美国雇主。
- 雇主代表外籍工人向美国移民局(USCIS)提交H1B申请。
- 该申请受到年度配额的限制,如果申请数量超过可用名额,则可能通过抽签程序。
- 如果被选中,USCIS将审核申请的合格性和符合性。
- 如果获得批准,外籍工人可以获得H1B签证,并开始在美国为雇主工作。
![]()
该过程涉及满足特定要求,例如持有学士学位或同等学历,并处理其他考虑因素,例如最低工资确定和雇主-雇员关系的文件记录。遵守和准备充分对于成功的H1B签证申请至关重要。
数据集
- 外国劳工认证办公室(OFLC)提供的2014年、2015年和2016年组合数据集包括案件编号、案件状态、雇主名称、雇主城市、雇主州、职位名称、SOC代码、SOC名称、工资率、工资单位、最低工资、最低工资来源、年份等列。
- 这些列提供了关于H1B签证申请的基本信息,包括案件细节、雇主信息、职位名称、工资率和最低工资数据。
- 使用OFLC官方网站https://www.foreignlaborcert.doleta.gov/performancedata.cfm上提供的数据集和数据布局,以完全了解所有可用列及其描述。
预处理
加入我一起进行迷人的数据转换之旅!我将xlsx文件转换为CSV,为了保持一致性,将列名称重命名,因为每个列包含相同的数据,但在每个年份中的名称不同,并将三年的数据合并。结果是一个庞大的数据集,包含1,786,160行和17列。
特征工程
- 通过创建就业期限列增强了数据集,该列基于开始和结束日期。
- 通过从结束日期中减去开始日期来计算持续时间(以天为单位)。
- 删除具有负值的行,因为负的就业期限在逻辑上是不可能的。
- 通过将其除以30.44来将持续时间转换为月,表示四年内一个月的平均天数。这种方法确保了准确的估计,考虑了闰年。
- 通过将空条目替换为0来处理缺失值。
# 将日期列转换为日期时间格式,并将无效数据赋值为NaN
final_df['LCA_CASE_EMPLOYMENT_START_DATE'] = pd.to_datetime(final_df['LCA_CASE_EMPLOYMENT_START_DATE'], errors='coerce')
final_df['LCA_CASE_EMPLOYMENT_END_DATE'] = pd.to_datetime(final_df['LCA_CASE_EMPLOYMENT_END_DATE'], errors='coerce')
# 用LCA_CASE_EMPLOYMENT_END_DATE减去LCA_CASE_EMPLOYMENT_START_DATE,以找到就业期间
LCA_CASE_EMPLOYMENT_PERIOD=final_df["LCA_CASE_EMPLOYMENT_END_DATE"]-final_df["LCA_CASE_EMPLOYMENT_START_DATE"]
# 创建一个新列,命名为LCA_CASE_EMPLOYMENT_PERIOD,赋值为LCA_CASE_EMPLOYMENT_PERIOD
final_df.insert(7, 'LCA_CASE_EMPLOYMENT_PERIOD', LCA_CASE_EMPLOYMENT_PERIOD)
# 将LCA_CASE_EMPLOYMENT_PERIOD转换为天格式
final_df['LCA_CASE_EMPLOYMENT_PERIOD'] = final_df['LCA_CASE_EMPLOYMENT_PERIOD'].dt.days
# 删除异常值,即就业天数小于0的值。
final_df = final_df[final_df['LCA_CASE_EMPLOYMENT_PERIOD'] > 0]
final_df['LCA_CASE_EMPLOYMENT_PERIOD'].describe()
# 就业期间转换为月份
final_df['LCA_CASE_EMPLOYMENT_PERIOD'] = (round(final_df['LCA_CASE_EMPLOYMENT_PERIOD'] / 30.44))
# 用0填充缺失值,并将列类型转换为整数
final_df['LCA_CASE_EMPLOYMENT_PERIOD']=final_df['LCA_CASE_EMPLOYMENT_PERIOD'].fillna(0).astype(int)
- 通过提取提供的NAICS代码的前两个数字,确定每个雇主的行业。
- 从在线下载NAICS代码和行业数据,以获得相应的行业信息。
- 创建一个名为EMPLOYER_SECTOR的新列,将每个雇主的基础代码映射到其相应的行业。
# 将LCA_CASE_NAICS_CODE列转换为字符串数据类型
final_df['LCA_CASE_NAICS_CODE'] = final_df['LCA_CASE_NAICS_CODE'].astype(str)
# 提取每个字符串值的前两个数字
final_df['LCA_CASE_NAICS_CODE'] = final_df['LCA_CASE_NAICS_CODE'].str[:2]
# 读取NAICS_data以进行交叉检查并创建一个新列以获取雇主行业
NAICS_data=pd.read_csv("/kaggle/input/h1b-visa/NAICS_data.csv")
NAICS_data.head()
# 循环遍历所有naics_unique_values中的NAICS
for i in naics_unique_values:
try:
# 假设数据帧名称为'df'
NAICS_data_code = NAICS_data.loc[NAICS_data['NAICS_CODE'] == i, 'NAICS_TITLE'].iloc[0]
except:
# 如果没有一个特定的soc代码的索引,则职业名称将为空
NAICS_data_code = "Unknown"
# 为条件创建布尔掩码
mask = (final_df['LCA_CASE_NAICS_CODE'] == i)
# 为过滤行更新LCA_CASE_SOC_NAME列
final_df.loc[mask, 'EMPLOYER_SECTOR'] = NAICS_data_code
- 此外,我从LCA_CASE_SUBMIT字段中提取了年份信息,创建了一个专用的年份列。这简化了数据分析,并允许方便的基于年份的见解。
# 从日期时间列LCA_CASE_SUBMIT中提取年份组件,并将其存储在新列year中
final_df['year'] = final_df['LCA_CASE_SUBMIT'].dt.year
数据转换
- 我执行了一系列数据转换,以完善数据集。删除了重复项,确保了干净和唯一的记录。
- 通过删除每行中的特殊字符,对LCA_CASE_SOC_CODE列进行了预处理。
# 删除'LCA_CASE_SOC_CODE'列中"."后的数字
final_df['LCA_CASE_SOC_CODE'] = final_df['LCA_CASE_SOC_CODE'].astype(str).apply(lambda x: x.split('.')[0])
# 函数以更正LCA_CASE_SOC_CODE
def preprocess_column(column):
pattern = r"^\d{2}-\d{4}$" # "XX-XXXX"格式的正则表达式模式
def preprocess_value(value):
if ("-" not in value) and len(value) < 6:
cleaned_value=np.nan
elif "-" in value :
value=value.replace('-','')
cleaned_value=value[0:2]+"-"+value[2:6]
if len(cleaned_value) != 7:
cleaned_value=np.nan
elif ("-" not in value) and len(value) > 5:
value=value.replace('/', '')
cleaned_value=value[0:2]+"-"+value[2:6]
return cleaned_value
cleaned_column = column.apply(lambda x: np.nan if pd.isna(x) else (x if re.search(pattern, str(x)) else preprocess_value(x)))
return cleaned_column
final_df["LCA_CASE_SOC_CODE"] = preprocess_column(final_df["LCA_CASE_SOC_CODE"])
# 替换'LCA_CASE_WAGE_RATE_FROM'列中的值
# 定义自定义函数来预处理工资率列
def preprocess_wage_rate(cell_value):
if isinstance(cell_value, float):
return cell_value
elif '-' in cell_value:
return cell_value.split('-')[0].strip()
else:
return cell_value
# 将自定义函数应用于工资率列
final_df['LCA_CASE_WAGE_RATE_FROM'] = final_df['LCA_CASE_WAGE_RATE_FROM'].apply(lambda x: preprocess_wage_rate(x))
- 我并没有消除LCA_CASE_SOC_NAME列中的空值,而是从”https://www.bls.gov/oes/current/oes_stru.htm#29-0000″上抓取了SOC代码和名称,并创建了一个CSV文件。然后我利用这个CSV文件来填补LCA_CASE_SOC_NAME中的空值。
# 初始化webdriver
driver = webdriver.Chrome()
# 导航到网页
driver.get('https://www.bls.gov/oes/current/oes_stru.htm#29-0000')
# 查找所有li元素
li_elements = driver.find_elements("xpath","//li")
# 创建空列表以存储数据
data = []
# 遍历li元素
for li in li_elements:
text = li.text
if "-" in text:
# 使用正则表达式提取SOC代码和职业名称
words = text.split()
soc=words[0]
name = (" ".join(words[1::])).replace('"', '').strip()
name_list=(words[1::])
if "-" in name:
for i, word in enumerate(name_list):
if ("-" in word) and (len(word) > 1):
name =(' '.join(name_list[:i])).replace('"', '').strip()
break
data.append({'SOC Code': soc, 'Occupation Name': name})
# 关闭webdriver
driver.quit()
# 创建数据帧
occupation_data = pd.DataFrame(data)
# 将数据帧保存为CSV文件
occupation_data.to_csv('occupations.csv', index=False)
解释
- 数据集中的’LCA_CASE_WAGE_RATE_FROM’列中有以不同单位表示的工资率,需要进行标准化以便进行一致的分析。
- 为了实现标准化,我将工资率转换为一个统一的年度值。这涉及将速率乘以特定的因子,具体取决于它们的原始单位。
- 例如,月薪率乘以12以考虑一年中的月数。同样地,每周薪资率乘以52(一年中的周数),每两周薪资率乘以26(假设一年中有26个两周期)。
- 处理小时工资率需要考虑职位是否为全职。对于标记为全职(’FULL_TIME_POS’ = ‘Y’)的职位,我将每小时工资率乘以每周40小时和每年52周。
- 对于非全职职位(’FULL_TIME_POS’ = ‘N’),我使用每周35小时和每年52周作为计算年度率的基础。
- 进行必要的计算后,’LCA_CASE_WAGE_RATE_FROM’列中的单位被替换为’Year’,以反映工资率在年度基础上的标准化表示。
- 这种标准化使得可以对数据集中的不同职位和类别的工资率进行有意义的比较和分析。
- 为了清洁LCA_CASE_SOC_NAME列,我将所有数据转换为小写形式,并将以’s’结尾的数据转换为单数形式。
- 为了方便理解,我将LCA_CASE_WAGE_RATE_FROM列中的值除以1000,以表示千元工资。删除了具有负工资值的行,因为它们无效。
简介
- 此外,我利用IQR方法消除了0.1和0.99分位数中的异常值,以确保准确的分析。
- 在“STATUS”列中,“INVALIDATED”和“REJECTED”这些值被替换为“DENIED”。这简化了被拒绝的签证申请的表示,因为“INVALIDATED”和“REJECTED”都指被拒绝的申请,并确保在数据集中使用单一标签“DENIED”表示所有被拒绝的H1B签证申请。
- 删除了不必要的列,包括“LCA_CASE_EMPLOYMENT_START_DATE”,“LCA_CASE_EMPLOYMENT_END_DATE”,“LCA_CASE_WAGE_RATE_UNIT”,“FULL_TIME_POS”和“LCA_CASE_NAICS_CODE”,简化了数据集并增强了清晰度。
- 数据现在已经精细化处理,准备好进行深入的探索。
分析
H-1B签证申请的总数是多少?过去三年的申请增长率是多少?

在2014年至2015年期间,H1B签证申请数量激增,增长了惊人的17.7%。来自世界各地的熟练人才渴望抓住在美国的机会。然而,2016年情况出现了意外的变化,申请数量突然下降了9%。这种下降让我们感到疑惑:是什么导致了这种显著的变化?
什么导致了申请率的突然下降?是拒绝率增加还是其他因素导致了这种下降?

令人惊讶的是,签证的拒绝率已经从5.41%降至3.4%。另一方面,接受率每年稳步增长。这也可能表明雇主已经变得更擅长提交强有力的申请,从而降低了拒绝率。
拒绝率的下降反映了一个积极的趋势,并标志着H1B签证申请人的更加有利的环境。不断增加的接受率表明美国对高技能外籍工人的需求正在增长。
这些积极的趋势可以归因于美国政府为熟练移民营造友好环境的努力。政府可能实施了更加有利的政策,简化了签证流程,消除了不必要的障碍。这反过来可能有助于降低拒绝率。因此,申请量的下降不能仅归因于更高的拒绝率。
H1B签证申请的前十大行业是哪些?

经过分析,我们发现大约72.4%的H1B签证申请来自专业、科学和技术服务行业。这个行业涵盖各种领域,包括计算机编程、科学研究、工程和咨询服务。申请量的激增表明这些领域需要高技能的专业人才。
此外,大公司对其员工增加H1B签证赞助的影响,也在专业、科学和技术服务行业中不断增加。这些公司依赖高技能的工人来维持他们的竞争优势,并在行业中保持增长。
前十大申请人数最多的雇主是哪些,并且它们属于哪些行业?

根据全面的分析,我们发现专业、科学和技术服务行业中有9家申请人数最多的雇主。这个行业以其持续对高技能人才的需求而闻名,涵盖了计算机编程、科学研究、工程和咨询服务等各种领域。
Infosys是领先的雇主,获得了惊人的82,271个批准的申请,而前十名雇主中被拒绝的申请数量最少。在H1B签证申请数量方面,Infosys的优异表现超过了排名第二的TCS和排名第三的Wipro的总和。
Infosys在H1B签证申请过程中的优异表现引发了有趣的问题,涉及该公司的方法以及它正在招聘哪些具体职位。
前十大雇主对H1B签证职位分布产生了多大的影响?

在分析数据后,我们创建了一张图表,以直观地表示前十大H1B签证发起雇主对前十大职位的贡献。剩余的雇主被分组为“其他雇主”。该图表强调了,虽然“其他雇主”拥有相当大的份额,但前十大雇主对前十大职位产生了重大影响。
例如,Infosys在计算机系统分析师职位上发挥了重要作用,而Microsoft在软件开发人员,应用职位上做出了显著贡献。同样,IBM在计算机程序员,应用职位上产生了显着影响。
该图表强调了前十大雇主在H1B签证申请过程以及特定职位上的重大影响。
薪资范围在何种程度上影响H1B签证申请的批准或拒绝?


在进行数据分析后,我们发现薪资范围与申请状态之间没有明显的相关性。这个观察结果对于前十大被接受和被拒绝的职位都是适用的,他们的薪资范围相同。
为了进一步了解申请状态和薪资范围之间的关系,我们将薪资范围分成四个分位数:低、平均、高于平均和高薪水层级。然后,我们分析了每个类别的数据。研究结果表明,大多数被批准的H1B签证申请落在(Q1)和平均(Q2)薪资范围类别中。

低(Q1)和平均(Q2)薪资范围类别包含了大多数被批准的H1B签证申请。然而,薪资范围和申请状态之间没有明显的趋势。除了薪资之外,其他因素也对H1B签证申请的结果产生了重要影响。
那么,工作年限对H1B签证申请的决定有影响吗?


在分析数据时,我们发现就业期与签证决策之间没有实质性的相关性。令人惊讶的是,无论是被批准的前几个工作职位还是被拒绝的前几个职位,都展示了平均就业期为33个月。就业期的长短似乎并不是决定签证决策过程的关键因素。
我们根据就业期的平均值将申请人分为两组:低于33个月和高于33个月。

尽管进行了彻底的分析,我们无法确定就业期与H1B签证申请结果之间的趋势。缺乏可辨认的模式表明,就业期的长短可能并没有起到关键作用。
H1B签证工作者的地理分布中是否存在任何趋势或模式?

塔达!最终,这些数据在它的无穷智慧中给了我们一个虚拟的高五,最终确认了我们的正确性。
显然,美国特定州展示了更高的H1B签证申请雇主的集中度。值得注意的是,得克萨斯州、加利福尼亚州和新泽西州是最多雇主的前三个州,共计约684,118个申请。这一观察结果表明,这些州可能面临对熟练工人的高需求,吸引了更多雇主寻求H1B签证。
分析揭示了美国各地存在着大量的H1B雇主热点,这些地区表明了对熟练专业人才的高需求。
结论
总之,本博客深入探讨了来自OFLC的H1B签证数据的意义,全面探索了它在吸引熟练外籍工人来美国方面的作用。本文专注于各种数据预处理技术,包括数据清理、特征工程和转换,以确保准确分析。通过对H1B签证批准和拒绝率的分析,本博客揭示了影响这些率的重要因素,通过数据可视化呈现了宝贵的见解。
关键点
- 职位和职称是决定H1B签证成功的关键因素。在高需求领域如编程和工程方面发展技术技能可以增加获得H1B签证工作的机会。
- 加利福尼亚州、得克萨斯州和新泽西州是H1B签证申请的前三个州,由于跨越各种行业的领先公司的存在,这些州提供了丰富的机会。
- 注意数据集中具有影响力的雇主,如Infosys和Tata Consultancy Services,因为与这些行业巨头的努力相一致可以显着提升H1B签证之旅的成功率。
通过掌握正确的技能,采取有针对性的州和雇主的方法,并拥抱前景的可能性,您可以自信地踏上H1B签证之旅,并在珍视您的才能的世界中茁壮成长。
常见问题解答
本文中显示的媒体不属于Analytics Vidhya所有,仅由作者自行决定使用。