背景


开始之前要了解
python: 一种蛇 instagram: 著名被墙网站之一 pandas: 数据处理类库 matplotlib&seaborn: 画图类库 机器学习: 一种对计算机算法的研究方式,算法会根据经验自动优化效果 分类问题: 把一组数据分成两类或者多类,要划分类型已提前定义 sklearn: 封装了多种机器学习算法的类库,开箱即用
数据处理
{
"id":"CAA-r0SjtF3",
"sourceTag":"dharmaproductions",
"publishTime":1589130910000,
"addTime":1589134125000,
"likes":4,
"comments":1,
"views":18,
"tagNumber":15,
"description":"",
"totalMedia":57149,
"hot":1
}
数据探索
用 seaborn 画直方图,查看热门/非热门内容的比例:
self.df = pd.read_json('debug/train_video.jl', lines=True)
sns.countplot(self.df['hot'], label="Count")

用 seaborn 画热力图,这一步是为了查看字段之间的关系:
self.df = pd.read_json('debug/train_video.jl', lines=True)
corr = self.df.corr()
plt.figure(figsize=(14, 14))
sns.heatmap(corr, annot=True)

点击查看大图
用 matplotlib 画频率分布直方图,查看字段的分布类型
点击查看大图
数据清洗&特征选择
df['days'] = (pd.to_datetime(df['addTime'], unit='ms') - pd.to_datetime(df['publishTime'], unit='ms')).dt.days
# 不满一天的用1天替换
df['days'] = df['days'].replace(0, 1)
df['hours'] = ((pd.to_datetime(df['addTime'], unit='ms') - pd.to_datetime(df['publishTime'], unit='ms'))
.dt.total_seconds() / 3600).astype(int)
df['hours'] = df['hours'].replace(0, 1)
df['like_per_hour'] = (df['likes'] / df['hours']).astype(int)
df['view_per_hour'] = (df['views'] / df['hours']).astype(int)
features = ['views', 'likes', 'comments', 'tagNumber', 'totalMedia', 'days', 'like_per_hour', 'view_per_hour']
评分标准
准确率,精确率,召回率

from sklearn.metrics import accuracy_score,precision_score,recall_score
if __name__ == '__main__':
y_predict = [1,0,1]
y_true = [0,0,1]
print(f'accuracy:{accuracy_score(y_true,y_predict)}')
print(f'precision:{precision_score(y_true,y_predict)}')
print(f'recall:{recall_score(y_true,y_predict)}')
宏平均和微平均
Class A: 1 TP and 1 FP
Class B: 10 TP and 90 FP
Class C: 1 TP and 1 FP
Class D: 1 TP and 1 FP
算法选择
sklearn 常用分类算法
效果对比
import pandas as pd
from sklearn import naive_bayes
from sklearn.ensemble import AdaBoostClassifier, RandomForestClassifier
from sklearn.metrics import classification_report
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.utils import shuffle
clf_list = {
'cart': DecisionTreeClassifier(max_depth=5),
# 'svm': svm.SVC(), # 太慢了,放弃
'nb_multi': naive_bayes.MultinomialNB(),
'k_neighbors': KNeighborsClassifier(),
'adaptive_boost': AdaBoostClassifier(),
'random_forest': RandomForestClassifier(max_depth=2)
}
def train():
train_data = pd.read_json('debug/train_video.jl', lines=True)
train_data = shuffle(train_data)
# 特征选择
features = ['views', 'likes', 'comments', 'tagNumber', 'totalMedia', 'days', 'like_per_hour', 'view_per_hour']
train_features = train_data[features]
train_labels = train_data['hot']
# 测试数据
test_data = pd.read_json('debug/test_video.jl', lines=True)
test_data = shuffle(test_data)
test_features = test_data[features]
test_labels = test_data['hot']
for k, clf in clf_list.items():
print(f'-----{k} result-------')
# 决策树训练
clf.fit(train_features, train_labels)
target_names = ['normal', 'hot']
test_predict = clf.predict(test_features)
sample_weight = test_labels.replace(1, 100).replace(0, 1)
# 打印测试报告
print(classification_report(test_labels, test_predict, target_names=target_names, sample_weight=sample_weight))
-----cart result-------
precision recall f1-score support
normal 0.44 0.90 0.59 24222.0
hot 0.99 0.92 0.95 344800.0
accuracy 0.92 369022.0
macro avg 0.72 0.91 0.77 369022.0
weighted avg 0.96 0.92 0.93 369022.0
-----nb_multi result-------
precision recall f1-score support
normal 0.17 0.63 0.27 24222.0
hot 0.97 0.79 0.87 344800.0
accuracy 0.78 369022.0
macro avg 0.57 0.71 0.57 369022.0
weighted avg 0.92 0.78 0.83 369022.0
-----k_neighbors result-------
precision recall f1-score support
normal 0.11 0.69 0.20 24222.0
hot 0.97 0.63 0.76 344800.0
accuracy 0.63 369022.0
macro avg 0.54 0.66 0.48 369022.0
weighted avg 0.91 0.63 0.72 369022.0
-----adaptive_boost result-------
precision recall f1-score support
normal 0.08 0.99 0.15 24222.0
hot 1.00 0.20 0.34 344800.0
accuracy 0.25 369022.0
macro avg 0.54 0.60 0.24 369022.0
weighted avg 0.94 0.25 0.32 369022.0
-----random_forest result-------
precision recall f1-score support
normal 0.10 0.96 0.18 24222.0
hot 0.99 0.37 0.54 344800.0
accuracy 0.41 369022.0
macro avg 0.54 0.67 0.36 369022.0
weighted avg 0.93 0.41 0.52 369022.0
点击查看大图
未解决的问题
,使用默认参数的模型是没有灵魂的。按直觉来说随机森林和 AdaBoost 应该优于决策树才对,结果准确率和召回率相差都很大,应该还可以优化。另外测试结果容易受测试集影响,当我使用只有 39 个样本,其中只有一个非热门内容的测试集时,决策树的召回率反而最低,只有 79%,所以选择测试集时要注意样本数量和真实性。-----cart result-------
precision recall f1-score support
normal 0.00 1.00 0.00 1.0
hot 1.00 0.79 0.88 3800.0
accuracy 0.79 3801.0
macro avg 0.50 0.89 0.44 3801.0
weighted avg 1.00 0.79 0.88 3801.0
保存分类器
import _pickle as cPickle
# 保存
with open('ins_hot_model.clf','wb') as f:
cPickle.dump(clf,f)
def use_model():
# 未分类的ins文档信息
doc = {"likes": 107, "comments": 2, "views": 435.0, "tagNumber": 25, "totalMedia": 22000, "days": 1343,
"like_per_hour": 0, "view_per_hour": 0}
# 读取分类器
clf = cPickle.load(open('ins_hot.clf', "rb"))
# 把文档转换为DataFrame
source = pd.DataFrame([doc], columns=list(doc.keys()))
features = ['views', 'likes', 'comments', 'tagNumber', 'totalMedia', 'days', 'like_per_hour', 'view_per_hour']
df = source[features]
# 为文档分类
print(clf.predict(df))
总结
。最后,想进一步了解机器学习和调参技巧的盆友们,现在扫码即可 8 折购买参加极客时间的数据分析课程哦



关注一下再走吧

文章转载自throwsnew,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。






