天天看點

基于python分析微信好友的性别分布,區域分布,詞雲分析,頭像拼接

 你知道你的微信好友男生多還是女生多嗎,(單身?應該能立馬答出來吧)

   你知道你的微信好友都是什麼性格嗎,話說你的工資大體是你最好的五個朋友的平均數(可以視情況去除一個最高值和最低值,萬一人家拆遷了),那性格是不是大多也可以這麼推理呢

   你知道你的好友簽名正能量多還是負能量多嗎,

   你知道你的好友全國分布嗎

不,你不知道

知道了還怎麼看我下面的文章

通過安裝第三方工具包itcaht,我們可以通過二維碼登陸微信,然後獲得我們的好友資訊,如下圖所示

itchat.auto_login(hotReload=False)
friends = itchat.get_friends(update=True)      

然後擷取你所有friends的資料,我們可以看到資料是以字典形式呈現的,第一個元素是目前使用者。是以,在下面的資料分析流程中,我們始終取friends[1:]作為原始輸入資料,集合中的每一個元素都是一個字典結構,以我本人為例,可以注意到這裡有Sex、City、Province、HeadImgUrl、Signature這四個字段,我們下面的分析就從這四個字段入手:

1.微信好友性别分布

首先分析好友性别,可以從friends中的Sex中提取出來,然後統計出來男性,女性和未知性别分别有多少,由于小編的好友都是程式設計愛好者,是以男性占了絕大部分,當然熱愛程式設計的女性好友也是有一定數量滴,可以大緻了解在網際網路行業男女的比例了,男女比例5:1,按照法定夫妻1:1配比,那麼還有剩下的4分男生可以。。。。。當我沒說

基于python分析微信好友的性别分布,區域分布,詞雲分析,頭像拼接

一行資料好友性别分布

def analyseSex(firends):
    sexs = list(map(lambda x: x['Sex'], friends[1:]))
    counts = Counter(sexs).items()
    counts = sorted(counts, key=lambda x: x[0], reverse=False)
    counts = list(map(lambda x: x[1], counts))
    labels = ['女性', '男性', '未知']
    colors = ['red', 'yellowgreen', 'lightskyblue']
    plt.figure(figsize=(8, 5), dpi=80)
    plt.axes(aspect=1)
    plt.pie(counts,
            labels=labels,
            colors=colors,
            labeldistance=1.1,
            autopct='%3.1f%%',
            shadow=False,
            startangle=90,
            pctdistance=0.6
            )
    plt.legend(loc='upper right', )
    plt.title(u'%s的微信好友性别組成' % friends[0]['NickName'])
    plt.show()      

2.微信好友頭像分析

分析好友頭像,從兩個方面來分析,第一,在這些好友頭像中,使用人臉頭像的好友比重有多大;第二,從這些好友頭像中,可以提取出哪些有價值的關鍵字。這裡需要根據HeadImgUrl字段下載下傳頭像到本地,然後通過騰訊優圖提供的人臉識别相關的API接口,檢測頭像圖檔中是否存在人臉以及提取圖檔中的标簽。其中,前者是分類彙總,我們使用餅圖來呈現結果;後者是對文本進行分析,我們使用詞雲來呈現結果。

通過者篇文章從微信頭像看出你的性格

   沒太刻意選擇過的生活照作頭像

   這類人對自己的接納度比較高,對外貌也比較有自信,不一定長得好看,但是能接納自己的本來面目。内心沒藏太多秘密,也沒做過什麼見不得人的事兒,在網絡世界和現實世界中差别不大。

   用風景美圖作頭像

   這種人通常為人比較成熟,人緣很好,很注重人際關系的和諧。

僅供參考,從我的分布圖

微信頭像分布圖

