关于程序员能做什么副业,我爬了相关文章用机器学习算法分析 | 附源码

520 阅读6分钟

​最近想了解下程序员可以做什么副业,我抓取了各大网站关于程序员搞副业的文章,但抓取的文章较多,为了将相似的文章归拢到一起,我用聚类算法将文章划分到不同的主题。下面我就来介绍一下分析的结论以及过程。文末回复关键字即可获取本次分析源码。
本次分析的文章是从博客园、CSDN、知乎、今日头条和微信上抓取,共140篇,聚类得到的主题如下:

  • 接私活:主要是在码市、程序员客栈等网站接项目做外包,对于接私活的评价大家褒贬不一,有的人决定接私活能够锻炼技术,但有的人觉得是重复劳动,可积累性差。我自己也接过私活,不建议程序员接私活,因为它相当于是工作时间的延伸,并没有给你带来其他的可能性

  • 写作:反对接私活的一部分人就提出来走写作这条路,因为写作一来可以有深度的思考,二来也可以沉淀技术,最后通过输出的内容变现

  • 出书和录视频:看书和看视频也是我们学习技术的主要途径,录视频是对技术能力和表达能力有更高的要求,相对而言写书会容易一些。对于程序员来说如果经常写原创博客,会有出版社的人员主动联系你。如果自己有时间、有能力的话可以考虑写本书,既可以赚钱还能提高个人影响力。我去年就写了一本小册,这个过程中确实需要付出很多时间和精力

  • 小项目:这个相对于外包来说会好一些,原文作者举了个例子,通过网上爬取公开的个人信息和联系方式,包装成软件出售,获得了不菲的收入

  • 公众号:通过公众号积累流量,接广告赚钱

  • 投资学习:通过聚类分析发现有些文章的观点画风比较清奇,认为程序员最大的副业是投资自己。这也是一条很好的路子,不断地拓宽自己的知识广度、打穿知识深度,能够在主营业务上创造出独一无二的成果也是一种副业

当然还有一些的关于讨论程序员应不应该搞副业的主题也能聚在一起,这里就不举例了,有兴趣朋友可以看详细的分析数据。

下面来介绍下分析过程

数据抓取:需求比较明确,第一步找到文章搜索的入口,第二步找到文章详情的入口。实现方案有两种,第一种是请求接口;第二种是解析网页HTML代码。在本次分析中这两种方案都有涉及,其中微信公众号的数据抓取比较困难,我用的是开源的项目wechatsogou,这个项目直接用也是有各种问题,但我都解决了,需要注意的问题在源代码中都有说明。由于这次抓取的网站比较多,抓取这一步花费了60%的时间。数据清洗:主要目的是为了保证我们后续分析的数据是干净的,且没有噪音。这里我主要做了两步,第一步限制文章的title包含“程序员”和“副业”,保证文章内容是可靠的;第二步通过BeautifulSoup取出HTML标签,保证正文干净

# 过滤文章
def article_filter(article):
    title = article['title']
    if '副业' in title and '程序员' in title:
        return True
return False

# 清洗正文,去掉html标签
def content_clean(content):
    content_bs = BeautifulSoup(content)
    content_text = content_bs.get_text()
    content_text = re.sub('\n|\xa0', '', content_text)
    return content_text

特征提取:因为我们是作文本分析,所以我们要将文本转化成计算机能识别的数字特征。转化的方式有两种,第一种词袋空间VSM(vector space model),简单来说它将一篇文章存储为一个数组,数组第n位的元素值代表该文章中第i个词出现的频次。然后通过TF-IDF计算第i个词在这篇文章的权重。如果某个词是文章的关键词,那么它的权重比其他词就大。所以如果两篇表达的是同一个主题,那么它俩的词分布以及词的权重会很像,做聚类的时候自然就能聚到一起;另一种方式是将文档转化成向量,即:Doc2Vector。这里主要介绍第一种方式,关于第二种源代码也有涉及,有兴趣的朋友可以自行看源码。

# 计算tf-idf 作为每个词的权重
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
# 统计词频
vectorizer = CountVectorizer(token_pattern=r"(?u)\b\w+\b")
# 计算tf-idf
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
# 权重矩阵, 二位数组,每行是一篇文章,每列是一个词
weight_matrix = tfidf.toarray()
# 特征词,数据,每个元素是一个词,也是weight_matrix第i列的词
word = vectorizer.get_feature_names()

聚类分析:关于聚类的算法有很多,比如:K-Means、Birch、LDA和DBSCAN。本次分析中我用到了K-Means和Birch,这里主要介绍K-Means的代码。K-Means的思想比较简单,就是将两个距离较近的文章聚成一类。前面我们已经将文章转成向量了,所以可以计算文章之间的距离。

# Kmeans 聚类
from sklearn.cluster import KMeans

# 聚成 15 类
kmeans = KMeans(n_clusters=15)
kmeans.fit(weight_matrix)

# 聚类结果,存放第i篇文章属于第几类
kmeans.labels_

K-Means的用法也比较简单,只需指定要最终聚出的类数量(n_clusters)即可。

效果评估:主要用来评估聚在一起的文章是否真的是同一类,或者同一类的文章是否聚在了一起。因为之前我们计算了TF-IDF,我们能获取每篇文章的关键词,所以我把每篇文章所在的类别、标题、以及关键词输出到文件,来进行评估

# 提取每篇文章最关键的5个词
# keywords
def get_key_words(weight, words):
    topk_weight = sorted(weight, reverse=True)[:5]
    min_weight = topk_weight[-1]
    max_weight = topk_weight[0]
    
    key_words = []
    for index, x in enumerate(weight):
        if x >= min_weight:
            key_words.append(words[index])
    return " ".join(key_words)

f = open("cluster_res.txt", "w", encoding='utf-8')
for index, label in enumerate(kmeans.labels_):
        kws = get_key_words(weight_matrix[index], word)
        raw = '%d\t%d\t%s\t%s\t%s\t%s\n' % (index,label, kws, attrs[index][0], attrs[index][1], attrs[index][2])
        f.write(raw)

下面贴几个case,聚类的效果还可以

类别3是接私活相关的文章,类别6是投资学习的文章,类别7是出书和视频的文章。本次分析过程就介绍到这里,其实这次分析具体到每个步骤可能没做那么细,比如:数据清洗、模型优化等,但整个流程还算比较完整。如果各位有兴趣可以自行深入研究。

希望这次分析能对你有用,欢迎公众号「渡码」。公众号回复关键字 副业 即可获得完整源码。