文章目录

  • 一、数据准备
  • 二、数据清洗
  • 1、缺失值处理
  • 2、异常值
  • 三、EDA
  • 1、发表文章数量最多的作者
  • 2、发表时间统计
  • 3、发表单位统计
  • 4、文献来源统计
  • 5、关键词统计
  • 四、共现网络
  • 五、K-means聚类
  • 六、数据降维,可视化结果
  • 七、数据集+源码获取


一、数据准备

这次主要是通过知网获取的学者信息,进行一个学者画像的分析。

一共是从知网下载了三份数据。如下图所示。

python 画像识别 python画像分析_聚类


每份数据的格式都是一样的。包含'SrcDatabase-来源库', 'Title-题名', 'Author-作者', 'Organ-单位', 'Source-文献来源', 'Keyword-关键词', 'Summary-摘要', 'PubTime-发表时间'八个字段。

因此我们可以将这三份数据合并到一个DataFrame中,再进行后续的数据清洗。代码如下。

import pandas as pd
import numpy as np
import os
import matplotlib.pyplot as plt
plt.style.use('seaborn')

base='./datasets/'
datasets=os.listdir(base)
print(datasets)
dfs=[]
for dataset in datasets:
    df=pd.read_excel(os.path.join(base,dataset),encoding='gbk')
    dfs.append(df)
df=pd.concat(dfs)
df.head()

二、数据清洗

1、缺失值处理

观察上述合并后的数据,可以看到第一列数据是不需要的。
其次,部分列的数据存在缺失值,对于存在缺失值的元素,这里直接删除对应行即可。

2、异常值

这里的异常值主要是部列中的值为标题名称。这里做个筛选,同样删除这些数据即可。

python 画像识别 python画像分析_数据分析_02

三、EDA

数据清洗完毕后接着进行数据探索。可以看到数据集中的各列数据均有挖掘价值。将相关内容可视化化出来。

1、发表文章数量最多的作者

从数据列可以发现,有的文章为多名作者合作完成,因此需要做一个简单的拆分

keywords={}
exponet=[]#每篇文章各个关键词出现次数之和,排序依据
for keys in df['Author-作者']:
    key_list=keys.split(';')
    for key in key_list:
        if key=='':
            continue
        if key in keywords:
            keywords[key]+=1
        else:
            keywords[key]=1

keywords=dict(sorted(keywords.items(),key=lambda x:x[1],reverse=True)[:10])
plt.title('发表文章最多作者Top10')
plt.bar(keywords.keys(),keywords.values())
plt.xticks(rotation=30)
#排序DataFrame
for keys in df['Author-作者']:
    score=0
    for key in keys.split(';'):
        try:
            score+=keywords[key]
        except:
            pass
    exponet.append(score)
df['数量']=exponet
df=df.sort_values(by='数量',ascending=False)
print("根据作着排序结果如下:")
df.head()

python 画像识别 python画像分析_python_03


python 画像识别 python画像分析_机器学习_04

2、发表时间统计

这里我们统计每年总共发表的文章数量

dates=pd.to_datetime(df['PubTime-发表时间'])
year_num=dates.map(lambda x:x.year).value_counts()
year_num.index=year_num.index.sort_values(ascending=False)
year_num.plot()
plt.xlabel('年份')
plt.ylabel('文章累计数')

python 画像识别 python画像分析_python 画像识别_05

3、发表单位统计

接着统计各个单位发表数量的Top10

organ=df['Organ-单位'].value_counts()
organ[:10].plot(kind='bar',title='单位发表数量top10')
df['数量']=[organ[i] for i in df['Organ-单位'] ]
df=df.sort_values(by='数量',ascending=False)
print("根据单位排序结果如下:")
df.head()

python 画像识别 python画像分析_python_06

4、文献来源统计

Source=df['Source-文献来源'].value_counts()
Source[:10].plot(kind='bar',title='文献来源数量top10')
df['数量']=[Source[i] for i in df['Source-文献来源'] ]
df=df.sort_values(by='数量',ascending=False)
print("根据单位排序结果如下:")
df.head()

python 画像识别 python画像分析_python_07

5、关键词统计

关键词统计的方法与1中的作者发表文章数量的统计方法类似。这里我们统计前15个关键词

keywords={}
exponet=[]#每篇文章各个关键词出现次数之和,排序依据
for keys in df['Keyword-关键词']:
    key_list=keys.split(';')
    for key in key_list:
        if key=='':
            continue
        if key in keywords:
            keywords[key]+=1
        else:
            keywords[key]=1
keywords=dict(sorted(keywords.items(),key=lambda x:x[1],reverse=True)[:10])
plt.title('关键词Top10')
plt.bar(keywords.keys(),keywords.values())
plt.xticks(rotation=30)
#排序DataFrame
for keys in df['Keyword-关键词']:
    score=0
    for key in keys.split(';'):
        try:
            score+=keywords[key]
        except:
            pass
    exponet.append(score)
