Python招聘岗位推荐系统(协同过滤算法)

1 前言:

Hello everyone,今天和大家分享一个pythonWeb项目 招聘推荐系统,下面介绍一下项目的大概内内容如下:

📖 项目实现功能:

1️⃣首页模块会展示全部的岗位信息以及比较热门的几个岗位的图片,作为轮播图,同时呢,在右侧有一个岗位分类可以根据分类来查看所有该分类的岗位,并且在每一个页面都能够有查看岗位详情在岗位详情页面会展示这个岗位的所有的信息,比如说薪资学历性质分类以及技能要求同时能用户可以对该岗位进行评分,收藏以及投递的操作! 2️⃣热门岗位模块呢,是按照被多少用户的收藏量进行一个排行! 3️⃣职位推荐模块栏用到的就是协同过滤算法来结合我们的一些指标,比如说用户的收藏,评分和投递简历的综合来进行一个算法推荐! 4️⃣在我的收藏模块,我的投递模块以及我的评分模块分别发的就是我们对岗位的收藏信息,投递信息以及评分信息! 5️⃣个人信息模块可以修改用户的基本信息, 6️⃣在岗位分析模块,是对我们这个岗位数据库的一些字段做一个综合的可视化分析! 7️⃣后台管理呢,我们用到了simpleui的一些管理界面可以对我们数据库的用户信息岗位信息以及收藏信息评分信息分类信息,评论信息等等做一个综合处理!

📖涉及技术:Python,Django,mysql,协同过滤算法,前端,后端!

2 数据库设计:

所有项目的数据库都是依据你项目所有实现的内容而定。

因为我们本次的项目实现了对招聘岗位的推荐,推荐指标是收藏和评分,自然便是需要收藏表和评分表,又因为用户可以对岗位评论,自然也需要创建对应的评论表,用户表和岗位表。详细代码如下:

from django.db import models


# 用户信息
class UserInfoModel(models.Model):
    username = models.CharField(max_length=100, verbose_name='用户名')
    password = models.CharField(max_length=100, verbose_name='密码')
    phone = models.CharField(max_length=100, verbose_name='手机号')
    edu_level = models.CharField(max_length=100, default='', verbose_name='学历')
    major = models.CharField(max_length=100, default='', verbose_name='专业')
    age = models.IntegerField(default=0, verbose_name='年龄')
    content = models.TextField(default='', verbose_name='介绍')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='加入时间')

    class Meta:
        db_table = 'db_user_info'
        verbose_name = '用户信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username


# 岗位类别
class CategoryModel(models.Model):
    name = models.CharField(max_length=100, verbose_name='名称')

    class Meta:
        db_table = 'db_category'
        verbose_name = '类别信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 岗位信息
class JobModel(models.Model):
    name = models.CharField(max_length=100, verbose_name='名称')
    money = models.CharField(max_length=100, verbose_name='薪资范围')
    edu_level = models.CharField(max_length=100, verbose_name='学历')
    image = models.ImageField(upload_to='', default='default_job_img.png', max_length=300, verbose_name='图片')
    content = models.TextField(verbose_name='介绍')
    number = models.IntegerField(default=1, verbose_name='岗位数量')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    view_number = models.IntegerField(default=0, verbose_name='浏览量')
    category = models.ForeignKey('CategoryModel', on_delete=models.CASCADE, verbose_name='所属分类')

    class Meta:
        db_table = 'db_job'
        verbose_name = '职位信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


choices_list = [
    (0, '简历未通过'),
    (1, '简历通过'),
    (2, '面试通过'),
    (3, '面试未通过'),
    (4, '已发送录用通知'),
    (5, '已发送简历'),
]


# 投递简历信息
class OrderModel(models.Model):
    job = models.ForeignKey('JobModel', on_delete=models.CASCADE, verbose_name='所属职位')
    user = models.ForeignKey('UserInfoModel', on_delete=models.CASCADE, verbose_name='所属用户')
    state = models.IntegerField(choices=choices_list, default=5, verbose_name='状态')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='投递时间')

    class Meta:
        db_table = 'db_order'
        verbose_name = '投递信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.user.username


# 收藏信息
class CollectModel(models.Model):
    job = models.ForeignKey('JobModel', on_delete=models.CASCADE, verbose_name='所属职位')
    user = models.ForeignKey('UserInfoModel', on_delete=models.CASCADE, verbose_name='所属用户')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='收藏时间')

    class Meta:
        db_table = 'db_collect'
        verbose_name = '收藏信息'
        verbose_name_plural = verbose_name


# 热门岗位
class HotModel(models.Model):
    job = models.ForeignKey('JobModel', on_delete=models.CASCADE, verbose_name='热门职位')

    class Meta:
        db_table = 'db_hot'
        verbose_name = '热门职位'
        verbose_name_plural = verbose_name


# 评论信息
class CommentModel(models.Model):
    user = models.ForeignKey('UserInfoModel', on_delete=models.CASCADE, verbose_name='所属用户')
    job = models.ForeignKey('JobModel', on_delete=models.CASCADE, verbose_name='所属职位')
    content = models.TextField(verbose_name='评论内容')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        db_table = 'db_comment'
        verbose_name = '评论信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.user.username