不過可以注意到,在所有微信好友中,約有接近1/4的微信好友使用了人臉頭像, 而有接近3/4的微信好友沒有人臉頭像,這說明在所有微信好友中對”顔值 “有自信的人,僅僅占到好友總數的25%,或者說75%的微信好友行事風格偏低調為主,不喜歡用人臉頭像做微信頭像。這是否說明”好看的皮囊”并非是千篇一律,長得好看的人實在是少數中的少數。是以,當女生的妝容越來越向着”韓式半永久粗平眉”、”瓜子臉”和”大紅唇”靠攏的時候,當男生的服飾越來越向着”大背頭”、”高領毛衣”和”長款大衣”靠攏的時候,我們能不能真正得個性一次。生命中有太多被世俗綁架着的事情,既要和别人不一樣 ,同時還要和大多數人一樣,這是人生在世的無可奈何。考慮到騰訊優圖并不能真正得識别”人臉”,我們這裡對好友頭像中的标簽再次進行提取,來幫助我們了解微信好友的頭像中有哪些 關鍵詞,其分析結果如圖所示:

微信頭像詞雲分布圖

你瞧!除了女孩,女孩,男孩,合影,合影還有天空,大海,卡通畫嘛

def analyseHeadImage(frineds):
    # Init Path
    basePath = os.path.abspath('.')
    baseFolder = basePath + '\\HeadImages\\'
    if(os.path.exists(baseFolder) == False):
        os.makedirs(baseFolder)
 
    # Analyse Images
    faceApi = FaceAPI()
    use_face = 0
    not_use_face = 0
    image_tags = ''
    for index in range(1,len(friends)):
        friend = friends[index]
        # Save HeadImages
        imgFile = baseFolder + '\\Image%s.jpg' % str(index)
        imgData = itchat.get_head_img(userName = friend['UserName'])
        if(os.path.exists(imgFile) == False):
            with open(imgFile,'wb') as file:
                file.write(imgData)
 
        # Detect Faces
        time.sleep(1)
        result = faceApi.detectFace(imgFile)
        if result == True:
            use_face += 1
        else:
            not_use_face += 1 
 
        # Extract Tags
        result = faceApi.extractTags(imgFile)
        image_tags += ','.join(list(map(lambda x:x['tag_name'],result)))
 
    labels = [u'使用人臉頭像',u'不使用人臉頭像']
    counts = [use_face,not_use_face]
    colors = ['red','yellowgreen','lightskyblue']
    plt.figure(figsize=(8,5), dpi=80)
    plt.axes(aspect=1)
    plt.pie(counts, #性别統計結果
            labels=labels, #性别展示标簽
            colors=colors, #餅圖區域配色
            labeldistance = 1.1, #标簽距離圓點距離
            autopct = '%3.1f%%', #餅圖區域文本格式
            shadow = False, #餅圖是否顯示陰影
            startangle = 90, #餅圖起始角度
            pctdistance = 0.6 #餅圖區域文本距離圓點距離
    )
    plt.legend(loc='upper right',)
    plt.title(u'%s的微信好友使用人臉頭像情況' % friends[0]['NickName'])
    plt.show()
 
    image_tags = image_tags.encode('iso8859-1').decode('utf-8')
    back_coloring = np.array(Image.open('face.jpg'))
    wordcloud = WordCloud(
        font_path='simfang.ttf',
        background_color="white",
        max_words=1200,
        mask=back_coloring,
        max_font_size=75,
        random_state=45,
        width=800,
        height=480,
        margin=15
    )
 
    wordcloud.generate(image_tags)
    plt.imshow(wordcloud)
    plt.axis("off")
    plt.show()      

3.微信好友簽名分析

分析好簽名,簽名是好友資訊中最為豐富的文本資訊,按照人類慣用的”貼标簽”的方法論,簽名可以分析出某一個人在某一段時間裡狀态,就像人開心了會笑、哀傷了會哭,哭和笑兩種标簽,分别表明了人開心和哀傷的狀态。這裡我們對簽名做兩種處理,第一種是使用用結巴分詞進行分詞後生成詞雲,目的是了解好友簽名中的關鍵字有哪些,哪一個關鍵字出現的頻率相對較高;第二種是使用SnowNLP分析好友簽名中的感情傾向,即好友簽名整體上是表現為正面的、負面的還是中立的,各自的比重是多少。這裡提取Signature字段即可

image

