浅谈Google Play ASO 优化

什么是ASO

ASO即APP Store Optimization,是用于提高APP在应用市场排名的工具,其实也就是移动产品的SEO工作。

ASO是为了提高该产品的搜索结果成绩,提升APP的下载量,针对Google Play来说,ASO就是优化APP页面。

为什么要做ASO

根据Forrester调研,有63%的用户寻找APP的时候是通过在应用市场搜索,另外,Google Play也有报道称80%的自然流量来自于Google Play的搜索。
在这里插入图片描述

Google Play ASO优化

ASO优化分为两部分,on-metadata和off-metadata,on-metadata的因素完全由我们控制,而off-metadata包含一些我们无法控制的因素,但我们仍可以去影响这些因素。

on-metadata ASO

针对Google Play,相关因素有Title、Short description、Long description、Icon、Screenshots & Video、崩溃率。另外,需要特别注意的是,Google Play搜索的关键词权重排序为:Title > Short description > Long description。

Title:APP名称,50个字符以内,通过研究排名前15的应用发现,title中包含相关关键词的应用高于其他应用10.3%的排名。因此,Title中一定要包含关键词。

Short Description:APP的短描述,80个字符以内,用一两句话来描述APP以及它的主要功能。

Long Description:APP的长描述,4000个字符以内,对APP的功能的进行非常清晰且具有吸引力的描述。

Icon:图标是APP与用户的第一次互动,所以要确保它能够很好的传达你的品牌。例如:BBC、News Republic、SoundCloud的Icon都做的非常好。

Screenshots & Video:在上传截图的时候,不要就真的只是“截图”,而应该是这些图片具有可推销性,因此可以在这些图片里包含文本和其他图形,以有趣直观的方式向用户呈现APP。
APP崩溃率:今年的Google大会上,Google称60%的一星评论是因为APP的崩溃、bug及响应速度,因此Google会调整算法,优先考虑APP质量,提高崩溃率的权重。另外,Google将崩溃率低于1%的应用化为低崩溃率应用,高于5%的化为为高崩溃率应用。因此,APP需要提升自身产品的质量。

如何选关键词

选取关键词的时候,需要综合考虑相关度、搜索热度和搜索难度。高关联度+合理难度+适当搜索流量+正确的位置放置=增加自然下载量。

off-metadata ASO

这部分我们无法直接控制,但仍可以做一些事情,来确保ASO可以达到更优的效果。

评星:评星非常影响APP排名,另外,用户即使通过搜索进入APP页面,如果评星很低,那么下载转化率也不会高。因此一定要联系一星用户改评星。

评论:和评星一样,很多用户在下载APP前会去看用户评论,如果评论不好,当然也会影响下载转化率。

A/B Test

Google Play提供了在APP页面的A/B Test,来对比不同的素材效果。这里有2种方式,Global和Localised,具体的区别如下。

在这里插入图片描述
下面是使用Localised方案做的一个测试结果:
在这里插入图片描述

如何评估ASO的效果

目前,Google Play Console上无法看到自然流量是由哪个关键词引来的(笔者目前也尚未找到其他工具可以看到),这是ASO相对于SEO最难的一点。Google Play Console上现在只可以看到自然流量的数据,以及和同类应用的对比情况(该功能也是刚刚上线的)。因此想具体来衡量ASO是否成功是很困难的,但是做了ASO之后,总是想知道效果如何,因此可以通过下面的一些方法来做衡量:

搜索排名:搜索排名肯定是跟踪ASO效果最有价值的数据。
排行榜
星评和评分
下载量
转化率和收入

如何做Google Play的ASO

每个人做ASO的套路和方法,以及使用的工具都有些许差别,以下是个人比较熟悉的方式,当然,工具无好坏,最适合的就是最好的。以下是大概的步骤:

(1)研究竞品的功能点(确定关键词选取方向)

建议将竞品的以下内容放到PPT里**(Title、Short Description、排名、评分、Icon、用户量、评论数、功能点、GP有代表性的评论)**,可以利用APP Annie排名和GP搜索结果以及similarWeb、apptweak等工具分析竞品,主要了解竞品用什么样的方式展现自己的哪些功能,以及他们的市场反应情况如何。

(2)分析竞品关键词

用apptweak可以分析出关键词的密度,综合similarWeb可以看到竞品的流量效果占比,以某 Browser为例:
在这里插入图片描述
在这里插入图片描述