# 评分信息
class MarkModel(models.Model):
    user = models.ForeignKey('UserInfoModel', on_delete=models.CASCADE, verbose_name='所属用户')
    item = models.ForeignKey('JobModel', on_delete=models.CASCADE, verbose_name='所属职位')
    score = models.IntegerField(default=5, verbose_name='评分')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        db_table = 'db_mark'
        verbose_name = '评分信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.user.username

3:项目业务代码:

3.1 登录注册(代码)

代码流程比较简单,就是在form表单使用post提交获取输入框的内容,然后储存在数据库用户表即可,登录就是获取后使用filter检索函数,比较输入框的账号和密码是否在数据库的用户表存在即可。

3.2 首页 :

首页展示的是一个前端的轮播图,右侧有一个分类,下侧数一些岗位的展示:

点击每一个岗位可以进入该岗位详情,详情页面展示了每个岗位的详细内容如薪资,学历和技能需求,同时用户也可以对岗位进行收藏,评分和评论。

 

评分和评分核心代码如下:

# 添加评论
def add_comment(request):
    user_id = request.session.get('user_id')
    if not user_id:
        return JsonResponse({'code': 400, 'message': '请先登录'})
    content = request.POST.get('content')
    job_id = request.POST.get('job_id')
    if not content:
        return JsonResponse({'code': 400, 'message': '内容不能为空'})

    CommentModel.objects.create(
        user_id=user_id,
        content=content,
        job_id=job_id
    )
    return JsonResponse({'code': 200})


# 用户对岗位进行评分
def input_score(request):
    user_id = request.session.get('user_id')
    if not user_id:
        return JsonResponse({'code': 400, 'message': '请先登录'})
    score = int(request.POST.get('score'))
    item_id = request.POST.get('job_id')
    mark = MarkModel.objects.filter(item_id=item_id, user_id=user_id).first()
    if mark:
        mark.score = score
        mark.save()
    else:
        MarkModel.objects.create(
            item_id=item_id,
            score=score,
            user_id=user_id
        )
    return JsonResponse({'code': 200})

3.3 热门岗位:

热门岗位是按照岗位被用户的收藏次数来评定的。

 

该业务代码如下:

def hot_jobs(request):
    # 获取所有岗位及其被收藏的次数
    jobs = JobModel.objects.annotate(collect_count=Count('collectmodel')).order_by('-collect_count')

    # 分页处理
    paginator = Paginator(jobs, 10)  # 每页显示10个岗位
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)

    context = {
        'page_obj': page_obj,
        'title': '热门岗位'
    }
    return render(request, 'hot_jobs.html', context)

3.4  职位推荐:

职位推荐的原理是根据用户来推荐的,比拟各个用户的评分和收藏指标来结合机器学习的协同过滤算法来个性化推荐岗位的。

核心处理代码如下:

# 计算两用户的余弦相似度
def calculate_cosine_similarity(user_ratings1, user_ratings2):
    # 将用户1的职位评分存入字典,键为职位ID,值为评分 1:5 2:3
    item_ratings1 = {rating.item_id: rating.score for rating in user_ratings1}
    print('item_ratings1:', item_ratings1)
    # 将用户2的职位评分存入字典,键为职位ID,值为评分 1:4
    item_ratings2 = {rating.item_id: rating.score for rating in user_ratings2}
    print('item_ratings2:', item_ratings2)
    # 找出两个用户共同评价过的职位 1
    common_items = set(item_ratings1.keys()) & set(item_ratings2.keys())
    print('common_items:', common_items)
    if len(common_items) == 0:
        return 0.0  # 无共同评价的职位,相似度为0

    # 提取共同评价职位的评分,存入NumPy数组
    user1_scores = np.array([item_ratings1[item_id] for item_id in common_items]) # 5
    user2_scores = np.array([item_ratings2[item_id] for item_id in common_items])  # 4
    print('user1_scores:', user1_scores)
    print('user2_scores:', user2_scores)
    # 计算余弦相似度
    cosine_similarity = np.dot(user1_scores, user2_scores) / (
            np.linalg.norm(user1_scores) * np.linalg.norm(user2_scores))
    print('cosine_similarity:', cosine_similarity)
    return cosine_similarity