通過詞雲,我們可以發現:在微信好友的簽名資訊中,出現頻率相對較高的關鍵詞有:人生,生命,努力、前行,戰略,堅強,美麗。果然我的微信好友都是溫暖、正直的好青年啊! 其實,簽名這個設定,從某種程度上是在反映人的一種心态,人在年輕時不免”為賦新詞強說愁”,等到你真正到了這個精神境界,突然發現年輕時圖樣圖森破,或許這就是我們不願意讓别人了解過去的原因,因為伴随着人的成長,某一種瞬間的狀态簡直不忍直視,QQ空間陪伴了我們這代人的整個青春,令人印象深刻的”那年今日”功能,有時讓我們感到回憶的溫暖,有時讓我們感到歲月的蕭殺,”當時隻道是尋常”的物是人非,”回首向來蕭瑟處”的淡定從容,”今夕複何夕”的失落惆怅……都在這一行行簽名裡留下深深淺淺的印記。在知乎上有關于簽名的話題讨論,對此感興趣的朋友不妨找時間看看。:

通過柱狀圖,我們可以發現:在微信好友的簽名資訊中,正面積極的情感判斷約占到55.56%,中立的情感判斷約占到32.10%,負面消極的情感判斷約占到12.35%。這個結果和我們通過詞雲展示的結果基本吻合,這說明在微信好友的簽名資訊中,約有87.66%的簽名資訊,傳達出來都是一種積極向上的态度。朋友圈中基本上有兩類使用者,第一類使用者使用朋友圈記錄自己的生活,第二類使用者使用朋友圈輸出自己的觀點。顯然,對于第二類使用者,它并不介意别人了解它的過去,它更在乎它從始至終輸出的觀點是否一緻。是以,不管朋友圈裡别人在或曬美食、或曬旅遊、或秀恩愛、或曬寶寶、或煲雞湯等等,在我看來這都是一種生活方式,精神層次和物質層次比你高的人群,覺得你朋友圈裡的内容”無趣”,這是符合人類一貫的認知方式的,在大多數情況下,反而是那些和你層次差不多的人群,對不熟悉的人或者事物妄加判斷,如果你不喜歡我朋友圈裡的内容,請直接屏蔽我就好,因為這樣我們還可以做朋友;如果你因為喜歡A而在我這裡和我說B不好,這就真的是三觀不合啦。我相信沒有完全興趣比對的兩個人,即使是男女朋友或者情侶之間,總之人與人相處嘛,真誠和互相尊重是基本要求。

代碼附上:

def analyseSignature(friends):
    signatures = ''
    emotions = []
    pattern = re.compile("1f\d.+")
    for friend in friends:
        signature = friend['Signature']
        if(signature != None):
            signature = signature.strip().replace('span', '').replace('class', '').replace('emoji', '')
            signature = re.sub(r'1f(\d.+)','',signature)
            if(len(signature)>0):
                nlp = SnowNLP(signature)
                emotions.append(nlp.sentiments)
                signatures += ' '.join(jieba.analyse.extract_tags(signature,5))
    with open('signatures.txt','wt',encoding='utf-8') as file:
         file.write(signatures)
 
    # Sinature WordCloud
    back_coloring = np.array(Image.open('flower.jpg'))
    wordcloud = WordCloud(
        font_path='simfang.ttf',
        background_color="white",
        max_words=1200,
        mask=back_coloring,
        max_font_size=75,
        random_state=45,
        width=960,
        height=720,
        margin=15
    )
 
    wordcloud.generate(signatures)
    plt.imshow(wordcloud)
    plt.axis("off")
    plt.show()
    wordcloud.to_file('signatures.jpg')
 
    # Signature Emotional Judgment
    count_good = len(list(filter(lambda x:x>0.66,emotions)))
    count_normal = len(list(filter(lambda x:x>=0.33 and x<=0.66,emotions)))
    count_bad = len(list(filter(lambda x:x<0.33,emotions)))
    labels = [u'負面消極',u'中性',u'正面積極']
    values = (count_bad,count_normal,count_good)
    plt.rcParams['font.sans-serif'] = ['simHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.xlabel(u'情感判斷')
    plt.ylabel(u'頻數')
    plt.xticks(range(3),labels)
    plt.legend(loc='upper right',)
    plt.bar(range(3), values, color = 'rgb')
    plt.title(u'%s的微信好友簽名資訊情感分析' % friends[0]['NickName'])
    plt.show()      

4.微信好友分布

分析好友位置,主要通過提取Province和City這兩個字段。本來想用pyecharts來實作,但是由于最近政策原因不能導出地圖,參照網上的一些意見發現BDP線上制圖非常好用,0程式設計門檻,拖拽使用,一鍵下載下傳,是以首先将資料存儲在csv上傳到這個線上制圖網站。

微信好友全國分布圖

基于python分析微信好友的性别分布,區域分布,詞雲分析,頭像拼接

上圖是BDP中生成的微信好友地理分布圖,可以發現:我的微信好友主要集中在北上廣深啊哈哈,可以小見大中國的網際網路分布主要還是在這些一線沿海地區,找工作在這些區域也會更加便利

def analyseLocation(friends):
    headers = ['NickName','Province','City']
    with open('location.csv','w',encoding='utf-8',newline='',) as csvFile:
        writer = csv.DictWriter(csvFile, headers)
        writer.writeheader()
        for friend in friends[1:]:
           row = {}
           row['NickName'] = friend['NickName']
           row['Province'] = friend['Province']
           row['City'] = friend['City']
           writer.writerow(row)      

5. 微信好友全家福

通過下載下傳好友頭像進行拼接,做成一張好友頭像全家福,快來看一看有沒有你呀! (ps:不知道這個有沒有侵犯你的隐私,如果覺得有冒犯來跟我說一下哦,我來删除或打碼)

基于python分析微信好友的性别分布,區域分布,詞雲分析,頭像拼接
import itchat
import math
import os
import PIL.Image as Image
 
# 開啟熱登入,短時間内退出,再次進入可以不用掃碼登入
itchat.auto_login(hotReload=False)
friends = itchat.get_friends(update=True)
# 下載下傳所有好友的頭像圖檔
num = 0
imgPath = './headImg/'
if not os.path.exists(imgPath):
    os.mkdir(imgPath)
for i in friends:
    img = itchat.get_head_img(i["UserName"])
    with open(imgPath + str(num) + ".jpg", 'wb') as f:
        f.write(img)
        f.close()
        num += 1
length = len(os.listdir(imgPath))
# 根據總面積求每一個的大小
each_size = int(math.sqrt(float(810 * 810) / length))
# 每一行可以放多少個
lines = int(810 / each_size)
# 生成一張空白大圖檔
image = Image.new('RGBA', (810, 810), 'white')
x = 0
y = 0
#把每張頭像依次粘貼到大圖上
for i in range(0, length):
    try:
        img = Image.open(imgPath + str(i) + ".jpg")
    except IOError:
        print(i)
        print("image open error")
    else:
        img = img.resize((each_size, each_size), Image.ANTIALIAS)
        image.paste(img, (x * each_size, y * each_size))
        x += 1
        if x == lines:
            x = 0
            y += 1
image.save(imgPath + "myFriends.png")
# 通過檔案傳輸助手發送到自己微信中
itchat.send_image(imgPath + "myFriends.jpg", 'filehelper')
image.show()      

6.小結

數字時代的神經牽動着每一個社交關系鍊的人,我們想要竭力去保護的那點隐私,在這些資料中一點點地折射出來。人類或許可以不斷地僞裝自己,可這些從資料背後抽離出來的規律和聯系不會欺騙人類。數學曾經被人稱為最沒有用的學科,因為生活中并不需要神聖而純粹的計算,在不同的學科知識裡,經驗公式永遠比理論公式更為常用。可是此時此刻,你看,這世界就像一隻滴滴答答轉動着的時鐘,每一分每一秒都是嚴絲合縫的。

如果有需要源碼的可以關注微信公衆号「一行資料」,背景回複"1023",可以獲得全套代碼直接運作哦

參考:

[1]

https://blog.csdn.net/qinyuanpei/article/details/79360703

[2]

https://zhuanlan.zhihu.com/p/26489740

[3]

https://zhuanlan.zhihu.com/p/34290391

繼續閱讀