df['数量']=exponet
df=df.sort_values(by='数量',ascending=False)
print("根据关键词排序结果如下:")
df.head()

python 画像识别 python画像分析_python_08

四、共现网络

构建作者与作者之间的合作网络。那么这个思路主要如下。

首先是将所有作者提取出来,这个在之前数据探索的过程中已经实现。将作者名作为行与列构建一个新的矩阵。

authors=[]
ketwords={}
for keys in df['Author-作者']:
    key_list=keys.split(';')
    for key in key_list:
        if key=='':
            continue
        if key in keywords:
            keywords[key]+=1
        else:
            keywords[key]=1
        if key not in authors:
            authors.append(key)
l=len(authors)
arr=np.zeros((l,l))
co_author_arr=pd.DataFrame(arr,index=authors,columns=authors)
co_author_arr.head()

python 画像识别 python画像分析_机器学习_09


对于上述的Dataframe我们将他当作一个二维数组,那么:

当作者i与作者j在同一条记录出现时co_author_arr[i][j]+=1,然后将同一个关系合并co_author_arr[i][j]+=co_author_arr[j][i]。最后形成我们最终的结果。

如果用Python的基本循环语法去遍历这个数据会是一个很漫长的过程。所以我们通过Pandas内置的迭代对象进行遍历。

leg=len(authors)
count=0
for index,row in co_author_arr.iterrows():
    for name in row.index:
        if name!=index:
            row[name]+=1
            row[name]+=co_author_arr.loc[name,index]
    count+=1
    print('\r{}%'.format(count/leg*100),end='')
co_author_arr.head()

最后结果如下

python 画像识别 python画像分析_python 画像识别_10

五、K-means聚类

由于每篇文章都包含多个不同的主题,我们为了能更合理地归类这些文章,可以将这些文章进行聚类。
将所有唯一的关键词作为行,所有文章标题作为列构建一个新的DataFrame,所有元素初始化为0。
如果当前文章包括某个关键词,则将该元素的值置为1。

  • 建立聚类表格
keywords=[]
for keys in df['Keyword-关键词']:
    key_list=keys.split(';')
    for key in key_list:
        if key=='':
            continue
        if key not in keywords:
            keywords.append(key)
            
title=df['Title-题名']
arr=np.zeros((len(title),len(keywords)))
tit_key=pd.DataFrame(arr,index=title,columns=keywords)
tit_key.head()

python 画像识别 python画像分析_python 画像识别_11

  • 计算结果
df=df.set_index('Title-题名')
for index,row in tit_key.iterrows():
    kw=df.loc[index,'Keyword-关键词']
    try:
        keys=kw.split(';')
        for k in keys:
            if k in keywords:
                row[k]=1
    except:
        pass

tit_key.head()

python 画像识别 python画像分析_聚类_12

  • 为了选取最优的簇数,我们通过不同的评估系数(CH指标、轮廓系数指标、SSE簇内误方差指标)进行评估,根据可视化的结果选取最佳的K值
from sklearn.cluster import KMeans   
from sklearn.metrics import silhouette_score
from sklearn.metrics import calinski_harabaz_score


#三种评价指标
silhouettteScore = []
CH_score=[]
SSE=[]
for i in range(2,30):
    ##构建并训练模型
    print('\r正在构建模型:{}%'.format((i-1)/28*100),end='')
    kmeans = KMeans(n_clusters = i,random_state=123).fit(tit_key)
    score = silhouette_score(tit_key,kmeans.labels_)
    ch=calinski_harabaz_score(tit_key,kmeans.labels_)
    
    silhouettteScore.append(score)
    CH_score.append(ch)
    SSE.append(kmeans.inertia_)
    
def plot_one(scores,title):
    plt.figure(figsize=(10,6))
    plt.plot(range(2,30),scores,linewidth=1.5, linestyle="-")
    plt.title(title)
plot_one(silhouettteScore,'轮廓系数')
plot_one(CH_score,'CH')
plot_one(SSE,'SSE')

python 画像识别 python画像分析_python 画像识别_13


通过上图,我们选择K=16作为聚类的簇数

六、数据降维,可视化结果

from sklearn.manifold import TSNE


kmeans=KMeans(n_clusters=16,random_state=123).fit(tit_key) #构建并训练模型

tsne = TSNE(n_components=2,init='random',random_state=177).fit(tit_key)
result=pd.DataFrame(tsne.embedding_)       ##将原始数据转换为DataFrame
result['labels'] = kmeans.labels_          ##将聚类结果存储进df数据表
 

# ## 绘制图形
plt.figure(figsize=(12,10))
for i in range(17):
    temp=result[result['labels']==i]
    plt.scatter(temp[0],temp[1])

python 画像识别 python画像分析_数据分析_14