# 基于用户协同过滤推荐
def user_based_recommendation(request, user_id):
    try:
        # 获取目标用户对象
        target_user = UserInfoModel.objects.get(id=user_id)
    except UserInfoModel.DoesNotExist:
        return JsonResponse({'code': 400, 'message': '该用户不存在'})

    # 获取目标用户的职位评分记录
    target_user_ratings = MarkModel.objects.filter(user=target_user)

    # 用于存储推荐职位的字典
    recommended_items = {}

    # 遍历除目标用户外的所有其他用户 test1 bhml
    for other_user in UserInfoModel.objects.exclude(pk=user_id):
        # 获取其他用户的职位评分记录
        other_user_ratings = MarkModel.objects.filter(user=other_user)

        # 计算目标用户与其他用户的相似度
        similarity = calculate_cosine_similarity(target_user_ratings, other_user_ratings)

        if similarity > 0:
            # 遍历其他用户评价的职位
            for item_rating in other_user_ratings:
                # 仅考虑目标用户未评价过的职位
                if item_rating.item.id not in target_user_ratings.values_list('item', flat=True):
                    if item_rating.item.id in recommended_items:
                        # 累积相似度加权的评分和相似度
                        recommended_items[item_rating.item.id]['score'] += similarity * item_rating.score
                        recommended_items[item_rating.item.id]['similarity'] += similarity
                    else:
                        # 创建推荐职位的记录
                        recommended_items[item_rating.item.id] = {'score': similarity * item_rating.score,
                                                                  'similarity': similarity}

    # 将推荐职位按照加权评分排序
    sorted_recommended_items = sorted(recommended_items.items(), key=lambda x: x[1]['score'], reverse=True)

    # 获取排名靠前的推荐职位的ID
    top_recommended_items = [item_id for item_id, _ in sorted_recommended_items[:5]]

    # 构建响应数据
    response_data = []
    for item_id in top_recommended_items:
        item = JobModel.objects.get(pk=item_id)
        similarity = recommended_items[item_id]['similarity']
        response_data.append({
            'job': item,
            'name': item.name,
            'id': item.id,
            'image': item.image,
            'similarity': similarity,
        })
    context = {
        'response_data': response_data
    }
    return render(request, 'job_recommend.html', context=context)

 3.5 职位收藏:

用户进入到职位详情页面时可以对用户进行收藏,收藏后的职位会在我的收藏模块页面进行显示

相关代码如下:

# 我的收藏
def my_collect(request):
    user_id = request.session.get('user_id')
    collects = CollectModel.objects.filter(user_id=user_id)
    return render(request, 'my_collect.html', {'collects': collects})


# 取消收藏
def delete_collect(request):
    collect_id = request.POST.get('collect_id')
    collect = CollectModel.objects.get(id=collect_id)
    collect.delete()
    return JsonResponse({'code': 200})

 3.6 职位投递:

用户进入到职位详情页面时可以对用户进行投递简历,投递后的职位会在我的投递模块页面进行显示

相关代码:

# 投递简历
def add_order(request):
    user_id = request.session.get('user_id')
    if not user_id:
        return JsonResponse({'code': 400, 'message': '请先登录'})
    job_id = request.POST.get('job_id')
    flag = OrderModel.objects.filter(user_id=user_id, job_id=job_id).first()
    if flag:
        return JsonResponse({'code': 400, 'message': '您已投递该岗位,请勿重复投递!'})
    OrderModel.objects.create(
        user_id=user_id,
        job_id=job_id
    )
    return JsonResponse({'code': 200})

 3.7 职位评分:

用户进入到职位详情页面时可以对让用户进行对岗位评分,被用户评分后的职位会在我的评分模块页面进行显示:

相关代码如下:

# 投递简历
def add_order(request):
    user_id = request.session.get('user_id')
    if not user_id:
        return JsonResponse({'code': 400, 'message': '请先登录'})
    job_id = request.POST.get('job_id')
    flag = OrderModel.objects.filter(user_id=user_id, job_id=job_id).first()
    if flag:
        return JsonResponse({'code': 400, 'message': '您已投递该岗位,请勿重复投递!'})
    OrderModel.objects.create(
        user_id=user_id,
        job_id=job_id
    )
    return JsonResponse({'code': 200})

 3.7 个人信息:

# 个人信息
def my_info(request):
    user_id = request.session.get('user_id')
    if request.method == 'GET':
        # 个人信息界面
        info = UserInfoModel.objects.get(id=user_id)
        return render(request, 'my_info.html', {'info': info})
    else:
        # 更新个人信息
        username = request.POST.get('username')
        password = request.POST.get('password')
        phone = request.POST.get('phone') or ''
        edu_level = request.POST.get('edu_level') or ''
        major = request.POST.get('major') or ''
        age = request.POST.get('age') or ''
        content = request.POST.get('content') or ''

        UserInfoModel.objects.filter(
            id=user_id
        ).update(
            username=username,
            password=password,
            phone=phone,
            edu_level=edu_level,
            major=major,
            age=age,
            content=content,
        )
        return JsonResponse({'code': 200})

 3.8 浏览量统计:


# 浏览量统计
def view_count(request):
    if request.method == 'GET':
        return render(request, 'view_count.html')
    else:
        jobs = JobModel.objects.all().order_by('-view_number')[:10]
        name_list = []
        count_list = []
        for job in jobs:
            name_list.append(job.name)
            count_list.append(job.view_number)
        return JsonResponse({'code': 200, 'name_list': name_list, 'count_list': count_list})

4 后台管理:

Django框架自带admin后台管理,只需要在admin.py里面进行声明即可,如果需要优化后台的样式界面可以使用simpleui模块进行优化。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小熊Coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值