(3)收集更多的关键词筛选

利用工具多做分析:Google keywords planner(现在只针对广告主开放)、Google trends、similarWeb、keyword tool(注意:搜出来的词和该词相关的用户搜索比较高的相关内容,而不是竞品包含的词),etc。

可以在Google Trends里搜索下相关的词,看下关键词的趋势对比,对优化ASO很有帮助,比如:hurricane这个词,通过Google Trends搜索可以看到,在某些地区的某些时间,该词的流量很高,那么针对天气类型的APP,就可以在这些时间点,优化这个关键词。

注意不要一开始就直接使用工具搜索关键词,这样就忽略了市场需求和背景,多去Google和Google Play搜索,Google给的搜索结果就是用户的需求痛点,另外,Google提供的搜索建议,也是用户在搜索该词时搜索的相关词,这些都可以作为关键词来分析。除此之外,搜索的时候搜索框给出的搜索建议都是用户平时在搜索的词,都可以用来做关键词的分析。

根据功能,和相关关键词的量,以及竞品的情况,挑出一些要用的关键词,挑选的时候,就大概理出每个关键词要用的地方(Title/Short description/Long description),即关键词计划,建议搜20个左右。
在做关键词的时候,由于主关键词的流量很大,很难竞争,因此建议多在长尾关键词上做突破,长尾关键词一定要包含主关键词。
确定关键词的时候,一定要考虑用户场景,多想想用户可能会怎么搜索。

(4)跟踪关键词排名,结合竞品关键词策略做优化

写文案的时候,这个时候可以将我们挑选的关键词,根据关键词计划,像写作文一样写出来。

需要注意关键词的密度,因为权重不会叠加,所以尽量不要大量的重复使用。

竞品和我们都有的功能,我们写的不能比竞品少,并且要重点突出竞品没有而我们有的功能。

做ASO的时候,GP第一版最好就写全,后面做微调,只要功能没有大的变化都做小的优化,比如根据节假日或者前面举到的Hurricane例子来做小调整。因为Google算法根据用户的行为路径会给关键词一定的权重,并且这个权重随着用户搜索量的增大以及转化率的提高而变大,如果修改比较大,关键词变化比较多,那么之前积累的权重又要重新开始。

此文只是针对Google Play ASO优化的一点个人想法,当然,ASO优化是一个长期的过程。

