记一次用python做的多元线性回归分析
程序员文章站
2022-03-10 22:01:26
...
相关背景
调查分析某鱼主播收到付费礼物收入和免费礼物收入
模型如下:
抓取数据
主播相关信息
主播名,主播编号,礼物总收入,付费礼物收入,免费礼物收入,礼物人数,弹幕人数,直播时长,人气峰值,订阅变化,活跃观众,订阅数,抓取时间,直播类型
弹幕相关信息
主播编号,用户名,用户id,用户全站等级,是否粉丝弹幕标记,徽章昵称,用户粉丝等级,弹幕内容,抓取时间,cid
清洗转换数据
根据模型要求,从弹幕数据中计算出所需自变量的值合并到主播相关信息中
并做简单清洗工作
#导入
import pandas as pd
import numpy as np
import re
import os
DataDF = pd.read_csv('清洗数据.csv',encoding = "utf-8",dtype = str)
#查看每列信息
#DataDF.info()
#初始化信息
streamerId=DataDF['主播编号']
paidGiftIncome=np.log(DataDF['付费礼物收入'].astype(float))
freeGifgIncome=np.log(DataDF['免费礼物收入'].astype(float))
#控制变量
subscribeNum=np.log(DataDF['订阅数'].astype(int))
fansNum=np.log(DataDF['活跃观众'].astype(int))
streamType=DataDF['直播类型'].astype(int)
topHot=np.log(DataDF['人气峰值'].astype(int))
#自变量
userLevelVariance=[]
fansLevelVariance=[]
fansBarrageNum=[]
nfansBarrageNum=[]
path = 'danmu/'
files=[]
for f in DataDF['主播编号']:
file=f+'.csv'
files.append(file)
df=pd.read_csv(path+file,encoding='utf-8',dtype=str,keep_default_na=False)
#根据用户id去重
dupDf=df.drop_duplicates('用户id','last')
#用户等级方差
userLevelVariance.append(np.var(dupDf['用户全站等级'].astype(int)))
#粉丝等级方差
fansLevelVariance.append(np.var(dupDf['用户粉丝等级'].astype(float)))
#等级中位数
mid=np.median(dupDf['用户全站等级'].astype(int))
#粉丝弹幕数量(高等级用户)
fansBarrageNum.append(np.log(df[(df['用户全站等级'].astype(int)>= mid )].size))
#非粉丝弹幕数量(低等级用户)
nfansBarrageNum.append(np.log(df[(df['用户全站等级'].astype(int)< mid )].size))
dataframe = pd.DataFrame({'主播id':streamerId,'ln关注数':subscribeNum,'ln粉丝数':fansNum,'直播类型':streamType,'ln人气峰值':topHot,'用户等级方差':userLevelVariance,'粉丝等级方差':fansLevelVariance,'ln(粉丝弹幕数量)':fansBarrageNum,'ln(非粉丝弹幕数量)':nfansBarrageNum,'收费礼物收入':paidGiftIncome,'免费礼物收入':freeGifgIncome})
dataframe.to_csv("data.csv",index=False,sep=',')
回归分析
讲导出的data文件作为数据全集,划分数据集后使用sklearn进行回归分析
最佳拟合线:截距 [-4.6001933 -2.76872536] ,回归系数: [[-0.46457999 0.85992775 0.96507715 0.59494828 0.02850018 0.00734763
-0.10940398 0.17530741]
[-0.01520268 0.93765167 0.14050881 -0.02137043 0.00608183 -0.02255079
0.3406813 -0.27023856]]
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from pandas import DataFrame,Series
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
df = pd.read_csv('data.csv')
newDf = df[['ln关注数','ln粉丝数','直播类型','ln人气峰值','用户等级方差','粉丝等级方差','ln(粉丝弹幕数量)','ln(非粉丝弹幕数量)','收费礼物收入','免费礼物收入']]
#得到我们所需要的数据集且查看其前几列以及数据形状
print('head:',newDf.head(),'\nShape:',newDf.shape)
#df.head()
X= newDf[['ln关注数','ln粉丝数','直播类型','ln人气峰值','用户等级方差','粉丝等级方差','ln(粉丝弹幕数量)','ln(非粉丝弹幕数量)']]
Y= newDf[['收费礼物收入','免费礼物收入']]
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2)
plt.rcParams['font.sans-serif']=['STSong'] #解决中文显示问题,目前只知道黑体可行
plt.rcParams['axes.unicode_minus']=False #解决负数坐标显示问题
#绘制散点图
plt.scatter(df.ln人气峰值,df.收费礼物收入,color = 'b',label = "Exam Data")
#添加图的标签(x轴,y轴)
plt.xlabel("x")
plt.ylabel("giftIncome")
#显示图像
plt.show()
#数据描述
print(newDf.describe())
#缺失值检验
print(df[df.isnull()==True].count())
newDf.boxplot()
plt.show()
##相关系数矩阵 r(相关系数) = x和y的协方差/(x的标准差*y的标准差) == cov(x,y)/σx*σy
#相关系数0~0.3弱相关0.3~0.6中等程度相关0.6~1强相关
print(df.corr())
# 通过加入一个参数kind='reg',seaborn可以添加一条最佳拟合直线和95%的置信带。
sns.pairplot(newDf, x_vars=['ln关注数','ln粉丝数','直播类型','ln人气峰值','用户等级方差','粉丝等级方差','ln(粉丝弹幕数量)','ln(非粉丝弹幕数量)'], y_vars=['收费礼物收入','免费礼物收入'],aspect=0.8,kind = 'reg')
#plt.savefig("pairplot.jpg")
plt.show()
model = LinearRegression()
model.fit(x_train,y_train)
a = model.intercept_ #截距
b = model.coef_ #回归系数
print("最佳拟合线:截距",a,",回归系数:",b)
score = model.score(x_test,y_test)
print(score)
#对线性回归进行预测
Y_pred = model.predict(x_test)
print(Y_pred)
plt.plot(range(len(Y_pred)),Y_pred,'b',label="predict")
#显示图像
#plt.savefig("predict.jpg")
plt.show()
plt.figure()
plt.plot(range(len(Y_pred)),Y_pred,'b',label="predict")
plt.plot(range(len(Y_pred)),y_test,'r',label="test")
plt.legend(loc="upper right") #显示图中的标签
plt.xlabel("自变量")
plt.ylabel('礼物收入')
#plt.savefig("ROC.jpg")
plt.show()