如果有ASO相关的需要讨论,欢迎私信我!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ASO优化算法是一种基于蚁群算法的优化算法,它可以用于解决多目标优化问题。BP神经网络算法可以用来进行分类、回归等任务。在使用BP算法进行ASO优化时,可以将多个目标转化为一个目标,然后使用BP神经网络进行训练和预测。 以下是一些实现ASO优化BP算法的C语言代码示例: 1. BP神经网络的实现 ```c //定义神经元结构体 typedef struct neuron { double input; //输入 double output; //输出 double delta; //误差 double bias; //偏置 double *weights; //权重 } neuron_t; //定义层结构体 typedef struct layer { int num_neurons; //神经元数量 neuron_t *neurons; //神经元 } layer_t; //定义神经网络结构体 typedef struct neural_network { int num_layers; //层数 layer_t *layers; //层 } neural_network_t; //初始化神经元 void init_neuron(neuron_t *neuron, int num_weights) { neuron->input = 0.0; neuron->output = 0.0; neuron->delta = 0.0; neuron->bias = (double)rand() / RAND_MAX; //随机初始化偏置 neuron->weights = (double *)malloc(num_weights * sizeof(double)); //动态分配权重数组 for (int i = 0; i < num_weights; i++) { neuron->weights[i] = (double)rand() / RAND_MAX; //随机初始化权重 } } //初始化层 void init_layer(layer_t *layer, int num_neurons, int num_weights) { layer->num_neurons = num_neurons; layer->neurons = (neuron_t *)malloc(num_neurons * sizeof(neuron_t)); //动态分配神经元数组 for (int i = 0; i < num_neurons; i++) { init_neuron(&layer->neurons[i], num_weights); } } //初始化神经网络 void init_neural_network(neural_network_t *nn, int num_inputs, int num_outputs, int num_hidden_layers, int num_hidden_neurons) { nn->num_layers = 2 + num_hidden_layers; //输入层、输出层和隐藏层 nn->layers = (layer_t *)malloc(nn->num_layers * sizeof(layer_t)); //动态分配层数组 //初始化输入层 init_layer(&nn->layers[0], num_inputs, 0); //初始化隐藏层 for (int i = 0; i < num_hidden_layers; i++) { if (i == 0) { init_layer(&nn->layers[i+1], num_hidden_neurons, num_inputs); } else { init_layer(&nn->layers[i+1], num_hidden_neurons, num_hidden_neurons); } } //初始化输出层 init_layer(&nn->layers[nn->num_layers-1], num_outputs, num_hidden_neurons); } //激活函数 double activation_function(double x) { return 1.0 / (1.0 + exp(-x)); } //前向传播 void feed_forward(neural_network_t *nn, double *inputs) { //输入层 for (int i = 0; i < nn->layers[0].num_neurons; i++) { nn->layers[0].neurons[i].output = inputs[i]; } //隐藏层和输出层 for (int i = 1; i < nn->num_layers; i++) { for (int j = 0; j < nn->layers[i].num_neurons; j++) { double sum = 0.0; for (int k = 0; k < nn->layers[i-1].num_neurons; k++) { sum += nn->layers[i-1].neurons[k].output * nn->layers[i].neurons[j].weights[k]; } sum += nn->layers[i].neurons[j].bias; nn->layers[i].neurons[j].input = sum; nn->layers[i].neurons[j].output = activation_function(sum); } } } //计算输出误差 void compute_output_error(neural_network_t *nn, double *targets) { layer_t *output_layer = &nn->layers[nn->num_layers-1]; for (int i = 0; i < output_layer->num_neurons; i++) { double output = output_layer->neurons[i].output; double delta = targets[i] - output; output_layer->neurons[i].delta = delta * output * (1.0 - output); } } //计算隐藏层误差 void compute_hidden_error(layer_t *layer, layer_t *next_layer) { for (int i = 0; i < layer->num_neurons; i++) { double output = layer->neurons[i].output; double sum = 0.0; for (int j = 0; j < next_layer->num_neurons; j++) { sum += next_layer->neurons[j].weights[i] * next_layer->neurons[j].delta; } layer->neurons[i].delta = output * (1.0 - output) * sum; } } //反向传播 void backpropagation(neural_network_t *nn, double *targets, double learning_rate) { //计算输出层误差 compute_output_error(nn, targets); //计算隐藏层误差 for (int i = nn->num_layers-2; i > 0; i--) { compute_hidden_error(&nn->layers[i], &nn->layers[i+1]); } //更新权重和偏置 for (int i = nn->num_layers-1; i > 0; i--) { for (int j = 0; j < nn->layers[i].num_neurons; j++) { neuron_t *neuron = &nn->layers[i].neurons[j]; for (int k = 0; k < nn->layers[i-1].num_neurons; k++) { double delta_weight = learning_rate * neuron->delta * nn->layers[i-1].neurons[k].output; neuron->weights[k] += delta_weight; } neuron->bias += learning_rate * neuron->delta; } } } //训练神经网络 void train_neural_network(neural_network_t *nn, double **inputs, double **targets, int num_examples, double learning_rate, int epochs) { for (int epoch = 0; epoch < epochs; epoch++) { double error = 0.0; for (int example = 0; example < num_examples; example++) { feed_forward(nn, inputs[example]); compute_output_error(nn, targets[example]); error += 0.5 * pow(targets[example][0] - nn->layers[nn->num_layers-1].neurons[0].output, 2); backpropagation(nn, targets[example], learning_rate); } printf("Epoch %d: error = %lf\n", epoch, error); } } //使用神经网络进行预测 double predict(neural_network_t *nn, double *inputs) { feed_forward(nn, inputs); return nn->layers[nn->num_layers-1].neurons[0].output; } ``` 2. ASO优化算法的实现 ```c //定义蚂蚁结构体 typedef struct ant { double *position; //位置 double *velocity; //速度 double *best_position; //最佳位置 double best_fitness; //最佳适应度 } ant_t; //初始化蚂蚁 void init_ant(ant_t *ant, int num_dimensions) { ant->position = (double *)malloc(num_dimensions * sizeof(double)); //动态分配位置数组 ant->velocity = (double *)malloc(num_dimensions * sizeof(double)); //动态分配速度数组 ant->best_position = (double *)malloc(num_dimensions * sizeof(double)); //动态分配最佳位置数组 for (int i = 0; i < num_dimensions; i++) { ant->position[i] = (double)rand() / RAND_MAX; //随机初始化位置 ant->velocity[i] = 0.0; //初始化速度为0 ant->best_position[i] = ant->position[i]; //最佳位置初始化为当前位置 } ant->best_fitness = DBL_MAX; //最佳适应度初始化为最大值 } //计算适应度 double fitness_function(ant_t *ant, neural_network_t *nn, double **inputs, double *targets, int num_examples) { double error = 0.0; for (int example = 0; example < num_examples; example++) { double output = predict(nn, inputs[example]); error += 0.5 * pow(targets[example] - output, 2); } return error; } //更新速度和位置 void update_velocity_and_position(ant_t *ant, ant_t *global_best_ant, double inertia_weight, double cognitive_weight, double social_weight) { for (int i = 0; i < num_dimensions; i++) { double r1 = (double)rand() / RAND_MAX; //随机数1 double r2 = (double)rand() / RAND_MAX; //随机数2 ant->velocity[i] = inertia_weight * ant->velocity[i] + cognitive_weight * r1 * (ant->best_position[i] - ant->position[i]) + social_weight * r2 * (global_best_ant->best_position[i] - ant->position[i]); ant->position[i] += ant->velocity[i]; if (ant->position[i] < 0.0) { ant->position[i] = 0.0; } else if (ant->position[i] > 1.0) { ant->position[i] = 1.0; } } } //ASO优化算法 void ASO(neural_network_t *nn, double **inputs, double *targets, int num_examples, int num_ants, int num_iterations, double inertia_weight, double cognitive_weight, double social_weight) { //初始化蚂蚁 ant_t *ants = (ant_t *)malloc(num_ants * sizeof(ant_t)); for (int i = 0; i < num_ants; i++) { init_ant(&ants[i], num_dimensions); } //计算适应度 double *fitness = (double *)malloc(num_ants * sizeof(double)); for (int i = 0; i < num_ants; i++) { fitness[i] = fitness_function(&ants[i], nn, inputs, targets, num_examples); if (fitness[i] < global_best_fitness) { global_best_fitness = fitness[i]; memcpy(global_best_position, ants[i].position, num_dimensions * sizeof(double)); } } //ASO优化循环 for (int iteration = 0; iteration < num_iterations; iteration++) { for (int i = 0; i < num_ants; i++) { update_velocity_and_position(&ants[i], &global_best_ant, inertia_weight, cognitive_weight, social_weight); double fitness_new = fitness_function(&ants[i], nn, inputs, targets, num_examples); if (fitness_new < fitness[i]) { fitness[i] = fitness_new; memcpy(ants[i].best_position, ants[i].position, num_dimensions * sizeof(double)); if (fitness_new < global_best_fitness) { global_best_fitness = fitness_new; memcpy(global_best_position, ants[i].position, num_dimensions * sizeof(double)); } } } } } ``` 将BP神经网络和ASO优化算法结合起来,可以实现ASO优化BP算法。 ```c int main() { srand(time(NULL)); //输入数据 double inputs[NUM_EXAMPLES][NUM_INPUTS] = { {0.0, 0.0}, {0.0, 1.0}, {1.0, 0.0}, {1.0, 1.0} }; //目标数据 double targets[NUM_EXAMPLES] = {0.0, 1.0, 1.0, 0.0}; //初始化神经网络 neural_network_t nn; init_neural_network(&nn, NUM_INPUTS, 1, 1, 4); //训练神经网络 train_neural_network(&nn, inputs, targets, NUM_EXAMPLES, LEARNING_RATE, EPOCHS); //ASO优化BP算法 ASO(&nn, inputs, targets, NUM_EXAMPLES, NUM_ANTS, NUM_ITERATIONS, INERTIA_WEIGHT, COGNITIVE_WEIGHT, SOCIAL_WEIGHT); //使用神经网络进行预测 for (int i = 0; i < NUM_EXAMPLES; i++) { double output = predict(&nn, inputs[i]); printf("Input: %lf %lf, Target: %lf, Output: %lf\n", inputs[i][0], inputs[i][1], targets[i], output); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的代码家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值